【问题标题】:Find the AVPlayer associated with an AVPlayerItem查找与 AVPlayerItem 关联的 AVPlayer
【发布时间】:2012-09-26 22:00:08
【问题描述】:

一个 AVPlayerItem 只能分配给一个 AVPlayer。将 AVPlayerItem 添加到 AVPlayer 后,以后尝试将其添加到不同的 AVPlayer 将 SIGABRT 应用程序。

那么,给定一个 AVPlayerItem,你如何确定:

  1. 它当前与哪个 AVPlayer 关联?和
  2. 过去是否曾将其插入 AVPlayer?

以下代码可靠地演示了该问题:

AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]];
AVPlayer *firstPlayer = [[AVPlayer alloc] init];
[firstPlayer replaceCurrentItemWithPlayerItem:item];
AVPlayer *secondPlayer = [[AVPlayer alloc] init];
[secondPlayer replaceCurrentItemWithPlayerItem:item];

这是错误信息:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An AVPlayerItem cannot be associated with more than one instance of AVPlayer'

【问题讨论】:

  • 你找到答案了吗?
  • 哈,不。我们采取了不同的方法。当我们准备将可疑血统的 AVPlayerItem 分配给 AVPlayer 时,我们克隆该项目并广播一条消息,我们正在用新项目替换旧项目。我们还使用关联对象将旧对象指向新对象。因此,如果我们得到一个旧的 AVPlayerItem 已经发生了这个过程,我们可以按照前向关联对象指针的链表找到最终的“真正的”。谢谢苹果。

标签: ios avplayer


【解决方案1】:

有一种半合法的方式在未来可能会失效。播放器项目有一个名为_player 的私有方法(而且似乎是变量)。你可以这样查询(技术上不使用私有 API,所以我认为它应该是 AppStore 安全的):

id player = [item valueForKey:@"player"];

【讨论】:

    【解决方案2】:

    您是否尝试过相反的方法?尝试访问 AVPlayer 正在播放的项目中的详细信息

    AVPlayer *firstPlayer = [[AVPlayer alloc]init];
    

    之后您可以访问firstPlayer.currentItem。这将使您可以访问firstPlayerAVPlayerItem

    例如:

    firstPlayer.currentItem.duration
    

    将为您提供该曲目的持续时间。

    【讨论】:

    • 就我而言,我得到的是一个 AVPlayerItem。该项目过去可能与 AVPlayer 相关联。我的目标是确定是否是这种情况。
    【解决方案3】:

    这是一个优雅的解决方案,没有私钥和相关对象。创建自定义播放器项目:

    class PlayerAwareItem {
        weak var player: AVPlayer?
    }
    

    设置播放器:

    let item = PlayerAwareItem(asset: asset)
    let player = AVPlayer(playerItem: item)
    item.player = player
    

    以后只要有物品就可以访问播放器(在本例中,我们希望在停止后重新启动播放器):

    @objc func handlePlayerItemDidStall(_ notification: Notification) {
        guard let playerItem = notification.object as? PlayerAwareItem,
            let player = playerItem.player else { return }
        player.play()
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用以下方法将AVPlayerItemAVPlayer 关联起来:

      static char playerKey;
      
      objc_setAssociatedObject(item, &playerKey, player, OBJC_ASSOCIATION_RETAIN);
      

      并使用:

      objc_getAssociatedObject(item, &playerKey);
      

      【讨论】:

      • 刚刚看到你的评论@jimbojw。我正在为同样的错误而苦苦挣扎,并且使用简单的关联对象并不能解决它。会尝试广播通知的方式。
      • #import <objc/runtime.h>
      【解决方案5】:

      根据 Anil 的回答,对于多个视频的循环播放:

      for (NSObject * obj in cachedVideos){
          if ([obj isKindOfClass:[AVPlayerLayer class]]){
              AVPlayerLayer * layer = (AVPlayerLayer *)obj;
              if ([layer.player.currentItem isEqual:n.object]){
                  [layer.player seekToTime:kCMTimeZero];
                  [layer.player play];
                  break;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多