Crash in - [AVPlayerItem _attachToPlayer:] AVPlayerItem не может быть связан с несколькими экземплярами AVPlayer

У меня произошел сбой, затрагивающий около 10% моих пользователей, но я не могу воспроизвести его и не знаю точно, когда это произойдет.

Crashlytics сообщает о половине сбойных пользователей, у которых приложение не находится в фокусе, I.e. делать фоновое аудио или AirPlay. Приложение воспроизводит видеопоток HLS и переключается на версию только для аудио, когда используется фоновый рисунок.

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

Спасибо!

Exception Type:
NSInvalidArgumentException
Reason:
An AVPlayerItem cannot be associated with more than one instance of AVPlayer
Fatal Exception
Latest Crash: 4/06/2013 at 8:48:46 UTC+0200
0   CoreFoundation  __exceptionPreprocess + 162
1   libobjc.A.dylib objc_exception_throw + 30
2   AVFoundation    -[AVPlayerItem _attachToPlayer:] + 188
3   AVFoundation    -[AVPlayer _attachItem:andPerformOperation:withObject:] + 336
4   AVFoundation    -[AVPlayer _insertItem:afterItem:] + 26
5   AVFoundation    -[AVQueuePlayer insertItem:afterItem:] + 136
6   MediaPlayer __block_global_4 + 520
7
...
libdispatch.dylib   _dispatch_call_block_and_release + 10
14

Ответ 1

Кажется, он решен путем явной остановки воспроизведения перед настройкой нового URL-адреса, например

[moviePlayer stop];
moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
[moviePlayer setContentURL:[NSURL URLWithString:[videos objectForKey:quality]]];

Ответ 2

Обнаружена причина для этой проблемы... Если MovieViewController был создан и в настоящее время он буферизует (i.e state!= MPMovieLoadStatePlayable или MPMovieLoadStatePlaythroughOK), вызов метода "play" приведет к сбою приложения с этим исключением.

Ответ 3

Попробуйте установить ContentURL после SourceType

moviePlayerController_ = [[MPMoviePlayerViewController alloc] init];
moviePlayerController_.movieSourceType = MPMovieSourceTypeStreaming;
[moviePlayerController_.moviePlayer setContentURL:url];

Ответ 4

Если вы не уверены в типе URL-адреса видео, вы отправляете тип источника заданного значения Unknown. Это будет работать для всех случаев.

moviePlayerController = [[MPMoviePlayerViewController alloc] init];
moviePlayerController.movieSourceType = MPMovieSourceTypeUnknown;
[moviePlayerController.moviePlayer setContentURL:url];

Ответ 5

Несколько вещей, которые следует учитывать:

  • Прокси-сервер между игроком и игроком предоставит средства для контроля доступа к элементу игрока экземплярами AVPlayer.

  • Связанные ссылки позволяют хранить свойства, добавленные в данный класс через категорию; поэтому вы можете создать категорию для класса элемента игрока, которая состоит из одного свойства, которое устанавливается, когда элемент игрока назначается AVPlayer (например, строка описания). Чтобы гарантировать, что элемент игрока не назначен другому игроку, просто сравните описание, сохраненное с AVPlayer, с тем, которое было возвращено игроком, о котором идет речь.