Use separate FFmpeg processes for each input channel to avoid resource contention and simplify error handling. This approach allows independent bitrate control, distinct output destinations, and stable operation even if one stream fails. You can manage these instances efficiently using a simple shell script or systemd services.
The Case for Multiple Instances
When dealing with professional video capture cards that provide multiple independent inputs, such as HDMI 1, HDMI 2, or SDI channels, the most robust architecture is to run one ffmpeg process per physical input. While it is technically possible to use complex filter graphs to merge streams within a single process, this introduces significant complexity regarding synchronization and resource allocation. If the filter graph crashes, all outputs are lost. By isolating each input into its own process, you ensure that a failure in processing Channel A does not impact the stability of Channel B.
This method also aligns better with modern multi-core CPUs. Each FFmpeg instance can utilize a dedicated CPU core for encoding, preventing the bottleneck that often occurs when a single process tries to handle multiple decoders and encoders simultaneously. Furthermore, managing logs and debugging becomes significantly easier when each stream has its own standard output and error stream.
Identifying Input Devices
Before launching any commands, you must correctly identify how your operating system exposes the capture card’s inputs. On Linux, tools like v4l2-ctl are essential. You can list all available devices and their capabilities by running:
v4l2-ctl --list-devices
This command will show you the device nodes (e.g., /dev/video0, /dev/video1) associated with your hardware. It is crucial to verify that each input corresponds to a unique device node. Some high-end capture cards may present multiple virtual devices for a single physical card, while others might require specific kernel modules to be loaded for each channel. Ensure that your user account has read/write permissions for these device nodes, typically by adding the user to the video group.
If you are on Windows, you would typically use DirectShow or Media Foundation sources, identifying them by their friendly names in FFmpeg's device list. The principle remains the same: each logical input must map to a distinct source identifier.
Launching Independent Processes
Once your inputs are identified, you can launch the FFmpeg instances. Below is an example for two HDMI inputs on a Linux system. Note that we use different output ports or paths for each stream to prevent file conflicts.
# Instance 1: Capture from /dev/video0
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset fast -b:v 2500k -an output_stream_1.mp4 &
# Instance 2: Capture from /dev/video1
ffmpeg -f v4l2 -i /dev/video1 -c:v libx264 -preset fast -b:v 2500k -an output_stream_2.mp4 &
The & at the end of each command runs the process in the background, allowing the shell to accept further commands. In a production environment, you should replace -an (no audio) with appropriate audio settings if your card provides audio channels. For network streaming, replace the local file output with an RTMP URL. For more details on streaming configurations, see Streaming Integrated Camera on Facebook using FFmpeg.
It is critical to monitor the exit codes of these background processes. If one FFmpeg instance crashes due to a dropped frame or hardware timeout, it will terminate, leaving that specific channel offline while others continue. This isolation is the primary benefit of this architecture.
Managing Stability and Logs
Running raw FFmpeg commands in the background is insufficient for long-term reliability. You need a wrapper script or a service manager to restart crashed instances automatically. A simple bash loop can achieve this:
#!/bin/bash
while true; do
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset fast -b:v 2500k -an output_stream_1.mp4
echo "Stream 1 crashed, restarting in 5 seconds..."
sleep 5
done
For enterprise-grade setups, use systemd. Create a service unit file for each input. This ensures that the OS manages the lifecycle of the process, handles logging via journald, and restarts the service on failure. This approach eliminates the need for custom shell loops and provides better integration with system monitoring tools.
Additionally, consider implementing retry logic if you are streaming over a network. Network instability can cause FFmpeg to exit. Implementing exponential backoff in your wrapper script prevents rapid restarts that could overwhelm the server. See Implementing FFmpeg Retry Logic for Live Streaming for strategies on handling transient network errors.
Resource Monitoring
With multiple instances running, CPU and memory usage will scale linearly with the number of inputs. Use tools like htop or top to verify that each FFmpeg process is assigned adequate resources. If you notice high CPU usage causing dropped frames, consider lowering the -preset value (e.g., from fast to superfast) or reducing the resolution. Hardware acceleration, such as VAAPI or NVENC, can offload encoding tasks from the CPU, allowing you to run more instances on the same hardware. For information on using hardware encoders, refer to Streaming fMP4 via ffmpeg using H.264_vaapi encoder: A Hardware Solution.
Frequently Asked Questions
Can I combine multiple inputs into a single FFmpeg process?
Yes, but it requires complex filter graphs and shared memory management, which increases the risk of total system failure if one input drops. It is generally recommended to keep inputs separate for stability and easier debugging.
How do I handle audio from multiple HDMI inputs?
You must specify the correct audio device index for each input. Use -map 0:a:0 to select the first audio stream from the first input. Ensure your capture card supports multi-channel audio extraction, as some cards only pass through audio from the active video source.
What happens if one FFmpeg instance crashes?
Only the failed instance stops; other instances continue running unaffected. To restore the failed stream, you need a watchdog script or systemd service configured to auto-restart the process upon exit.
How can I reduce CPU load for many simultaneous streams?
Use hardware encoders like NVIDIA NVENC or Intel QuickSync (QSV). These offload the heavy lifting of H.264/H.265 encoding from the CPU cores, allowing you to run significantly more instances on the same machine.
Is it better to use MP4 or FLV for live streaming?
For live streaming, container formats like FLV or MPEG-TS are preferred because they support seamless appending of data. MP4 files require a finalization step to make them playable, which is not suitable for continuous live feeds.