Sample ViewController file
This sample ViewController.swift
file demonstrates all the APIs available
through the SDK. It references some UI elements which should be clear from
the naming. This file can be directly run on a fresh xcode iOS project after
connecting the IBOutlet
s and IBAction
s with appropriate UIButton
,
UILabel
and UIView
.
For the AVPlayer
container, it uses AVPlayerViewController
which will
display iOS native player controls.
It contains an offline capable OTP and playbackInfo for demonstration purpose.
//// ViewController.swift// DemoApp//
import UIKitimport VdoFrameworkimport AVFoundationimport AVKit
class ViewController: UIViewController, AssetPlaybackDelegate {
@IBOutlet weak var downloadStateLabel: UILabel! @IBOutlet weak var downloadActionButton: UIButton! @IBOutlet weak var playOnlineButton: UIButton! @IBOutlet weak var playOfflineButton: UIButton! @IBOutlet weak var container: UIView! fileprivate var playerViewController = AVPlayerViewController() private var asset: VdoAsset? private var otp = "20160313versIND313U23cSmhREBvfAxBOjVfItnUFq66mSNOK6Za7U8hb58ePX8" private var playbackInfo = "eyJ2aWRlb0lkIjoiMGViNTVkNWRjMjI2NGY4MGIxOWMwYzI0YmZmYWJmZTMifQ==" private var videoId = "0eb55d5dc2264f80b19c0c24bffabfe3" override func viewDidLoad() { super.viewDidLoad() // Setting the AVPlayer controller in a subview self.playerViewController.view.frame = self.container.bounds self.playerViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.addChild(self.playerViewController) self.container.addSubview(self.playerViewController.view) self.playerViewController.didMove(toParent: self) // 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) // create a delegate for tracking player state VdoCipher.setPlaybackDelegate(delegate: self) // make a new asset VdoAsset.makeAsset(videoId: videoId) { asset in print("title is: " + asset.title!) self.asset = asset DispatchQueue.main.async { self.updateUI(downloadState: asset.downloadState, percentDownload: asset.percentDownload ?? -1) self.playOnlineButton.isEnabled = true self.downloadActionButton.isEnabled = true } } } override func viewWillAppear(_ animated: Bool) { downloadStateLabel.text = "Generating asset..." playOfflineButton.isEnabled = false } private func updateUI(downloadState: VdoAsset.DownloadState?, percentDownload: Double = -1) { self.playOfflineButton.isEnabled = false switch downloadState { case .notDownloaded: self.downloadStateLabel.text = "not downloaded" self.downloadActionButton.setTitle("Download", for: .normal) break; case .downloaded: self.downloadStateLabel.text = "downloaded" self.downloadActionButton.setTitle("Delete", for: .normal) self.playOfflineButton.isEnabled = true break; case .downloading: self.downloadStateLabel.text = "downloading \(percentDownload)" self.downloadActionButton.setTitle("Cancel", for: .normal) break; default: self.downloadStateLabel.text = "getting download state..." } } // 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) } }
@IBAction func playOnline(_ sender: Any) { guard let asset = asset else { return print("not ready for playback") } asset.playOnline(otp: otp, playbackInfo: playbackInfo) }
@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() }
@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") } print("title is \(String(describing: button.currentTitle))") print("download action \(buttonText)") switch buttonText { case "Delete": print("downloaded, now can delete") asset.deleteDownload() case "Cancel": print("downloading..., now can cancel") asset.cancelDownload() case "Download": print("download action triggered") asset.startDownload(otp: otp, playbackInfo: playbackInfo) default: print("can't get here") } }}
extension ViewController { func streamPlaybackManager(playerReadyToPlay player: AVPlayer) { // player is ready to play player.play() } func streamPlaybackManager(playerCurrentItemDidChange player: AVPlayer) { // player current item has changed playerViewController.player = player }}