Troubleshooting: Unable to Show Vimeo Video Using HCVimeoVideoExtractor with AVPlayer
This article aims to help you identify and resolve issues when trying to display a Vimeo video using the HCVimeoVideoExtractor package in combination with AVPlayer, but unable to show the video due to an error similar to: 'maths' [63530:11355]'.
Key Concepts
Before we start, let's understand the main components at play:
- Vimeo: A video-sharing platform that hosts and streams videos.
- HCVimeoVideoExtractor: An iOS library that allows you to extract video information and download videos from Vimeo.
- AVPlayer: A framework by Apple for playing media within your applications.
The Problem
When combining HCVimeoVideoExtractor with the AVPlayer to stream Vimeo videos, a common error occurs: 'maths' [63530:11355]'. This error usually occurs when the video information extracted from Vimeo is incorrect or incompatible with the AVPlayer. Let's discuss ways to address this issue.
Solution 1: Verify Video URL
First, ensure you have the correct video URL. Normally, this can be found in the Vimeo video's page source code (using the browser's "Inspect" function). You're looking for the video_id or clip_id parameters in the script tag. However, due to Vimeo's security and privacy restrictions, HCVimeoVideoExtractor may not always succeed in generating the correct URL.
Solution 2: Extract Video Information Directly
An alternative approach is to extract video information directly from Vimeo's GraphQL API, which usually holds the necessary information. Here is a Swift example of how you can achieve this:
import Foundation
struct VimeoVideo {
var link: String
}
func fetchVimeoVideo(with id: String, completion: @escaping (VimeoVideo?) -> Void) {
let url = "https://api.vimeo.com/graphql"
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = """
{
"query": "query {
video(id: \"\(id)\") {
playbackId
streamUrl
}
}"
}
"""
request.httpBody = body.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {
completion(nil)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
if let data = json["data"] as? [String: Any],
let videoData = data["video"] as? [String: Any],
let playbackId = videoData["playbackId"] as? String,
let streamUrl = videoData["streamUrl"] as? String {
completion(VimeoVideo(link: streamUrl))
} else {
completion(nil)
}
} catch {
completion(nil)
}
}
task.resume()
}
With the correct video link, you can create an AVAsset and load it into the AVPlayer:
import AVFoundation
func playVimeoVideo(with link: String) {
let asset = AVAsset(url: URL(string: link)!)
let player = AVPlayer(asset: asset)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true, completion: nil)
}
References
- HCVimeoVideoExtractor: GitHub Repository
- Vimeo Developer Portal: Vimeo Developer Portal
- AVFoundation: Apple Developer Documentation