Table of Contents
FFmpeg
Super handy terminal-based tool for working with video.
Use
Some examples I use.
Converting
Most of the time I just use—
ffmpeg -i [input.ext] [output.ext]
—and it usually works fine leaving it to just use defaults.
This gives good results (and a smaller file size) converting MP3 to OGG though:
ffmpeg -i [input].mp3 -c:a libvorbis -q:a 4 [output].ogg
Fuck-off those .WEBMs:
ffmpeg -i [input].webm -acodec copy -vcodec copy [output].mkv
Multiple
For doing a whole directory I use this one-liner I got from Stack Exchange.
for i in *.[ext]; do ffmpeg -i "$i" "${i%.*}.[ext]"; done
For converting files for my m-u-s-u-c blog I also strip out the cover images: -map a
tells it to take only the audio stream.
for i in *.mp3; do ffmpeg -i "$i" -c:a libvorbis -q:a 4 -map a "${i%.*}.ogg"; done
You can use the wildcard *
in the file extension to, so if you've got a mix of .mkv and .mp4 files from Youtube you can do. say:
for i in *.m*; do ffmpeg -i "$i" "${i%.*}.ogv"; done
If you want to put the new videos into a subdirectory, first create it, then simply add it to the output part:
for i in *.[ext]; do ffmpeg -i "$i" "directory/${i%.*}.[ext]"; done
For converting a directory of .FLAC files to .MP3. [-q:a 0|-b:a 320k]
is your choice between VBR with the best quality (0) or a CBR of 320k. VBR is generally just as good, though sometimes you need CBR.
for i in *.flac; do ffmpeg -i "$i" [-q:a 0|-b:a 320k] "${i%*}.mp3"; done
Editing
Concatenation
The main thing I use FFmpeg for is just stitching videos together. I make a list of the files inside a text document, each line looks like this:—
file '[file location]'
—then point FFmpeg at that and give the command and it runs through them all. Nice and easy.
ffmpeg -f concat -safe 0 -i "inputfile.txt" -c copy "inputfile.ext"
FFmpeg's docs on generating the list:
# with a bash for loop for f in *.wav; do echo "file '$f'" >> mylist.txt; done # or with printf printf "file '%s'\n" *.wav > mylist.txt
If you have a movie in two parts and want to stick them together with less fuss, or you just want to save yourself the trouble of making the file, you can use process substitution:
ffmpeg -f concat -safe 0 -i <(for f in ./*.avi; do echo "file '$PWD/$f'"; done) -c copy output.avi
NB: Some older codecs let you stick files together with just Cat!: https://ffmpeg.org/faq.html#toc-Concatenating-using-the-concat-protocol-_0028file-level_0029
Cropping
To crop a 16:9 video to 4:3, add:
-filter:v "crop=ih/3*4:ih"
Full example, with copied audio stream:
ffmpeg -i [file] -filter:v "crop=ih/3*4:ih" -c:a copy [file]
Remove Audio
Add -an
to your command.
Rotation
Rotate 90°.
ffmpeg -i inputfile.ext -vf "transpose=1" outputfile.ext
Trimming
You can pretty easily make a video shorter. The only caveat is that if you don't want to re-encode you're limited by where keyframes are placed.
ffmpeg -i inputfile.ext -ss HH:MM:SS -to HH:MM:SS -c copy outputfile.ext
-ss
is the point you want it to start-to
is the point you want it to end-t
is the length you want it to run from the start time- Instead of using the format
HH:MM:SS
you can just give a number of seconds.- You can also add milliseconds to either of those formats.
- Leaving out the
-ss
or-to
|t
will use the file's existing start or end time. - If you leave out the
-c copy
it will re-encode the video
Images
Extract each frame as an image
ffmpeg -i [file] frame%03d.png
Create video from images
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - [file]
GIF
Default loops. Add -loop -1
to only play once.
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - [filename].gif
APNG
Default doesn't loop. Add -plays 0
to loop.
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - -f apng [filename].png
Lowering the file size
Slow, but compresses better:
-preset veryslow
Bitrate
Dimensions
Scales 50%
ffmpeg -i "inputfile.ext" -vf "scale=iw/2:ih/2" "outputfile.ext"
Scales to set pixel dimensions (replace 'width' and 'height'):
ffmpeg -i "inputfile.ext" -vf scale=width:height "outputfile".ext
Repairing
Just had an .AVI file throwing error messages about a busted index. Copying the file seemed to fix it.
ffmpeg -i "inputfile.avi" -c:v copy -c:a copy "outputfile.avi"
Frontends
- FFmpeg Explorer - Browser-based GUI with a node-based interface for changing parameters.