16

一个 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'
4

5 回答 5

7

有一种半合法的方式在未来可能会被打破。播放器项目有一个名为_player. 您可以像这样查询它(从技术上讲,它不使用私有 API,所以我认为它应该是 AppStore 安全的):

id player = [item valueForKey:@"player"];
于 2015-07-07T14:09:38.797 回答
3

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

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

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

例如:

firstPlayer.currentItem.duration

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

于 2012-10-18T12:50:29.103 回答
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()
}
于 2019-03-22T20:08:34.300 回答
0

您可以将 anAVPlayerItemAVPlayerusing 关联:

static char playerKey;

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

并使用:

objc_getAssociatedObject(item, &playerKey);
于 2014-01-05T05:25:32.307 回答
0

Based on Anil's answer, for a looped playback on multiple videos:

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;
        }
    }
}
于 2016-07-07T14:37:16.737 回答