Найти 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;
}
}
}