Android HLS- Streaming не удалось получить сегмент

Я пишу видеоплеер для Android для потоковой передачи видео по HLS. На моем сервере есть m3u8-Playlist и .ts-Segments. Мой код выглядит так:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    vidSurface = (SurfaceView) findViewById(R.id.surfView);
    vidHolder = vidSurface.getHolder();
    vidHolder.addCallback(this);
}


public void surfaceCreated(SurfaceHolder arg0) {
    try {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDisplay(vidHolder);
        mediaPlayer.setDataSource(vidAddress);
        mediaPlayer.prepareAsync();
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }
    catch(Exception e){
        e.printStackTrace();
    }
}    

Плеер отлично работает с примером Apple bipbopall.m3u8. Но когда я пытаюсь воспроизвести свой плейлист, возникает эта ошибка:

E/PlaylistFetcher﹕ failed to fetch .ts segment at url 'http://example.com/USSM.mp4Frag1Num0.ts'
E/LiveSession﹕ XXX Received error -1008 from PlaylistFetcher.
E/MediaPlayer﹕ error (1, -1008)

Думаю, есть проблема с расшифровкой файлов AES-128. Расшифровывает ли MediaPlayer файлы самостоятельно, и как я могу проверить, было ли дешифрование успешным? (Я использую последнюю версию Android)


person henchman21    schedule 27.08.2015    source источник
comment
1008 - это ERROR_OUT_OF_RANGE при попытке получить файл. Как выглядит ваш плейлист?   -  person aergistal    schedule 27.08.2015
comment
@aergistal #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:NO #EXT-X-VERSION:2 #EXT-X-KEY:METHOD=AES-128,URI="/hls-vod-enc-key/hlscf.key",IV=0X99b74007b6254e4bd1c6e03631cad15b #EXT-X-TARGETDURATION:8 #EXTINF:8, USSM20000051_abr-100.mp4Frag1Num0.ts #EXTINF:8, USSM20000051_abr-100.mp4Frag1Num1.ts #EXTINF:8, USSM20000051_abr-100.mp4Frag2Num2.ts #EXTINF:8, USSM20000051_abr-100.mp4Frag3Num3.ts #EXT-X-ENDLIST   -  person henchman21    schedule 27.08.2015
comment
MediaPlayer может расшифровать файлы. HLS поддерживает AES, поскольку v1 и Android могут использовать v2 на 3.x и v3 на 4.x. Вы можете попробовать тот же поток в приложении VLC для Android (не в бета-версии) и посмотреть, работает ли он. Вы также можете включить в нем журнал отладки.   -  person aergistal    schedule 27.08.2015
comment
Спасибо, похоже, это ошибка на сервере Apache. Но я могу транслировать mp4-файл, и я делаю все, что описано, для настройки моего веб-сервера. Для доставки контента не требуются специальные серверные модули, и обычно требуется очень небольшая конфигурация на веб-сервере. Рекомендуемая конфигурация обычно ограничивается указанием ассоциаций типа MIME для файлов .M3U8 и .ts. (Apple Developer HLS)   -  person henchman21    schedule 27.08.2015
comment
mp4 файлы передаются по-разному с использованием прогрессивной загрузки. Чтобы проверить шифрование, используйте openssl и попробуйте расшифровать один из сегментов с помощью предоставленного ключа и iv. Используемый алгоритм - aes-128-cbc .   -  person aergistal    schedule 27.08.2015
comment
Я пробовал это с файлом без шифрования, и возникает та же ошибка   -  person henchman21    schedule 27.08.2015
comment
.ts сегменты находятся в контейнере mp4. Этот файл можно воспроизводить, например с VLC-Player   -  person henchman21    schedule 27.08.2015
comment
Это не может быть правильным, потому что .ts также является форматом контейнера.   -  person aergistal    schedule 27.08.2015


Ответы (1)


Чтобы возобновить обсуждение в комментариях:

1008 ERROR_OUT_OF_RANGE возвращается при попытке прочитать сегмент в буфер. Убедитесь, что сервер правильно отвечает, загрузив сегмент, расшифровав его и попытавшись воспроизвести (см. Метод ниже).

Что еще нужно проверить: убедитесь, что MPEG-TS сегменты действительны. Если вы использовали поток H.264, содержащийся в файле MP4 для создания сегментов, проверьте, используют ли они формат Annex B (например, в ffmpeg вы можете использовать фильтр битового потока h264_mp4toannexb, который работает с закодированным потоком - вы можете использовать его с -c:v copy )

Чтобы проверить правильность шифрования, используйте openssl.

  1. Получить ключ в простом шестнадцатеричном формате

    xxd -p keyfile.key

  2. Расшифровать сегмент .ts

    openssl aes-128-cbc -d -in encrypted_segment.ts -out decrypted_segment.ts -nosalt -iv <iv_hex> -K <key_hex>
    

    Если нет определенного IV, то он равен медиа-последовательности.

  3. Попытка воспроизвести расшифрованный сегмент.

person aergistal    schedule 27.08.2015