androidreact-nativesslssl-certificatereact-native-video

React native video unable to play m3u8 file


Problem

I'm trying to stream a m3u8 file in a react native app (for android TV) and I'm getting this error:

 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"}}

I don't know java so from the above traceback I'm guessing that the server is responding with an HTTP 403 and therefore it is unable to stream the file.

What I've tried

I decided to ssh into my android TV and directly use curl to fetch the m3u8 file and it responds with this:

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.

Moreover, many of the issues I found on github having a similar problem contain a URL that gives the same response when fetched directly with curl. Interestingly, if I use the fetch API in JS to console log the response from the m3u8 url, it works perfectly. So I'm guessing the problem is somewhere in exoplayer.

Specs


Solution

  • The issue was with the user-agent header, exoplayer was setting a user-agent which was causing an HTTP 403. I had to use a proxy to figure this out and still have no clue as per why android studio was not showing the request that had an error.