2012-06-23 3 views
99

Обратите внимание, что на вопрос ниже: все активы локальны на устройстве - сетевое потоковое вещание не происходит. Видео содержат звуковые дорожки.Как уменьшить задержку запуска IOS AVPlayer

Я работаю над приложением iOS, которое требует воспроизведения видеофайлов с минимальной задержкой для запуска рассматриваемого видеоролика. К сожалению, мы не знаем, какой именно видеоролик будет дальше, пока нам не понадобится его запускать. В частности: когда один видеоролик воспроизводится, мы узнаем, что представляет собой следующий набор (примерно) 10 видеороликов, но мы не знаем, какой именно, пока не придет время «немедленно» воспроизвести следующий клип.

Что я сделал, чтобы посмотреть фактические задержки запуска, позвоните addBoundaryTimeObserverForTimes на видеопроигрыватель с периодом времени в миллисекунду, чтобы увидеть, когда действительно начнется воспроизведение видео, и я беру разницу в этой отметке времени с первым местом в коде, которое указывает, какой актив начать играть.

Из того, что я видел, таким образом далеко, я обнаружил, что при использовании комбинации AVAsset загрузки, а затем создавая AVPlayerItem от этого, как только он будет готов, а затем ждет AVPlayerStatusReadyToPlay, прежде чем я называю игру, как правило, занимает от 1 и 3 секунды, чтобы запустить клип.

С тех пор я перешел на то, что, на мой взгляд, примерно эквивалентно: позвоните [AVPlayerItem playerItemWithURL:] и в ожидании AVPlayerItemStatusReadyToPlay играть. Примерно такая же производительность.

