背景
拿到一個(gè)視頻的 url 地址(無(wú)論是遠(yuǎn)程還是本地),有時(shí)候在播放之前需要檢測(cè)該視頻是否可以播放(本地可能是文件損壞固以,遠(yuǎn)端地址情況更復(fù)雜)杆勇,下面介紹兩種適用不同情況的方法來(lái)實(shí)現(xiàn)。
常用的異步方法
import UIKit
import AVFoundation
class ViewController: UIViewController {
var avplayer: AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://gslb.miaopai.com/stream/24fONfescp-SRz61DjJz62WO1LLIwjIQXHthNg__.mp4")!
avplayer = AVPlayer(url: url)
avplayer.addObserver(self, forKeyPath: "status", options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (avplayer == object as? AVPlayer) && (keyPath == "status") {
print((avplayer.status == .readyToPlay) ? "readyToPlay" : "fail")
}
}
}
如代碼所示馆衔,我們可以使用 AVPlayer (MPMoviePlayerController 在 iOS 9 被 deprecated) 嘗試解析 url井誉,進(jìn)行視頻播放蕉扮。然后可以通過(guò) KVO 在它的 status 屬性變?yōu)?“readyToPlay” 的時(shí)候,進(jìn)行播放等操作颗圣。在這里這個(gè) status 只能異步獲取喳钟,如果你直接在初始化 AVPlayer 之后就同步獲取這個(gè)值,這個(gè)值會(huì)是 “unknown”在岂。
如果你在這里需要直接使用這個(gè) AVPlayer 進(jìn)行視頻播放奔则,那么推薦使用這個(gè) KVO 方法。否則會(huì)有這樣幾個(gè)缺點(diǎn):
- avplayer 用于判斷視頻可播放性蔽午,本應(yīng)該是局部變量易茬,現(xiàn)在因?yàn)?KVO 它的 scope 被擴(kuò)大了
- KVO 方法在代碼可讀性上不如同步的直接判斷
- 控制臺(tái)會(huì)默認(rèn)打印下面這些東西:
2017-09-05 14:43:36.983707+0800 VideoPlayable[40473:10508878] [aqme] 254: AQDefaultDevice (1): skipping input stream 0 0 0x0
2017-09-05 14:43:38.992581+0800 VideoPlayable[40473:10508878] [aqme] 254: AQDefaultDevice (173): skipping input stream 0 0 0x0
2017-09-05 14:43:41.000864+0800 VideoPlayable[40473:10508878] [aqme] 254: AQDefaultDevice (173): skipping input stream 0 0 0x0
同步判斷方法
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://gslb.miaopai.com/stream/24fONfescp-SRz61DjJz62WO1LLIwjIQXHthNg__.mp4")!
let avasset = AVAsset(url: url)
print(avasset.isPlayable)
}
}
經(jīng)過(guò)一番折騰,發(fā)現(xiàn)直接通過(guò) url 新建出 AVAsset及老,即可通過(guò)
isPlayable 屬性判斷視頻是否可以正常播放抽莱。如果僅僅是想要判斷視頻可播放性,而不需要使用 AVPlayer骄恶,建議使用這種方法食铐,可以將 AVAsset 的創(chuàng)建邏輯加入到你的自定義播放器的 init 方法中。
我嘗試在 iPhone 6s 上使用本地的一個(gè)約 800k 的 mp4 視頻進(jìn)行粗略測(cè)試僧鲁,發(fā)現(xiàn)新建 AVAsset 耗時(shí)約 0.02s虐呻,新建 AVPlayer 異步返回耗時(shí)約 0.05s,這種同步方法大概快了一倍寞秃。