Обратите внимание на вопрос ниже: все ресурсы локальны на устройстве - потоковая передача по сети не выполняется. Видео содержат звуковые дорожки.
Я работаю над приложением iOS, которое требует воспроизведения видеофайлов с минимальной задержкой для запуска рассматриваемого видеоклипа. К сожалению, мы не знаем, какой именно видеоклип будет следующим, до тех пор, пока нам действительно не понадобится его запустить. В частности: когда воспроизводится один видеоклип, мы будем знать, каков будет следующий набор (примерно) из 10 видеоклипов, но мы не знаем, какой именно, пока не наступит время «немедленно» воспроизвести следующий клип.
Что я сделал, чтобы посмотреть на фактические задержки запуска, так это вызвал addBoundaryTimeObserverForTimes
видеоплеер с периодом времени в одну миллисекунду, чтобы увидеть, когда видео действительно начало воспроизводиться, и я беру разницу этой отметки времени с первым местом в код, который указывает, какой актив начать воспроизведение.
Из того, что я видел до сих пор, я обнаружил, что использование комбинации AVAsset
загрузки, а затем создание AVPlayerItem
из нее, когда она будет готова, а затем ожидание, AVPlayerStatusReadyToPlay
прежде чем я вызову play, обычно занимает от 1 до 3 секунд, чтобы запустить клип.
С тех пор я переключился на то, что, по моему мнению, примерно равноценно: звонить [AVPlayerItem playerItemWithURL:]
и ждать начала AVPlayerItemStatusReadyToPlay
игры. Примерно такая же производительность.
Одна вещь, которую я наблюдаю, - это то, что загрузка первого элемента AVPlayer происходит медленнее, чем остальных. Кажется, одна из идей - предварительно запустить AVPlayer с коротким / пустым активом, прежде чем пытаться воспроизвести первое видео, может быть хорошей общей практикой. [ Медленный запуск AVAudioPlayer при первом воспроизведении звука
Я бы хотел максимально сократить время начала видео и иметь некоторые идеи, с которыми можно поэкспериментировать, но хотел бы получить рекомендации от любого, кто мог бы помочь.
Обновление: приведенная ниже идея 7 в том виде, в котором она реализована, дает время переключения около 500 мс. Это улучшение, но было бы неплохо сделать это еще быстрее.
Идея 1: использовать N AVPlayers (не сработает)
Используем ~ 10 AVPPlayer
объектов и запускаем и приостанавливаем все ~ 10 клипов, и как только мы знаем, какой из них нам действительно нужен, переключаемся на правильный AVPlayer
, снимаем паузу и начинаем все заново для следующего цикла.
Я не думаю, что это работает, потому что я читал, что AVPlayer's
в iOS есть примерно 4 активных . Кто-то спрашивал об этом здесь в StackOverflow и узнал об ограничении в 4 AVPlayer: быстрое переключение между видео-использованием-avfoundation
Идея 2: использовать AVQueuePlayer (не сработает)
Я не верю, что добавление 10 AVPlayerItems
в одну AVQueuePlayer
заранее загрузит их все для плавного старта. AVQueuePlayer
это очередь, и я думаю, что она действительно только делает следующее видео в очереди готовым для немедленного воспроизведения. Я не знаю, какое из ~ 10 видео мы хотим воспроизвести, пока не пришло время начать это. ИОС-AVPlayer-видео-поджимать
Идея 3: загрузка, воспроизведение и сохранение AVPlayerItems
в фоновом режиме (еще не уверен на 100%, но не очень хорошо)
Я смотрю, есть ли какие-либо преимущества для загрузки и воспроизведения первой секунды каждого видеоклипа в фоновом режиме (подавление вывода видео и звука) и сохранения ссылки на каждый из них AVPlayerItem
, и когда мы знаем, какой элемент необходимо воспроизвести для real, поменяйте местами этот и поменяйте местами фоновый AVPlayer с активным. Промыть и повторить.
Теоретически можно было бы предположить, что недавно воспроизведенные AVPlayer/AVPlayerItem
файлы могут содержать некоторые подготовленные ресурсы, которые ускорят последующее воспроизведение. До сих пор я не видел преимуществ от этого, но, возможно, у меня нет AVPlayerLayer
правильной настройки для фона. Я сомневаюсь, что это действительно улучшит ситуацию по сравнению с тем, что я видел.
Идея 4. Используйте другой формат файла - может быть, тот, который загружается быстрее?
В настоящее время я использую формат H.264 .m4v (видео-MPEG4). 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
Как вы думаете, какой подход будет лучшим? Пока что я не добился больших успехов в сокращении задержки.