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
- This one is not much of a solution but I tried switching to the
react-native-video-player
instead ofreact-native-video
but that didn't work. - I tried passing the
type: 'm3u8'
andtype: 'hls'
inside the source attribute of the video tag along with the uri and this didn't help at all. - Tried to check if another m3u8 url (i.e. from another domain/server) is working, and it is working.
- Downgrading
react-native-video
version, problem persists with different error message.
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
- react-native : 'npm:[email protected]'
- react-native-video : '^6.0.0-alpha.3'
- Android TV : Tested both on a Raspberry Pi running Android TV (LineageOS I think) and an actual android tv set top box with same results.
CodePudding user response:
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.