Реагировать на родное видео не удается воспроизвести файл m3u8

Проблема

Я пытаюсь передать файл m3u8 в родном приложении для реагирования (для Android TV), и я получаю эту ошибку:

 LOG  {"error": {"errorCode": "22004", "errorException": "com.google.android.exoplayer2.ExoPlaybackException: Source error", "errorStackTrace": "com.google.android.exoplayer2.ExoPlaybackException: Source error
    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632)
    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:604)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:223)
    at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 403
    at com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource.open(OkHttpDataSource.java:329)
    at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:258)
    at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
    at com.google.android.exoplayer2.upstream.DataSourceInputStream.checkOpened(DataSourceInputStream.java:99)
    at com.google.android.exoplayer2.upstream.DataSourceInputStream.open(DataSourceInputStream.java:62)
    at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:174)
    at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
", "errorString": "ExoPlaybackException: ERROR_CODE_IO_BAD_HTTP_STATUS"}}

Я не знаю java, поэтому из приведенной выше трассировки я предполагаю, что сервер отвечает HTTP 403 и, следовательно, не может передать файл в потоковом режиме.

Что я пробовал

  • Это не очень хорошее решение, но я попытался переключиться на react-native-video-player вместо react-native-video, но это не сработало.
  • Я попытался передать type: 'm3u8' и type: 'hls' внутри исходного атрибута тега видео вместе с uri, и это совсем не помогло.
  • Пытался проверить, работает ли другой URL-адрес m3u8 (т.е. с другого домена/сервера), и он работает.
  • Понижение версии react-native-video, проблема сохраняется с другим сообщением об ошибке.

Я решил подключиться по ssh к своему Android-телевизору и напрямую использовать curl для извлечения файла m3u8, и он отвечает следующим образом:

curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Более того, многие из проблем, которые я нашел на github с похожей проблемой, содержат URL-адрес, который дает тот же ответ при прямом извлечении с помощью curl. Интересно, что если я использую API-интерфейс fetch в JS для консольного логирования ответа от URL-адреса m3u8, он работает отлично. Так что я предполагаю, что проблема где-то в exoplayer.

Спецификации

  • реагировать-родной: 'npm: реагировать-родной[email protected]'
  • реагировать на родное видео: '^ 6.0.0-альфа.3'
  • Android TV: протестировано как на Raspberry Pi под управлением Android TV (я думаю, LineageOS), так и на реальной телевизионной приставке Android с одинаковыми результатами.

263
1

Ответ:

Решено

Проблема была с заголовком пользовательского агента, exoplayer устанавливал пользовательский агент, который вызывал HTTP 403. Мне пришлось использовать прокси, чтобы понять это, и до сих пор не знаю, почему студия Android не показывала запрос, который была ошибка.