HLS直播视频无法在首次加载时播放

问题描述 投票:0回答:1

我正在尝试在iOS中直播,所以步骤如下 -

  1. 初始化播放器 player = AVPlayer() player.rate = 1.0 player.actionAtItemEnd = AVPlayerActionAtItemEnd.none
  2. 设置播放器图层 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)
  3. 设置播放器项目 let avAsset = AVURLAsset(url: streamingUrl) playerItem = AVPlayerItem(asset: avAsset)
  4. 替换播放器中的currentItem并播放 self.player?.replaceCurrentItem(with: self.playerItem) self.player?.play()

如果我在流媒体开始后加载我的播放器,但是如果我在从后端开始实时流式传输之前加载播放器然后在某个时间之后开始流式播放它不播放视频,那么我的视频播放效果非常好。

我尝试将一个观察者添加到playerItem的状态属性,但是在上面提到的条件下也没有改变它只会在流媒体开始后加载播放器并且一切正常后才会改变。所以我的问题是为什么我没有获得我的playerItem的状态更改?我错过了什么吗?请帮忙。提前致谢。

ios swift avplayer live-streaming hlsl
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.