User Tools

Site Tools


ffmpeg

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

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. [-qscale: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 a in ./*.flac; do ffmpeg -i "$a" [-qscale:a 0|-b:a 320k] "${a[@]/%flac/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"

See Also

ffmpeg.txt · Last modified: 2022/04/14 21:12 by rjt