Downloading videos for offline
Generating OTP for Offline Playback
To initialize video playback on website or app, your backend has to generate
an OTP
+playbackInfo
using the VdoCipher API. The regular OTP does
not have permission to be persisted offline. To enable offline playback you
will need to send additional parameters while making the API call for the OTP.
You can specify the time period for which the offline download will be available for playback. The time period of validity is called the rental duration. Beyond the rental duration the license will expire, and the downloaded file will no longer play.
You can find more details on the OTP-based playback mechanism at the API page.
Setting up offline
Offline video playback is only available if you have set up Fairplay DRM and configured it with your VdoCipher account.
1. Notification handlers
// listen to the download events
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDownloadProgress(_:)),
name: .AssetDownloadProgress, object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDownloadStateChange(_:)),
name: .AssetDownloadStateChanged, object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDownloadFailed(_:)),
name: .AssetDownloadFailed, object: nil
)
2. Handler functions to update the UI about progress and download completions
The notification received from the above will be of the following structures.
AssetDownloadProgress
{
"videoId": "____",
"percentDownlaod": 0.2
}
AssetDownloadStateChanged
The downloadState will be one of the enum from VdoAsset.DownloadState
.
{
"videoId": "___",
"downloadState": "downloaded"
}
AssetDownloadFailed
{
"videoId": "____",
"message": "___ __ __",
"code": xxxx
}
Do not use string for the keys. Use the VdoAsset.Keys
struct for the keys of
the userInfo
. Check the examples below for an example.
Sample handler code
// MARK: Notification handlers
@objc func handleDownloadStateChange(_ notification: Notification) {
print("handle download state change")
let notice = notification.userInfo!
guard videoId == notice[VdoAsset.Keys.videoId] as? String else {
return
}
guard let stateRawValue = notice[VdoAsset.Keys.downloadState] as? String,
let newState = VdoAsset.DownloadState(rawValue: (stateRawValue)) else {
return
}
print("state change: \(newState)")
DispatchQueue.main.async {
self.updateUI(downloadState: newState)
}
}
@objc func handleDownloadProgress(_ notification: Notification) {
print("handle download progress")
let notice = notification.userInfo!
guard videoId == notice[VdoAsset.Keys.videoId] as? String else {
return
}
guard let percent = notice[VdoAsset.Keys.percentDownloaded] as? Double else {
return
}
print("progress percent: \(percent)")
DispatchQueue.main.async {
self.updateUI(downloadState: .downloading, percentDownload: percent)
}
}
@objc func handleDownloadFailed(_ notification: Notification) {
print("handle download failed")
let notice = notification.userInfo!
if let message = notice[VdoAsset.Keys.message], let code = notice[VdoAsset.Keys.code]
{
print("Download Failed with message:\(message) code:\(code)")
}
}
3. Call the download APIs from the UI
@IBAction func downloadAction(_ sender: Any) {
guard let asset = asset, let button = sender as? UIButton, let buttonText = button.currentTitle else {
return print("not ready for playback or action not defined")
}
asset.startDownload(otp: otp, playbackInfo: playbackInfo)
}
@IBAction func cancelAction(_ sender: Any) {
asset.deleteDownload()
}
@IBAction func deleteAction(_ sender: Any) {
asset.deleteDownload()
}
@IBAction func pauseAction(_ sender: Any) {
asset.pauseDownload()
}
@IBAction func resumeAction(_ sender: Any) {
asset.resumeDownload()
}
4. Call the playOffline()
method to start offline playback
@IBAction func playOffline(_ sender: Any) {
guard let asset = asset else {
return print("not ready for offline playback")
}
if asset.downloadState != .downloaded {
return print("not downloaded yet")
}
asset.playOffline()
}
Get list of downloads
Call the getListOfDownloads()
method to get list of downloads. It return array of
type 'DownloadInfo' which has all the basic information about a downloaded asset
let allDownloads = VdoCipher.getListOfDownloads()
}
Alternatively, you can filter your results using 'DownloadInfoFilter'. You can get 'DownloadInfo' of particular set of videoIds and also for particular 'DownloadState'.
let videoIds = ["vid1", "vid2", "vid3"]
let downloads = VdoCipher.getListOfDownloads(filterBy: DownloadInfoFilter.init(videoId: videoIds, downloadState: [.paused, .downloading]))
}