Super handy terminal-based tool for working with video.
Some examples I use.
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
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
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
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]
Add -an
to your command.
Rotate 90°.
ffmpeg -i inputfile.ext -vf "transpose=1" outputfile.ext
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 timeHH:MM:SS
you can just give a number of seconds.-ss
or -to
|t
will use the file's existing start or end time.-c copy
it will re-encode the videoffmpeg -i [file] frame%03d.png
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - [file]
Default loops. Add -loop -1
to only play once.
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - [filename].gif
Default doesn't loop. Add -plays 0
to loop.
cat *.png | ffmpeg -framerate [framerate] -f image2pipe -i - -f apng [filename].png
Slow, but compresses better:
-preset veryslow
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
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"