Switch Video Streams with FFmpeg Streamselect
This guide explains how to dynamically switch between multiple input
video streams in FFmpeg using the streamselect filter. You
will learn the core parameters of streamselect, how to
combine it with the sendcmd filter to schedule stream
transitions at specific timestamps, and how to control stream switching
in real time using ZeroMQ.
Understanding the streamselect Filter
The streamselect filter takes \(N\) input streams and maps one or more of
them to the output. By default, it operates statically, but it supports
runtime commands to change the active input index without interrupting
the output stream.
Basic parameters include:
inputs: The number of input streams (default is 2).map: The 0-based index of the input stream(s) to route to the output.
Because streamselect does not evaluate dynamic
expressions on its own, dynamic switching requires sending commands to
it during processing. This is typically achieved using either the
sendcmd filter (for pre-planned, time-based switching) or
the zmq filter (for interactive, external control).
Scheduled Switching with sendcmd
The sendcmd filter can dispatch commands to
streamselect at predefined timestamps.
Command Syntax
To switch streams, format the command string as:
[timestamp] streamselect map [input_index]
Example: Timed Switching
The following command takes two inputs (cam1.mp4 and
cam2.mp4). It starts on cam1.mp4 (index
0), switches to cam2.mp4 (index
1) at 5 seconds, and switches back to cam1.mp4
at 10 seconds.
ffmpeg -i cam1.mp4 -i cam2.mp4 -filter_complex \
"[0:v]sendcmd=c='5.0 streamselect map 1; 10.0 streamselect map 0'[cmd0]; \
[cmd0][1:v]streamselect=inputs=2:map=0[outv]" \
-map "[outv]" -c:v libx264 output.mp4In this command:
sendcmdintercepts stream0and injects switching instructions at seconds5.0and10.0.- Both the processed stream
[cmd0]and the second input[1:v]enterstreamselect. streamselect=inputs=2:map=0defaults to the first input until the command updates themapvalue.
Using an External Command File
For complex switching schedules, store the instructions in a separate
text file (e.g., commands.txt):
5.0 streamselect map 1;
10.0 streamselect map 0;
15.0 streamselect map 1;
Load the file using the f parameter:
ffmpeg -i cam1.mp4 -i cam2.mp4 -filter_complex \
"[0:v]sendcmd=f=commands.txt[cmd0]; \
[cmd0][1:v]streamselect=inputs=2:map=0[outv]" \
-map "[outv]" -c:v libx264 output.mp4Real-Time Switching with ZeroMQ (zmq)
If you are streaming live and need to switch inputs on demand,
combine streamselect with the zmq filter to
receive commands over a network socket.
ffmpeg -i live1.flv -i live2.flv -filter_complex \
"[0:v]zmq[cmd0]; \
[cmd0][1:v]streamselect=inputs=2:map=0[outv]" \
-map "[outv]" -c:v libx264 -f flv rtmp://destination/liveTo trigger a switch while FFmpeg is running, send a message to the
listening socket using the zmqsend utility or a custom
script:
echo "streamselect map 1" | zmqsendKey Considerations
- Stream Parameters: All input streams should share
the same resolution, pixel format, and frame rate. If they differ,
normalize them beforehand using
scale,fps, andformatfilters. - Audio Synchronization: The
streamselectfilter also supports audio streams (astreamselect). If you are switching video and audio together, route both through their respectivestreamselectandastreamselectfilters synchronized with matching timestamps.