Подтвердить что ты не робот

Возможно ли кэшировать сегменты HLS с помощью AVPlayer?

Корневая проблема

Наше видео много буферизуется при поиске в iOS. Он буферизует немного больше, чем наш веб-плеер, который сохраняет копии уже просмотренных сегментов в хранилище temp.

Желаемое решение

Кэширование видео сегментов локально на диске устройства. Мы в порядке с кешированием одного качества и всегда воспроизводим его.

Blocker

Мы не можем найти способ выполнить кеширование в AVFoundation/AVPlayer.

Что мы пробовали

2 способа перехвата сетевых запросов с помощью AVPlayer.

  • Соответствует AVAssetResourceLoaderDelegate и обрабатывает загрузку носителя вручную

Не работает с HLS. Вы можете загружать файлы m3u8, реализуя AVAssetResourceLoaderDelegate, который позволяет передавать аутентификацию или расшифровывать ответ, однако файлы .ts не могут быть загружены. Вот код, который мы пробовали: https://gist.github.com/nathanhillyer/84e46152d7c4c88183b6

  1. Реализация NSURLProtocol для захвата запросов для файлов .ts.

AVURLAsset фактически избегает перехвата. Как-то сетевые запросы просто не захватываются. (Не знаю, почему)

4b9b3361

Ответ 1

Начнем с действительно хороших новостей - iOS 10 и выше - выдает это из коробки. Вскоре не будет необходимости в хаке. Более подробную информацию можно найти в следующем сеансе WWDC16 о том, что нового в потоке HTTP Live: https://developer.apple.com/videos/play/wwdc2016/504/

Теперь вернемся к текущему состоянию вещей - iOS 9 и ниже: С AVPlayer нет. Но вы можете кэшировать сегменты HLS через локальный HTTP-сервер и воспроизводить локальный поток с помощью AVPlayer.

AVPlayer и AVAsset не содержат необходимой информации при работе с HLS-воспроизведением (он ведет себя иначе, чем статический файл MP4, например).

TL; DR - вам нужно использовать HTTP-запросы для получения сегментов и их обслуживания с помощью локального HTTP-сервера.

Несколько компаний, включая ту, для которой я работаю, используют эту стратегию.

Используйте соединение для загрузки сегментов по желаемому качеству, перестройте манифест и скомпенсируйте все это в один каталог и одно качество, а затем используйте локальный HTTP-сервер внутри приложения, чтобы обслуживать его в AVPlayer (AVPlayer может воспроизводить только HLS потоки, переданные через HTTP, а не из файловых ресурсов).

Существуют крайние случаи, например, буферизация, если вы хотите играть и загружать за один проход, правильно перестраивая манифест m3u8, и различные состояния AVPlayer с чтением диска.

Я нашел это из первых рук, имея такую ​​систему в производстве в течение 5 лет и других видеопродуктах в App Store, которые используют одно и то же решение - в целом обслуживают многих пользователей.

Это также лучшее решение для Android.

Ответ 2

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

К счастью, в AVURLAsset есть большой API-интерфейс - объект resourceLoader, который вы можете предоставить контролируемому доступу к удаленному аудиофайлу в AVPlayer. Это работает как локальный HTTP-прокси, но без всех неприятностей.

Вы можете найти более подробную информацию о https://gist.github.com/anonymous/83a93746d1ea52e9d23f

Ответ 3

О NSURLProtocol: Как я понял, он создает собственные запросы, поэтому ваши пользовательские теги/поля/метки будут удалены.

Я сделал это по-другому: перенаправляет запросы сегментов на какую-то настраиваемую схему URL-адресов и просто проверяет схему в протоколе canInitWithRequest.

Таким образом, все работает отлично. (потратил неделю на то, чтобы вычислить всю обработку hls-обработки...)