In a live stream setup, I have 2 cameras and each one sends RTMP stream to one different application which is on my Nginx-RTMP server. On the browser I am using Videojs Hls plugin.

Now my question is how can I load these two streams one after another in the same hlsplayer player instance. For example, I want to load the first 15 seconds in my first source and the next 15 seconds from my second source in the same player. Since the .ts files are named incrementally and if I have 5sec chunks of .ts files in each .m3u8 file, I want to load the first 3 .ts files to be loaded from the first source(.m3u8 file) and the next 3 from another source(.m3u8 file). How can I achieve that?

Can I generate some kind of master M3U8 file which has the list of these other .M3U8 files or can I develop a plugin in videojs to load the appropriate ts files directly?



I want to load 1.ts from source1.m3u8 and 2.ts from source2.m3u8 but with no delay or lag.

  • 1
    Do you have a solution? Commented Nov 24, 2019 at 0:40
  • Did you ever work this out?
    – Piotr Kula
    Commented Aug 23, 2022 at 12:32

1 Answer 1


Switching between multiple HLS streams can be useful in two scenarios:

  • The typical scenario is multi-bitrate HLS, where you switch between different bitrates and resolutions to accommodate different client bandwidths.
  • Backup and disaster recovery scenarios, where you switch between two similar HLS streams when one becomes unavailable.

Multiple Resolution HLS

Multi-bitrate HLS cannot be implemented on the streaming server itself. As you mentioned, two HLS .ts files need to be switchable, with the same name and content, to avoid issues like stuttering or image repetition. Multi-bitrate encoding needs to be done at the encoder level, such as using FFmpeg to transcode an RTMP stream into multiple HLS streams with different bitrates:

ffmpeg -f flv -i "rtmp://server/live/livestream" \
  -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
  -c:v libx264 -crf 22 -c:a aac -ar 44100 \
  -filter:v:0 scale=w=480:h=360  -maxrate:v:0 600k -b:a:0 500k \
  -filter:v:1 scale=w=640:h=480  -maxrate:v:1 1500k -b:a:1 1000k \
  -filter:v:2 scale=w=1280:h=720 -maxrate:v:2 3000k -b:a:2 2000k \
  -var_stream_map "v:0,a:0,name:360p v:1,a:1,name:480p v:2,a:2,name:720p" \
  -preset fast -hls_list_size 10 -threads 0 -f hls \
  -hls_time 3 -hls_flags independent_segments \
  -master_pl_name "livestream.m3u8" \
  -y "livestream-%v.m3u8"

It will generate a master.m3u8, which contains 3 different m3u8 with different resulutions. You can refer to the detailed explanation in the provided link.

Fault Tolerance HLS

For backup and disaster recovery scenarios, the two HLS streams don't need to be identical. When one HLS stream becomes unavailable, users will likely refresh the encoder. At this point, switching to another HLS stream or providing a manual switch option can achieve fault tolerance.

Additionally, HLS distribution is usually done through a CDN, which inherently provides fault tolerance for an HLS stream. For self-built HLS CDN distribution scenarios, you'll need to handle this yourself. In this case, it's more suitable to have backup and switching at the RTMP level. You can push multiple RTMP streams, choose an available one to generate HLS, and use an FFmpeg script to achieve this:

while TRUE; do
  ffmpeg -re -i rtmp://ip/app/stream1 -c copy -f flv rtmp://ip/app/production;
  ffmpeg -re -i rtmp://ip/app/stream2 -c copy -f flv rtmp://ip/app/production;
  sleep 0.5;

It only generate one HLS stream, but switch between different source RTMP stream. For more information, refer to the detailed explanation in this post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.