gpt4 book ai didi

ios - 尝试使用 AV Foundation 流式播放视频时 KVO 遇到麻烦

转载 作者:行者123 更新时间:2023-11-30 14:01:17 40 4
gpt4 key购买 nike

目标:
我最终试图读取外部视频文件(.mp4、.mpg...);在 AVPlayerViewController 的实例中。

但我遇到了各种各样的 KVO 问题。

  1. AVPlayerViewController 的 KVO 观察器始终会触发,即使我没有如控制台中所示注册它(来源:请参阅下面代码列表中的observeForKeyPath().print(key path)):

playerController.status playerController.contentDimensions playerController.playingOnExternalScreen playerController.externalPlaybackType playerController.allowsExternalPlayback playerController.hasEnabledVideo playerController.hasEnabledAudio bounds videoScaled playerController.playingOnExternalScreen view.viewWindowState bounds playerController.playing

  • 我的 KVO 观察者(“timedMetadata”)未注册。显然:
  • self.playerItem!.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)

    不工作:
    a) 'observeValueForKeyPath()' 没有为此观察者触发;和
    b) 我收到以下运行时错误(在立即删除观察者作为测试后):

    ...reason: 'Cannot remove an observer... for the key path "timedMetadata" from ... because it is not registered as an observer.'

        class EditShowVideoViewController:AVPlayerViewController {

    var playerItem:AVPlayerItem?

    override func viewDidLoad() {

    self.view.hidden = true

    if let url = NSURL(string: gEditMediumTuple!.medium as! String) {
    let asset = AVURLAsset(URL: url)
    let requestedKeys = Array(arrayLiteral: "tracks", "playable")
    asset.loadValuesAsynchronouslyForKeys(requestedKeys, completionHandler: { () in
    // do something
    dispatch_async(dispatch_get_main_queue(), {
    self.playerItem = AVPlayerItem(asset: asset)
    self.playerItem!.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
    self.removeObserver(self, forKeyPath:"timedMetadata") //...still runtime error.
    })
    })

    } else {
    showAlert(sender: self.parentViewController!, withTitle: "No Video", withMessage: "No video is found.", alertPurpose: .noVideo)
    }
    }

    override func observeValueForKeyPath(keyPath: String?,
    ofObject object: AnyObject?, change: [String : AnyObject]?,
    context: UnsafeMutablePointer<()>) {
    print(keyPath!)
    guard keyPath == "readyForDisplay" else {return}
    guard let obj = object as? AVPlayerViewController else {return}
    guard let ok = change?[NSKeyValueChangeNewKey] as? Bool else {return}
    guard ok else {return}
    dispatch_async(dispatch_get_main_queue(), {
    self.finishConstructingInterface(obj)
    })

    self.removeObserver(self, forKeyPath:"timedMetadata")
    }

    func finishConstructingInterface (vc:AVPlayerViewController) {
    self.removeObserver(self, forKeyPath:"readyForDisplay")
    self.view.hidden = false
    }

    // ...

    }

    我想做的就是加载视频 URL 并播放它。

    如果缺乏补救措施,欢迎提出任何建议。

    最佳答案

    运行时错误是因为您将观察添加到播放器项目,但随后尝试将其从自身中删除。

    在观察者回调中,如果键不属于您的观察,那么您应该调用 super。您不知道不这样做会破坏什么。

    考虑将视频 VC 添加为子类,而不是将您的类添加为子类。这将使其在逻辑上保持独立并防止 KVO 回调混淆。

    一般来说,使用 KVO 进行代码流管理会让你的代码更难遵循、调试和维护。最好使用不同的机制并保存 KVO 纯粹用于更改跟踪和响应。另外,至少保留一个 bool 标志来表明您是否正在观察,以便您可以适本地进行整理。您不能允许您的类被释放并留下悬而未决的观察结果。

    关于ios - 尝试使用 AV Foundation 流式播放视频时 KVO 遇到麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32958253/

    40 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com