找到与AVPlayerItem关联的AVPlayer

时间:2012-09-26 22:00:09

标签: ios avplayer

AVPlayerItem只能分配给一个AVPlayer。将AVPlayerItem添加到AVPlayer后,将来尝试将其添加到其他AVPlayer将会对应用程序进行SIGABRT。

因此,给定AVPlayerItem,您如何确定:

  1. 目前与哪个AVPlayer相关联?和
  2. 如果它曾经在过去的任何时候被插入AVPlayer?
  3. 以下代码可靠地演示了这个问题:

    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'
    

6 个答案:

答案 0 :(得分:6)

将来有一种半合法的方式可能会破裂。玩家项目有一个名为_player的私有方法(似乎是变量)。您可以像这样查询它(技术上不使用私有API,所以我认为它应该是AppStore安全的):

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

答案 1 :(得分:3)

你有没有尝试过反过来?尝试访问AVPlayer正在播放的项目内的详细信息

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

之后您可以访问firstPlayer.currentItem。这样您就可以访问firstPlayer的{​​{1}}。

例如:

AVPlayerItem

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

答案 2 :(得分:1)

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

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()
}

答案 3 :(得分:0)

您可以使用以下内容将AVPlayerItemAVPlayer相关联:

static char playerKey;

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

并使用:

objc_getAssociatedObject(item, &playerKey);

答案 4 :(得分:0)

根据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;
        }
    }
}

答案 5 :(得分:0)

如果您要分配一个项目给第二个玩家,那么在分配它之前,您必须将第一个玩家的项目设置为nil,然后分配给第二个玩家。