Одна вещь, которую я наблюдаю, заключается в том, что первая загрузка элемента AVPlayer медленнее остальных. Кажется, одна идея заключается в предполетном AVPlayer с коротким/пустым активом, прежде чем пытаться воспроизвести первое видео может быть хорошей общей практикой. [Slow start for AVAudioPlayer the first time a sound is played

Я хотел бы, чтобы время начала видеороликов было как можно меньше, и у вас есть идеи о том, что нужно экспериментировать, но хотелось бы, чтобы какое-то руководство было у кого-нибудь, кто мог бы помочь.

Обновление: идея 7, ниже, как реализовано, дает время переключения около 500 мс. Это улучшение, но было бы неплохо добиться этого еще быстрее.

Идея 1: Используйте N AVPlayers (не будет работать)

Использование ~ 10 AVPPlayer объектов и пуско-паузы все ~ 10 клипов, и как только мы знаем, какой из них нам действительно нужно, переключатель и не снимайте паузу с правильного AVPlayer и начинайте все заново для следующего цикла.

Я не думаю, что это работает, потому что я читал, что в iOS имеется примерно 4 активных AVPlayer's. Был кто-то спрашивать об этом на StackOverflow здесь, и узнал о пределе 4 AVPlayer: fast-switching-between-videos-using-avfoundation

Идея 2: Использование AVQueuePlayer (не будет работать)

Я не верю, что толкая 10 AVPlayerItems в AVQueuePlayer будет предварительно загружать их все для бесшовного запуска. AVQueuePlayer - это очередь, и я думаю, что это действительно только делает следующее видео в очереди готовым к немедленному воспроизведению. Я не знаю, какой из 10 видеороликов мы хотим воспроизвести, пока не приступит к началу этого.ios-avplayer-video-preloading

Идея 3: Загрузка, воспроизведение и сохранение AVPlayerItems в фоновом режиме (не 100% уверен, что еще - но не очень хорошо)

Я смотрю, если есть какие-либо преимущества для загрузки и воспроизведения первая секунда каждого видеоклипа в фоновом режиме (подавление видео и аудиовыхода) и сохраняйте ссылку на каждый номер AVPlayerItem, и когда мы знаем, какой элемент нужно воспроизвести для реального, замените его и замените фоновый AVPlayer на активный. Промыть и повторить.

Теория будет заключаться в том, что в последнее время игра AVPlayer/AVPlayerItem может по-прежнему содержать подготовленные ресурсы, которые ускоряют последующее воспроизведение. До сих пор я не видел преимуществ от этого, но у меня может не быть настройки AVPlayerLayer правильно для фона. Я сомневаюсь, что это действительно улучшит ситуацию из того, что я видел.

Идея 4: Используйте другой формат файла - возможно, тот, который быстрее загружается?

В настоящее время я использую формат .m4v (video-MPEG4) H.264. В H.264 есть много разных опций кодеков, поэтому возможно, что некоторые параметры быстрее искать, чем другие. Я обнаружил, что использование более продвинутых параметров, которые делают размер файла меньшим, увеличивают время поиска, но не нашли никаких вариантов, которые идут в другую сторону.

Идея 5: Сочетание формата видео без потерь + AVQueuePlayer

Если есть видео формат, который быстро загружается, но, может быть, где размер файла безумна, одна идея может быть предварительно подготовить первые 10 секунд каждого видеоклипа с версией, раздутой, но быстрее загружаемой, но обратно с активом, закодированным в H.264. Используйте AVQueuePlayer и добавьте первые 10 секунд в формат несжатого файла и следуйте этому примеру, который находится в H.264, который получает до 10 секунд времени подготовки/предварительной загрузки. Поэтому я бы получил «лучшее» из обоих миров: быстрое время начала, но также выигрывает от более компактного формата.

Идея 6: Использование нестандартного AVPlayer/написать мой собственный/использовать чужие

Учитывая мои потребности, может быть, я не могу использовать AVPlayer, но придется прибегнуть к AVAssetReader и декодировать первый несколько секунд (возможно, напишите необработанный файл на диск), и когда дело доходит до воспроизведения, используйте необработанный формат, чтобы быстро воспроизвести его. Кажется, это огромный проект для меня, и если я буду заниматься наивным образом, это будет неясным/вряд ли даже лучше работать. Каждый декодированный и несжатый видеокадр составляет 2,25 МБ. Наивно говоря - если мы пойдем с ~ 30 кадров в секунду для видео, я бы закончил с требованием ~ 60 МБ/с для чтения с диска, что, вероятно, невозможно/подтолкнуло. Очевидно, нам пришлось бы сделать некоторый уровень сжатия изображения (возможно, родные форматы сжатия OpenGL/es через PVRTC) ... но это безумно. Может быть, есть библиотека, которую я могу использовать?

Идея 7: Объединить все в одном фильме актива и seekToTime

Одна мысль, что может быть проще, чем некоторые из выше, чтобы объединить все в один фильм, и использовать seekToTime. Дело в том, что мы будем прыгать по всему месту. По сути, произвольный доступ к фильму. Я думаю, что это может на самом деле работать нормально: avplayer-movie-playing-lag-in-ios5

Какой подход вы считаете лучшим? До сих пор я не добился такого большого прогресса в плане сокращения отставания.

+0

Для чего это стоит, я собираюсь с идеей 7. Это все еще медленно, но не так непредсказуемо медленно, как другие варианты. Следующий вопрос, который у меня есть, - варианты кодеков, разрешение и частота ключевого кадра - влияют на время поиска? –

+0

Поздно к игре, но возможно, стоит переключать видео как можно быстрее (т. Е. Сразу же после запуска новой игры) и профилировать приложение, чтобы увидеть, где он тратит большую часть своего процессорного времени. –

+1

Почти через год, что вы когда-либо узнали об этом? – lnafziger

ответ

0

Без каких-либо действий в прошлом, исходя из ваших мыслей и переживаний, я бы попытался использовать комбинацию 7 и 1: предварительно загрузите один AVPlayer с помощью первых нескольких секунд из 10 последующих видеороликов. Тогда пропуски, скорее всего, будут быстрее и надежнее из-за меньшего количества данных. Пока вы играете выбранную пьесу, у вас есть достаточно времени, чтобы подготовить AVPlayer для остальной части выбранного последующего видео в фоновом режиме. Когда начало закончено, вы переключаетесь на подготовленный AVPlayer. Таким образом, вы в любой момент времени загружаете максимум 2 AVPlayers.

Конечно, я не знаю, можно ли это сделать так плавно, чтобы оно не мешало воспроизведению.

(добавил бы это как комментарий, если я мог бы.)

Лучшего, Питер

+0

Я не нашел выгоды для загрузки 10 активов в серии на одном AVPlayer. Кроме того, я не понимаю вашего предложения, поскольку я вижу вариант (1) и (7) взаимоисключающим. Вариант 7 объединяет все видеоактивы в один актив - таким образом, для периода загрузки существует только один актив. Это то, что я делаю сегодня, и за то, что стоит, я получаю примерно 500 мс задержки на фактические времена начала/воспроизведения. Стоит отметить, что SeekTo заканчивается быстрее, чем воспроизводится фактический первый кадр, поэтому для истинного времени начала я измеряю, когда первый кадр фактически воспроизводится с помощью обратного вызова по времени. –

+0

Просто, чтобы понять мою идею: моя идея состояла в том, чтобы разделить актив на две части: первые несколько секунд и все остальное. Теперь вы сделали два актива из одного. 10 начинаний, к которым вы присоединились, и использовать пропустить, и, играя в начале, вы загрузите остальные. Затем это включает предложение 8, которое добавляется в ваш список. – ilmiacs

+0

Но, как я понимаю из вашего последнего комментария, вы тем временем продвинули исследование, которое хорошо, и решение 7 тоже не работает. Похоже, что AV принципиально остается на вашем пути, и единственный путь для вас - это использовать технологию под этим, то есть Core Media, чтобы получить больше контроля над вашими активами. Питер. – ilmiacs

1

Актив может не готов, как только вы его создать, может ли расчеты, как продолжительность фильма, убедитесь, содержат все метаданные фильма в файле.

1

Сначала попробуйте вариант № 7, чтобы убедиться, что вы можете это сделать. Я подозреваю, что это не будет работать для ваших нужд, так как время поиска, вероятно, не будет достаточно быстрым, чтобы обеспечить плавное переключение между клипами. Если вы попробуете это и не получится, то я бы посоветовал вам сделать вариант 4/6 и взглянуть на мою iOS-библиотеку, разработанную специально для этой цели, просто выполните быстрый поиск Google на AVAnimator, чтобы узнать больше. Моя библиотека позволяет реализовать бесшовные циклы и переключиться с одного клипа на другой, это очень быстро, потому что видео необходимо предварительно декодировать в файл. В вашем случае все 10 видеоклипов будут дешифрованы в файлы до начала, но переход между ними будет быстрым.

+0

Как насчет аудиофрагментации видео? Мне нужно синхронизировать видео и аудио. –

+0

Да, звук уже обрабатывается с очень жесткой синхронизацией между звуковой дорожкой и видеоклипом. См. Примеры проектов xcode. Это уже все реализовано, вам просто нужно скачать и попробовать. – MoDJ

+0

Есть ли возможность воспроизведения сетевого видео с помощью AVAnimator? –

-1

Вот некоторые свойства и методы, предоставляемые класс AVAsset, которые могут помочь:

- (void)_pu_setCachedDuration:(id)arg1; 
- (id)pu_cachedDuration; 
- (struct 
{ 
    long long x1; 
    int x2; 
    unsigned int x3; 
    long long x4; 
})pu_duration; 
- (void)pu_loadDurationWithCompletionHandler:(id /* block */)arg1; 
0

Если я понял ваш вопрос правильно, кажется, что у вас есть одно непрерывного видео, к которому нужно загрузить звуковую дорожку на мгновение.

Если это так, я предлагаю изучить BASS. BASS - это аудио-библиотека, подобная AVPlayer, которая дает (относительно) легкий доступ к низкоуровневым API-интерфейсам среды AudioUnits в iOS. Что для вас значит? Это означает, что с небольшим количеством манипуляций с буфером (вам может и не понадобиться, зависит от того, насколько малы вы хотите задержку), вы можете начать играть музыку мгновенно.

Ограничения, однако, распространяются на видео, как я уже сказал, это библиотека audio, поэтому любые манипуляции с видео по-прежнему должны выполняться с помощью AVPlayer. Однако, используя -seekToTime:toleranfeBefore:toleranceAfter:, вы должны быть в состоянии добиться быстрого поиска в видео, пока вы используете все необходимые параметры.

Если вы синхронизируете несколько устройств (что может предложить ваше приложение), просто оставьте комментарий, и я с удовольствием отредактирую свой ответ.

PS: BASS может выглядеть пугающе в первую очередь из-за его формата C-like, но это действительно очень просто использовать для чего-то.

Смежные вопросы