Найти AVPlayer, связанный с AVPlayerItem

AVPlayerItem может быть привязан только к одному AVPlayer. Когда AVPlayerItem добавлен в AVPlayer, будущие попытки добавить его к другому AVPlayer будут SIGABRT приложением.

Итак, с учетом AVPlayerItem, как вы можете определить:

  • С чем связан AVPlayer? и
  • Если он когда-либо был вставлен в 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'

Ответ 1

Попробовал ли ты наоборот? Попробуйте получить доступ к деталям внутри элемента, который воспроизводится с помощью AVPlayer

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

После этого вы можете получить доступ к firstPlayer.currentItem. Это даст вам доступ к firstPlayer AVPlayerItem.

Например:

firstPlayer.currentItem.duration

даст вам продолжительность этого трека.

Ответ 2

Существует полулегальный способ, который может сломаться в будущем. Элемент игрока имеет закрытый метод (и, кажется, переменный) с именем _player. Вы можете запросить его так (это технически не использует частный API, поэтому я думаю, что он должен быть безопасным для AppStore):

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

Ответ 3

Вы можете связать AVPlayerItem с AVPlayer, используя:

static char playerKey;

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

и получите его, используя:

objc_getAssociatedObject(item, &playerKey);

Ответ 4

На основе ответа 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;
        }
    }
}