拿到一個視頻的 url 地址(不管是遠程仍是本地),有時候在播放以前須要檢測該視頻是否能夠播放(本地多是文件損壞,遠端地址狀況更復雜),下面介紹兩種適用不一樣狀況的方法來實現。bash
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,進行視頻播放。而後能夠經過 KVO 在它的 status 屬性變爲 「readyToPlay」 的時候,進行播放等操做。在這裏這個 status 只能異步獲取,若是你直接在初始化 AVPlayer 以後就同步獲取這個值,這個值會是 「unknown」。異步
若是你在這裏須要直接使用這個 AVPlayer 進行視頻播放,那麼推薦使用這個 KVO 方法。不然會有這樣幾個缺點:ide
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)
}
}複製代碼
通過一番折騰,發現直接經過 url 新建出 AVAsset,便可經過
isPlayable 屬性判斷視頻是否能夠正常播放。若是僅僅是想要判斷視頻可播放性,而不須要使用 AVPlayer,建議使用這種方法,能夠將 AVAsset 的建立邏輯加入到你的自定義播放器的 init 方法中。測試
我嘗試在 iPhone 6s 上使用本地的一個約 800k 的 mp4 視頻進行粗略測試,發現新建 AVAsset 耗時約 0.02s,新建 AVPlayer 異步返回耗時約 0.05s,這種同步方法大概快了一倍。ui