About FFmpeg (and other command line!) support
We have a cool new feature, FFmpeg and other command line tools support.
Basically, you can use FFmpeg (or other command line tools) to do things like:
- Receiving streams (like libVLC, but FFmpeg runs as a separate process so if it crashes it cannot take Stereo Tool down with it)
- Sending streams, in all kinds of formats (HTTP streams work, and it can encode FLAC etc)
- Reading from or writing to files - so yes, this basically means that there's now a file writer
- Replacing audio in a live video stream while keeping audio and video in sync! (demux audio/video, run audio through Stereo Tool, mux audio/video again while delaying the video to match the audio)
- There's probably much more. Let me know if you find any other uses.
In this first version, we have only focussed on making it work, not on making it easy to use. Tom is working on redesigning the I/O framework, once that's done we'll make all of this much easier. For now, read the text below to know how to use it.
Limitations that we are planning to resolve soon:
- You have to enter FFmpeg command line strings to make it work. No easy-to-use parameters yet.
- Current code always uses 16 bit audio; we'll fix that later.
- For video demux/mux, there is a hard coded delay of 7 seconds.
- We can only read and write a single audio stream in this version. We will add support for multiple, for example for video with multiple languages.
- Support this for Input 2, and later also for FM output.
Issues to be looked into:
- What should the behavior be if the input signal disappears? Right now we block, and after some time the watchdog will try to restart FFmpeg. Especially for use in Input 2 for example we may need something that keeps feeding Stereo Tool with silence.
Example: Play a file
Code:
C:\ffmpeg\bin\ffmpeg -y -re -i "C:\ffmpeg\bin\T\TTT.MP4" -map 0:a:0 -vn -f s16le -ar 48000 -ac 2 {OUT1}
-re makes it run at normal speed instead of as fast as possible. {OUT1} is the output from FFmpeg to Stereo Tool
Example: Write to a file
Code:
C:\ffmpeg\bin\ffmpeg -y -f s16le -ar 48000 -ac 2 -i {IN1} -c:a aac -b:a 192k -movflags +faststart C:\\temp\\out.m4a
Without +faststart this hangs! {IN1} is the input from Stereo Tool to FFmpeg!
Example: Replace audio in a video file
Code:
C:\ffmpeg\bin\ffmpeg -y -re -i C:\ffmpeg\bin\T\TTT.MP4 -re -itsoffset 7.000 -i C:\ffmpeg\bin\T\TTT.MP4 -f s16le -ar 48000 -ac 2 -i {IN1} -map 1:v:0 -c:v copy -map 2:a:0
-af aresample=async=1:first_pts=0 -c:a aac -b:a 192k -max_interleave_delta 0 -muxdelay 0 -muxpreload 0 -shortest C:\ffmpeg\bin\T\output.mp4 -map 0:a:0 -f s16le -ar 48000 -ac 2 {OUT1}
(Remove the enter!)
Important: You need to have a perfectly identical line for the input and output device for this to work!
-itsoffset 7.000 delays the video by 7 seconds, which is exactly the (currently hard coded) delay. This reads a file C:\ffmpeg\bin\T\TTT.MP4 and writes the output to C:\ffmpeg\bin\T\output.mp4
In all these examples, instead of files you can also use streams! FFmpeg also receives HLS streams for example.
Creating command lines
Since most people probably aren't experts in crafting FFmpeg command lines, here's a ChatGPT prompt that you can use to help you write one. Make sure that after using it, you replace the FFmpeg binary with the full path to FFmpeg on your system, and that input and output files and paths are correct.
Code:
You are helping me build ffmpeg command lines for an app that uses placeholders instead of real pipe paths. Please follow these rules exactly:
Placeholders (must use these)
{IN1} = audio input from my app into ffmpeg (my app writes PCM here; ffmpeg reads it).
{OUT1} = audio output from ffmpeg to my app (ffmpeg writes PCM here; my app reads it).
Do not replace these placeholders with OS paths or tcp://… URLs. The app will substitute them.
PCM format (default unless I say otherwise)
Raw PCM: -f s16le -ar 48000 -ac 2
What I might ask for
Input-only (send audio from a file/stream to my app via {OUT1}).
Output-only (take audio from {IN1} and write to a file/stream).
Pass-through (read a media source for video, replace/encode audio from {IN1}, and optionally also tap original audio to {OUT1}).
Optional details I may provide: sample rate, channels, codec/bitrate, container, delay (on audio or video), real-time pacing, low-latency, etc.
Flags & style
Keep commands minimal and robust for embedding in an app (no shell redirections like 1>/2>; no -nostdin unless necessary).
Use -y only when writing a file (to avoid overwrite prompts). Omit -y otherwise.
For inputs, use -re unless I say that it should not run at “real-time pace”.
Avoid huge -thread_queue_size; omit unless clearly useful (or use a small value like 64 near the -i it affects).
For video passthrough, prefer -map and -c:v copy when we’re not re-encoding video.
For audio encoding, default to -c:a aac -b:a 192k unless I request something else.
If I ask to align/delay, prefer shifting the audio with -itsoffset on the audio input (or the video if I ask). The software currently causes a hard coded audio delay of exactly 7 seconds.
If we tap original audio to {OUT1}, output it as raw PCM with the same PCM format block noted above.
Output format (very important)
Give me one command line (Windows-friendly quoting is fine) plus a 1–2 line explanation.
If there are variants (e.g., MP4 vs M4A), show the best default first, and optionally one neat alternative.
Don’t add extra commentary.
Quick examples (follow these patterns)
Input-only (file → my app):
ffmpeg -re -i "video.mp4" -map 0:a:0 -vn -f s16le -ar 48000 -ac 2 {OUT1}
(Real-time paced audio from the file to my app.)
Output-only (my app → file, AAC):
ffmpeg -y -f s16le -ar 48000 -ac 2 -i {IN1} -c:a aac -b:a 192k out.m4a
(Take PCM from my app and encode to AAC in M4A.)
Replace audio but keep video copy:
ffmpeg -i "video.mp4" -f s16le -ar 48000 -ac 2 -i {IN1} -map 0:v:0 -c:v copy -map 1:a:0 -c:a aac -b:a 192k output.mp4
(Copy video, use my app’s audio as the new track.)
Add audio delay (e.g., delay audio by 2.2 s):
ffmpeg -i "video.mp4" -f s16le -ar 48000 -ac 2 -itsoffset 7.0 -i {IN1} -map 0:v:0 -c:v copy -map 1:a:0 -c:a aac -b:a 192k output.mp4
Here are some download links to FFmpeg binaries for Windows:
https://www.gyan.dev/ffmpeg/builds/
https://github.com/BtbN/FFmpeg-Builds/releases
By the way, you can use this for any command line program that accepts named pipes as input or output. For example, on Linux you can just write
Code:
cat {IN1} > /tmp/file.pcm
to write the output audio to that file. You can even pipe audio through a command line version of Stereo Tool - no idea why you would want that but it's possible.