TheWidlarzGroup / react-native-video

A <Video /> component for react-native
https://thewidlarzgroup.github.io/react-native-video/
MIT License
7.17k stars 2.89k forks source link

m3u8 playlist can't be parsed with ExoPlaybackException #3303

Closed HMT2002 closed 1 year ago

HMT2002 commented 1 year ago

Bug

Platform

Which player are you experiencing the problem on:

Environment info

Library version: 6.0.0-alpha.8 Device: Samsung A50

Steps To Reproduce

Others m3u8 files work fine but mine doesn't. I convert the video into m3u8 playlist manually with ffmpeg, and it played fine with diffrent player like vlc, mpv,... or others library like video.js, hls.js,... but it got stuck with react-native-video. I regcognized there are some differences between my m3u8 and the working ones, but even I tried to change the format into similar file, it still not work, it keep showing "None of the available extractors (FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, Mp3Extractor, AviExtractor, JpegExtractor) could read the stream" or "ExoPlaybackException: ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED"

This is my m3u8 file:

EXTM3U

EXT-X-VERSION:1

EXT-X-TARGETDURATION:4

EXT-X-MEDIA-SEQUENCE:0

EXTINF:10.166667,

test0.ts

EXTINF:10.800000,

test1.ts

EXTINF:12.433333,

EXT-X-ENDLIST

Others working file:

EXTM3U

EXT-X-VERSION:1

Created with Unified Streaming Platform (version=1.11.20-26889)

variants

EXT-X-STREAM-INF:BANDWIDTH=493000,CODECS="mp4a.40.2,avc1.66.30",RESOLUTION=224x100,FRAME-RATE=24

tears-of-steel-audio_eng=64008-video_eng=401000.m3u8

EXT-X-STREAM-INF:BANDWIDTH=2468000,CODECS="mp4a.40.2,avc1.100.40",RESOLUTION=1680x750,FRAME-RATE=24,VIDEO-RANGE=SDR

I understand the differences is that because others have the m3u8 as a playlist of different playlist for differences internet speed, while mine is just simply playlist of the segments. Even I try to create a playlist of playlist as they do, it still not working. Can someone tell me the key problem here why is my playlist can't be parsed and played, thanks in advanced.

Expected behaviour

  1. My m3u8 can be played as others m3u8
  2. Mine can't be played, while others can

Reproducible sample code

The code is as normal

  <Video
    source={{uri: 'My local host path',}} // the video file
    // Working m3u8 file
    // source={{uri: "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8"}}

    paused={false} // make it start    r
    style={styles.backgroundVideo} // any style you want
    repeat={true} // make it a loop
    ref={videoRef} // Store reference
    onBuffer={this.onBuffer} // Callback when remote video is buffering
    onError={error => {
      console.log(error);
    }}
  />

Video sample

Here is the working m3u8 URL https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8

freeboub commented 1 year ago

Just a question, did you try to force the type to m3u8 in the source parameter ? It looks like exoplayer didn't even try to download the file (as it cannot infer the media type)

HMT2002 commented 1 year ago

Just a question, did you try to force the type to m3u8 in the source parameter ? It looks like exoplayer didn't even try to download the file (as it cannot infer the media type)

I not really understand your meaning of force the type to m3u8 in the source parameter, if you asking whether I change the exoplayer or react-native-video player, then I only change the kotlin-gradle-plugin to 1.6.20 so that it can be complied, that just it. But I think I found the problems already. I use my own server to serve the m3u8 and the segments. I have 2 type of server, 1 is the central, use to redirect client to the sub-server, which the actual server that serve the files. It go like this client -->central -->sub-server. After central receive client request and do some checking, it redirect the request to subserver. There are some logs too, so I pretty sure the central and the sub-server received the request and served the file to client. But here the problem, if request go as above, it will show the error above, but if request go client --> sub-server, it work. So I guess problem can be because player doesn't take redirect URL or somethings. Do you have any ideas about this problems, and how can I fix it with out changing the flow?

freeboub commented 1 year ago

Ok, better description / investigation !

Yes I had a similar use case in some of my projects. I think this is an exoplayer limitation / behavior. When it will download chuncks it will use the NOT redirected url but the original url.

To bypass this behavior I resolve the redirection on the application side and provide the redirected manifest url to react native video. I didn't find an easy way to do that in JS , so I had to implement this redirection resolving in a custom native module.

I think it can be a common problem and can be integrated in react native video (if you have time :) ). I can help you define the best approach if you want.

Thank you.

HMT2002 commented 1 year ago

Thanks for the reply anyway, I guess I have to figure different approach instead of redirecting. 'Cause I have seen others player such as VLC do take redirect url, so I just kinda defaultly assume it can be done within the transcoder or the encode library, not the player.

freeboub commented 1 year ago

👍 I don't exactly know why you do that, but on my side it was used for load balancing. If you agree, we can close the ticket ?

schimini commented 3 months ago

@freeboub Hi! I think I'm having a similar issue with vimeo hls videos. Can you point me in the right direction to fix this ? Is the idea to regenerate master m3u8 files with pre-calculated urls?

Thanks !

freeboub commented 3 months ago

@schimini no, not exactly here the issue was redirection, url were good. The idea of the discussion was to ensure the source url is directly pointing to a content. Initially when I retrieve the content (m3u file) I have an error 3xx indicating that I should retrieve the content from somewhere else. Do we agree on the use case ?