ffmpeg
ffmpeg is a tool for editing movie files.
Links
- https://fileconverter.tommyjepsen.com: ffmpeg based video converter that runs in-browser
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.