I would like to serve video files in my mobile app (React Native using the react-native-video player). The two things I care about are:
- Adaptive bitrate so people with slower bandwidth (e.g., LTE) can still watch the video with minimal buffering
- Fast seek times
- Low bandwidth consumption
It seems like HLS streaming (specifically an .m3u8 playlist + TS files) fits all the above criteria.
I used ffmpeg
with -hls_time 6
(6 second segment lengths, as recommended by Apple) to generate the files. Here's an example of a master playlist:
# sample-30s.m3u8
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=1205600,RESOLUTION=1920x1080,CODECS="avc1.640032,mp4a.40.2"
sample-30s_0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=105600,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
sample-30s_1.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=52800,RESOLUTION=854x480,CODECS="avc1.64001f,mp4a.40.2"
sample-30s_2.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=52800,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2"
sample-30s_3.m3u8
I then store them on DigitalOcean Spaces and source them in react-native-video
via the CDN endpoint for the master playlist, e.g.:
https://onecoach-public.nyc3.cdn.digitaloceanspaces.com/classes/beginner-to-2.0/1-ball-control/1-why-ball-control/view0_hls/view0.m3u8
This all works fine and dandy on my 50Mb/s down Wifi, but when I switch over to LTE (~5-10Mb/s from DO's NYC1 datacenter) the HLS stream seems to buffer every 6s (on the boundary of the segments). Each segment is ~800KB, so 5Mb/s should be more than enough to download each segment in time.
Am I doing something wrong here?