Skip to content

ffmpeg

ffmpeg is a tool for editing movie files.

Examples

Convert container format

This will copy all streams from every mkv container file in the current directory into an mp4 container file.

for X in *.mkv ; do ffmpeg -i "${X}" -codec copy -map 0 "${X%.mkv}.mp4" ; done ;

Some codecs will not be compatible and will need to be transcoded in order to be mp4 compatible. Here is an example that transcodes video to h264 using hardware hardware transcoding (h264_videotoolbox):

FILE=all-your-base.mkv
ffmpeg -i "${FILE}" -c:v h264_videotoolbox -b:v 4000k -c:a copy "${FILE%.mkv}.mp4"

Sample video output settings

Before spending a long time converting a video, it's good to sample what you would see. You can render only a portion of the movie to make sure your settings are not too low. The following example starts encoding from 35 minutes into the source file (-ss HH:MM:SS.ss) and produces 20 seconds of output (-t HH:MM:SS.ss):

ffmpeg -ss 00:35:00 -t 00:00:20.00 -i "${FILE}" -c:v h264_videotoolbox -b:v 4000k -c:a copy "${FILE%.mkv}.mp4"

Note that the HH:MM:SS.ss is given in the time duration spec that is detailed in man ffmpeg-utils and can have other forms.

Also note that -ss behaves differently depending on where it is placed in the command in regard to the input and output files.

Time Lapse

Generate a movie from an image sequence like 001.jpg-999.jpg

ffmpeg -r 10 -b 1800 -i %03d.jpg test1800.mp4

Rename files as a sequence:

i=0 ;
find . -type f |
  while read -r F ; do
    let i=${i}+1 ;
    fn=$(printf %06d ${i}) ;
    mv "${F}" "${fn}.jpg" ;
  done ;

Sample some of the middle of the time-lapse

ffmpeg -pattern_type sequence -start_number 3000 -r 30 -i %06d.jpg -s 1440x1080 -frames 120 "$(date +%F_%T).mp4"

Turn these images into a video

ffmpeg -pattern_type sequence -r 30 -i %06d.jpg -s 1440x1080 "$(date +%F_%T).mp4"

Audio Replace

Replace the audio of DSC_4436.AVI with 01 Gymnopedie 1.mp3 and limit the duration of the output so the music doesn't play beyond the end of the video.

ffmpeg -t 00:00:47.99 -i DSC_4436.AVI -i "01 Gymnopedie 1.mp3" -map 0:0 -map 1:0 -vcodec copy -acodec copy output.AVI

Slow down video to half speed, drop audio

ffmpeg -i DHO_8751.MOV -an -vf "setpts=(2/1)*PTS" output.mp4

Extract two seconds worth of frames at 24fps starting at 15m

ffmpeg -i movie.mkv -r 24 -t 00:00:02.00 -ss 00:15:00 temp/movie-%4d.jpg

Detect errors in files

ffmpeg -v error -i 20091024-08-46-00.mpg -f null - 2>> error.log

Dump a raw stream

If you encounter a file that has an unsupported stream and you want to dump it for analysis, you can use ffprobe to see what streams there are. ffprobe will produce output including something like:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'DJI_20230929174507_0003_D.MP4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    creation_time   : 2023-09-29T21:45:07.000000Z
    encoder         : DJI Mini4 Pro
  Duration: 00:00:18.28, start: 0.000000, bitrate: 93326 kb/s
  Stream #0:0[0x1](und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709), 3840x2160, 90422 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
    Metadata:
      creation_time   : 2023-09-29T21:45:07.000000Z
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Data: none (djmd / 0x646D6A64), 68 kb/s
    Metadata:
      creation_time   : 2023-09-29T21:45:07.000000Z
      handler_name    : DJI meta
  Stream #0:2[0x3](und): Data: none (dbgi / 0x69676264), 2315 kb/s
    Metadata:
      creation_time   : 2023-09-29T21:45:07.000000Z
      handler_name    : DJI dbgi
  Stream #0:3[0x0]: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 90k tbr, 90k tbn (attached pic)
Unsupported codec with id 0 for input stream 1
Unsupported codec with id 0 for input stream 2

Here we see 4 streams. 0:0 is a video stream, 0:1 is a DJI meta data stream, 0:2 is a DJI dbgi data stream, and 0:3 is a video mjpeg stream. Using this list as a reference, we can dump an individual stream. For instance, to dump the 0:2 stream:

ffmpeg -i DJI_20230929174507_0003_D.MP4 -map 0:2 -f data -c copy stream2.bin

Reduce frame rate

This example is taken directly from https://trac.ffmpeg.org/wiki/ChangingFrameRate

ffmpeg -i src.mp4 -filter:v fps=30 dest.mp4

Record video from a macOS webcam

This is video only, no audio

ffmpeg -f avfoundation -r 30 -i 1 webcam.mov

Screen record a macOS desktop

ffmpeg -f avfoundation -r 30 -i 3 screen_capture.mov

Generate a timelapse from DJI hyperlapse photos

The DJI Hyperlapse videos are pretty awful, with unnecessary cropping and perspetive warping. You're better off generating your own movie from the still images it took. To do so, cd to the directory with the hyperlapse photos in it and run:

ffmpeg -framerate 30 -pattern_type glob -i "HYPERLAPSE*.JPG" -s:v 4032x3024 -c:v libx264 -crf 17 -pix_fmt yuv420p timelapse.mp4

You may need to adjust the 4032x3024 dimensions if you are not using the Mini 4 Pro.

Crop a video

Find the dimensions of your video with exiftool -ImageSize "$FileName" or ffprobe -v error -show_entries stream=width,height -of default=noprint_wrappers=1 "$FileName". Once you have that, you must construct a command like this:

ffmpeg -i Sunset.mp4 -filter:v "crop=2884:2160:478:0" Sunset-cropped.mp4

Where 2884 is the width, 2160 is the height, 478 is how far to shift the crop from the left edge of the frame, and 0 is how far to shift the crop from the top of the frame.