我正在尝试在iOS中进行直播,因此请遵循以下步骤-
初始化播放器
player = AVPlayer()
player.rate = 1.0
player.actionAtItemEnd = AVPlayerActionAtItemEnd.none
设置播放器图层
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.bounds
playerLayer.backgroundColor = UIColor.clear.cgColor
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
if let sublayers = self.layer.sublayers {
for layer in sublayers {
layer.removeFromSuperlayer()
}
}
self.layer.addSublayer(playerLayer)
设置播放器项目
let avAsset = AVURLAsset(url: streamingUrl)
playerItem = AVPlayerItem(asset: avAsset)
将currentItem替换为播放器并播放
self.player?.replaceCurrentItem(with: self.playerItem)
self.player?.play()
如果在流式传输开始后立即加载播放器,我的视频就可以正常播放,但如果在从后端开始实时流传输之前加载了播放器,然后在一段时间后不播放视频,就可以开始流式传输。 / strong>
我尝试将观察者添加到playerItem的status属性中,但是在上面提到的条件下也没有改变,只有在流媒体开始并且一切正常之后,我加载播放器时,它才会改变。所以我的问题是为什么我没有获得我的playerItem的状态更改?我想念什么吗?请帮忙。预先感谢。
答案 0 :(得分:0)
在您可以使用的情况下,先使用AVAsset(url: URL).isPlayable
检查网址是否可以播放
if avAsset.isPlayable {
playerItem = AVPlayerItem(asset: avAsset)
...
}
为获得更好的方法,请使用观察者
class ViewController: UIViewController {
private var observerContext = 0
private let player = AVPlayer()
private var readyForPlayback = false
private var playerItem: AVPlayerItem? {
willSet {
playerItem?.removeObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), context: &observerContext)
}
didSet {
playerItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.initial, .new], context: &observerContext)
}
}
private var asset: AVAsset? {
willSet {
readyForPlayback = false
asset?.removeObserver(self, forKeyPath: #keyPath(AVURLAsset.isPlayable), context: &observerContext)
}
didSet {
guard asset == nil else {
asset!.addObserver(self, forKeyPath: #keyPath(AVURLAsset.isPlayable), options: [.initial, .new], context: &observerContext)
return
}
playerItem = nil
player.replaceCurrentItem(with: nil)
}
}
// MARK: KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &observerContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
guard let keyPath = keyPath else { return }
switch keyPath {
case #keyPath(AVURLAsset.isPlayable):
guard asset?.isPlayable == true else { return }
playerItem = AVPlayerItem(asset: asset!)
player.replaceCurrentItem(with: playerItem)
case #keyPath(AVPlayerItem.status):
guard let status = playerItem?.status else { return }
if status == .readyToPlay {
guard !readyForPlayback else { return }
readyForPlayback = true
player.play()
} else if status == .failed {
readyForPlayback = false
if let error = playerItem?.error {
print("Error: \(error)")
}
}
default:
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
}
用法
self.asset = AVAsset
停止播放时
self.asset = nil