AVPlayer и прогрессивная загрузка видео с AVURLAssets
У нас есть приложение, над которым мы работаем, которое должно обеспечивать воспроизведение видеофайлов через AVPlayer. Файлы должны храниться на устройстве пользователя, но также должны воспроизводиться во время загрузки.
На данный момент мы создали модуль загрузки, который использует библиотеку ASIHTTPRequest для получения видеофайлов через PHP (мы не хотим, чтобы носители были связаны с помощью общедоступных URL-адресов) и асинхронной записи их на диск.
Затем мы настроили AVPlayer в соответствии с Руководством по программированию AVFoundation, получив файл с помощью AVURLAsset, сделав AVPlayerItem с активом, собрав AVPlayer с элементом, а затем установив проигрыватель в AVPlayerLayer. Плеер отлично работает с полностью загруженным видеофайлом, а также будет отлично запускать прогрессивно загруженный файл в симуляторе.
К сожалению, на реальном устройстве поведение проигрывателя меняется, вместо этого он, похоже, загружает видео один раз и не пытается захватить новые пакеты с диска. В результате проигрыватель будет воспроизводить видео и аудио до той точки в видео, которая отмечает, где происходил процесс загрузки во время загрузки ресурса (например, если буферизовано 2 МБ данных, то создается проигрыватель, проигрыватель будет только играть до 2 МБ данных). Поскольку у него есть заголовок видео, проигрыватель с радостью продолжит думать, что он воспроизводится на протяжении всего видео, но никакое другое видео не отображается на экране.
Последний недостаток заключается в том, что если видео вставлено в AVComposition и AVPlayer создан с этим, прогрессивное видео будет воспроизводиться нормально. Это было бы хорошим решением (и в любом случае необходимо для нашего приложения), за исключением того, что клиент нашего приложения требует, чтобы видео воспроизводилось на Apple TV через AirPlay, на что AVCompositions не способен.
Кто-нибудь знает, есть ли способ воспроизведения прогрессивно загружаемых видеофайлов с использованием AVPlayer, созданного из AVURLAssets? Есть ли способ заставить player/playerItem читать с диска с помощью AVURLAsset так, как это происходит с AVComposition вместо того, чтобы, казалось бы, кэшировать видео в памяти?
Спасибо!
1 ответ
У меня нет решения просто заставить его работать с AVURLAssets, но я использую немного другой подход. Мы связываем наше приложение с CocoaHTTPServer и воспроизводим видеофайлы, которые загружаются не полностью через HTTP-запрос на локальный сервер.
Сервер знает общую длину файла и может затем определить, просматривая HTTP-заголовки, какая часть файла является запросом, и загружать его с диска или из удаленного источника.
При его разработке всегда выполняются три начальных запроса: один для первых двух байтов файла, один из фрагментов большего размера в начале файла и один фрагмент непосредственно в конце файла. Вот почему всегда нужно было загружать хотя бы последнюю часть непосредственно с удаленного сервера, так как игроку она понадобится с самого начала. Я предполагаю, что то же самое происходит с локальными файлами, поэтому проигрыватель загружает последние байты из файла (которые не являются правильными последними байтами) и не будет воспроизводиться в течение этой длины.
Вы должны будете создать подкласс HTTPConnection и создать свой собственный класс HTTPResponse, посмотрев на предоставленный "HTTPAsyncFileResponse".
Я надеюсь, что это дает вам представление о том, как сделать это с помощью другого подхода.