If you know anything about me then you know I love automating anything and everything. I even have a complete course on building automation CLI tools with Node.js.
In this post, I am sharing a couple of super useful ffmpeg
workflows.
If you know anything about me then you know I love automating anything and everything. I even have a complete course on building automation CLI tools with Node.js.
In this post, I am sharing a couple of super useful ffmpeg
workflows.
FFmpeg is a free and open-source software project consisting of a large suite of libraries and programs for handling video, audio, and other multimedia files and streams. At its core is the FFmpeg program itself, designed for command-line-based processing of video and audio files.
Converting videos and audio has never been this easy. I’m able to do a lot of excellent tricks with this command-line tool. Actually, that’s a good enough introduction โ let me share the real deal.
# Gif to video.
# https://web.dev/replace-gifs-with-videos/
function gif2vid() {
if [[ "-h" == "$1" ]]; then
echo "-"
echo "${wb}${bf}โ Help! โ${r}"
echo "${wb}${bf}USAGE: rgif2vid some.gif nameOfVideos${r}"
echo "-"
return 1
else
ffmpeg -i "$1" "$2".mp4
ffmpeg -i "$1" -c vp9 -b:v 0 -crf 41 "$2".webm
fi
}
# Video cutting.
function cut1min() {
for i in *.mp4;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -ss 00:00:00.000 -i "$i" -t 60 -c:v libx264 -c:a copy "${name}-1min.mp4"
done
}
# vidtrim <vid file name> <seconds to trim from start>
# vidtrim vid.mp4 5
function vidtrim() {
ffmpeg-bar -i "$1" -ss "$2" -vcodec copy -acodec copy trimmed-"$1"
}
# vidjoin <intro vid file name> <actual vid file name>
# vidjoin intro.mp4 input.mp4
function vidjoin() {
echo file "$1" >> vidjoin.txt
echo file "$2" >> vidjoin.txt
ffmpeg-bar -f concat -i vidjoin.txt -c copy output.mp4
rm vidjoin.txt
}
ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
-vn
is no video.-acodec copy
use the same audio stream that’s already in there.# Rotate 90 clockwise:
ffmpeg -i in.mov -vf "transpose=1" out.mov
For the transpose parameter you can pass:
0 = 90 Counter Clockwise and Vertical Flip (default)
1 = 90 Clockwise
2 = 90 Counter Clockwise
3 = 90 Clockwise and Vertical Flip
Use -vf "transpose=2,transpose=2"
for 180 degrees.
For Linux and macOS this can be done in one line, using parameter expansion to change the filename extension of the output file:
for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
An alternate method would be like this:
for i in *.avi;
do name=`echo "$i" | cut -d'.' -f1`
echo "$name"
ffmpeg -i "$i" "${name}.mov"
done
To convert with subdirectories use:
find . -exec ffmpeg -i {} {}.mp3 \;
You can use -progress -
to print-friendly info formatted by key=value
.
ffmpeg -i vid.mp4 -progress - -y out.mp4
speed=3.15x
frame=458
fps=45.8
stream_0_0_q=39.0
bitrate=2337.0kbits/s
total_size=1231258682
out_time_ms=12323423
out_time=00:00:58.44534
dup_frames=0
drop_frames=0
You can use -qscale:v
(or the alias -q:v
) to control image quality from a video as an output option.
qscale
being roughly half the bitrate.-qmin 1
output option (because the default is -qmin 2
).ffmpeg -i input.mp4 -qscale:v 2 output_%03d.jpg
See the image muxer documentation for more options involving image outputs and their quality requirements.
ffmpeg -ss 60 -i input.mp4 -qscale:v 4 -frames:v 1 output.jpg
ffmpeg -i infile.mp4 -i infile.srt -c copy -c:s mov_text outfile.mp4
The order of -c copy -c:s mov_text
is quite important.
You are telling FFmpeg to do the following:
Alternatively, you could just use -c:v copy -c:a copy -c:s mov_text
in any order.
This method adds the subtitles to your video file as one of the streams. You will need player support to view the subtitles (such as VLC).
This will “burn them into” the video, meaning you can’t turn them off in the player. This is different from adding them as a subtitle stream which can be read by the player and displayed if the viewer wants them.
If your FFmpeg has libass enabled at compile-time, you can directly do:
ffmpeg -i mymovie.mp4 -vf subtitles=subtitles.srt mysubtitledmovie.mp4
Otherwise, you can the libass
library (make sure your FFmpeg install has the library in the configuration --enable-libass
).
First, convert the subtitles to .ass
format: (haha fun extension name)
ffmpeg -i subtitles.srt subtitles.ass
Then add them using a video filter:
ffmpeg -i mymovie.mp4 -vf ass=subtitles.ass mysubtitledmovie.mp4
ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g'
I hope you enjoy some of these. I’ll take some more time out to explain all of these and add a couple more which are tied up in a bit extra complex workflow, un-needed for this post.
Use your code for good. Peace!
Stay ahead in the web dev community with Ahmad's expert insights on open-source, developer relations, dev-tools, and side-hustles. Insider-email-only-content. Don't miss out - subscirbe for a dose of professional advice and a dash of humor. No spam, pinky-promise!