in=... ; out=... # or eg. out="${in/%.mov/-small.mov}"
ffmpeg -i "$in"
Example:
ffmpeg -i "$in" -tune film -crf 20 -preset slow -b:a 192k -movflags +faststart "${in%%.webm}.mp4"
-c:v libx264 -pix_fmt yuv420p -tune film -crf 20 -g 50 -preset slow # (veryfast fast medium slow slower veryslow)
Can be used with -crf
-maxrate 6M -bufsize 6M
Or set an average bitrate, without using -crf
(see Limiting the output bitrate)
-b:v 4M -maxrate 6M -bufsize 10M
-c:v prores_ks -profile:v 1 -vendor apl0 -c:a pcm_s16le
See https://trac.ffmpeg.org/wiki/Scaling for details.
If using -s WxH
, you need to calculate the right sizes to preserve the aspect ratio. It's easier and generally better to use -vf scale=...
, which offers various shortcuts, and allows selecting the resizing algorithm.
Examples:
-vf "scale=hd1080" -vf "scale=hd1080:flags=lanczos" # same, but with lanczos algorithm instead of default bilinear -vf scale=640:-2 # width 640px, height as needed but divisible by 2 -vf "scale=iw/2:ih/2" # half width and height of original -vf "scale=iw/2:-2" # same (half width and height), but height divisible by 2 etc.
See https://ffmpeg.org/ffmpeg-filters.html#yadif :
yadif=mode:parity:deint
defaults: 0(send_frame=one frame for each frame) : -1(auto=auto detection of field order) : 0(all=all frames)
-vf "yadif=0:-1:0"
start=00:05:12.000 # or just seconds: start=312 duration=00:01:05.000 # or just seconds: duration=65 ffmpeg -i "$in" -ss $start -t $duration -c:v copy ...
If -ss $start
is before the -i
input, it may be faster in some cases. But with codecs like h264, the resulting output may also miss the needed keyframes at the start, and the beginning of the video may be corrupted.
All frames as .png:
in="file.mov"; out="${in%.*}.%06d.png" ffmpeg -i "$in" -f image2 "$out"
Here a frame at 5 seconds, and a frame at 300 seconds from the start
in="file.mov" for start in 5 300; do ffmpeg -ss $start -i "$in" -r 1 -vframes 1 -f image2 "${in/%.mov/}-at-$start-sec.png"; done
Output one image for every I-frame:
ffmpeg -i input.flv -vf "select='eq(pict_type,PICT_TYPE_I)'" -vsync vfr thumb%04d.png
Find all .mov files under some directory, and extract a single Jpeg:
pos=2 # get frame at $pos seconds from start of file search_in=/mnt/x/y ext="mov" find "$search_in" -type f -name "*.$ext" -not -name ".*" \ | while read f; do n=$(basename "$f") [ -f "$n" ] && n="$n-$RANDOM" ffmpeg -nostdin -hide_banner -loglevel error -ss $pos -i "$f" \ -r 1 -vframes 1 -f image2 "$n.jpg" \ && echo "OK $n.jpg" done
Output all frames for a given duration (in seconds):
in="file.mkv" start=00:09:38.000 duration=20 out="${in%%.mkv}-$start.%04d.png" ffmpeg -ss $start -i "$in" -t $duration -f image2 "$out"
See also ffmpeg's Create a thumbnail image every X seconds of the video.
With numbered frames, the numbering must start at 0: "frame0000.png", "frame0001.png", "frame0002.png", ...
Frames to animated .webp :
in="test-tiff%08d.tif"; out="tiff-2.webp" ffmpeg -r 25 -i "$in" -c:v libwebp_anim -lossless 1 -loop 0 -preset default -an -vsync 0 -s 480x270 "$out"
Animated .gif to .webp (copied from Convert GIF to WebM with ffmpeg)
ffmpeg -i my-animation.gif -c vp9 -b:v 0 -crf 41 my-animation.webm
1 .jpg image = 1 frame :
in="image%03d.jpg" # image000.jpg to image999.jpg out="image-to-video.mp4" ffmpeg -framerate 25 -i "$in" -c:v libx264 -crf 18 -pix_fmt yuv420p "$out"
To start on a specific numbered frame, use -start_number
. Example staring at "image150.jpg":
in="image%03d.jpg" # image000.jpg to image999.jpg out="image-to-video.mp4" ffmpeg -start_number 150 framerate 25 -i "$in" -c:v libx264 -crf 18 -pix_fmt yuv420p "$out"
Slideshow with 1 .jpg = 1 second :
fps=25 out="slideshow-glob.mp4" ffmpeg -framerate 1 -pattern_type glob -i '*.jpeg' -c:v libx264 -crf 20 -g $fps -pix_fmt yuv420p -r $fps "$out"
If the size of the frames is uneven (eg. 512x459), it needs to be set to an even size, or there will be this error:
height not divisible by 2 (512x459)
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
In this case, specify the size. For example: -s 512x460
-c:a aac -b:a 192k
Using defaults:
ffmpeg -i input.ac3 -ac 2 output.ac3
Or manual:
... -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" ...
See also: https://forum.videohelp.com/threads/404278-Ac3-5-1-audio-track-convert-to-stereo
I think that since -map
is used, -map:v
must be added too or the output is without video.
-filter_complex "[0:a:0][0:a:1]amerge,channelmap=channel_layout=stereo[st]" -map 0:v -map "[st]"
dir="/path/to/output_dir"; mkdir -p "$dir" for f in *.flac; do f2=$(basename "${f%.flac}.mp3"); \ out="$dir/$f2"; \ ffmpeg -i "$f" -c:a libmp3lame -q:a 0 -c:v copy "$out" done
-q:a 0
with libmp3lame
makes it use best quality VBR. See https://trac.ffmpeg.org/wiki/Encode/MP3
-c:v copy
makes it copy album art if there is any (instead of converting it to .png)
The metadata from FLAC is preserved by default, and written to a ID3v2.4 header. To write an ID3v2.3 header instead, add the -id3v2_version 3
option.
Can be done with flac
instead of ffmpeg:
for f in *.wav; do flac "$f" --keep-foreign-metadata -V -o "${f%%wav}.flac" done
This was slow? 330 mn. for a 167 mn. / 600GB file with 16 audio channels. Not slow on 30GB 16channels quicktime. But doesn't separate channels!
time ffmpeg -i "$in" -map 0:a -af "volumedetect" -f null - 2>&1 | tee "$in-volumedetect.txt"
ffmpeg -i "$in" -vn -sn -dn -map 0:a -af "astats=measure_overall=none" -f null - 2>&1
See also https://ffmpeg.org/ffmpeg-filters.html#toc-ebur128-1
For a file with 12 mono audio tracks:
for t in {0..11}; do ffmpeg -nostats -i "$in" -map 0:a:$t -filter_complex ebur128 -f null - > $(printf "ebur-$in-a%02d.txt" $t) 2>&1 ; done
Move "moov" atom to start of file (https://ffmpeg.org/ffmpeg-formats.html#Options-8). (Implies file copy after encoding)
-movflags faststart
-r 25
or -vf "fps=fps=25"
Example to check what it does:
ffmpeg -f lavfi -i testsrc=duration=10:size=854x480:rate=60 \ -vf "drawtext=text=%{n}:fontsize=72:r=60:x=(w-tw)/2: y=h-(2*lh):fontcolor=white:box=1:boxcolor=0x00000099" test.mp4
Example with Fuji .MOV files, to add the "Create Date" time as a timecode:
find . -type f | perl -ple 's/^.*\.(\w+)/$1/' | sort -u
dest=/mnt/share/temp mkdir -p "$dest"
find . -type f -name "*.MOV" \ | while read f; do \ b=$(basename "$f"); t=$(exiftool -CreateDate "$f" | awk '{print $NF}'); tc="$t:00"; echo "====== $f $tc"; ffmpeg -loglevel warning -i "$f" -codec copy -map_metadata 0 -movflags use_metadata_tags -timecode "$tc" -f mov "$dest/$b" </dev/null || break; touch -r "$f" "$dest/$b"; echo; done
If the exiftool command gives the error "End of processing at large atom (LargeFileSupport not enabled)", add the -api largefilesupport=1
option so the exiftool line becomes:
t=$(exiftool -api largefilesupport=1 -CreateDate "$f" | awk '{print $NF}');
From https://reto.ch/training/2017/201706/FFmpeg.html
f1=... # file 1 f2=... # file 2 t="-t 60" # limit time out=delta.mp4 ffmpeg -i "$f1" -i "$f2" $t \ -filter_complex "[1]format=yuva444p,lut=c3=128,negate[1_with_alpha_channel];[0][1_with_alpha_channel]overlay" "$out"
How to add resize? How to add different start times for input files?
ffmpeg -i "$f1" -i "$f2" $t \ -filter_complex "blend=all_mode=difference" \ -c:v libx264 -crf 18 -c:a none "$out"
Or http://dericed.com/2012/display-video-difference-with-ffmpegs-overlay-filter/
ffmpeg "$f1" -i "$f2" $t \ -filter_complex '[1:v]format=yuva444p,lut=c3=128,negate[video2withAlpha],[0:v][video2withAlpha]overlay[out]' \ -map [out] "$out"
$ ffmpeg -i "$filename" -map 0:a -codec copy -f md5 "$filename.md5"
$ ffmpeg -i "$filename" -map 0:a -codec copy -hide_banner -loglevel warning -f md5 -
$ ffmpeg -i "$filename" -map 0 -c copy -f streamhash -hash md5 - ... 0,v,MD5=50224fec84bc6dfde90d742bcf1d2e01 1,a,MD5=1d2a32ed72798d66e0110bd02df2be65
$ ffmpeg -i "$f" -map 0 -c copy -f streamhash -hash md5 "$f.stream.md5"
See also:
-nostdin
Verbosity:
-hide_banner -loglevel warning -stats # or -hide_banner -loglevel info -stats
See How do I name an audio track with ffmpeg:
ffmpeg -i input.mp4 -map 0 -c copy -metadata:s:a:0 title="One" -metadata:s:a:1 title="Two" -metadata:s:a:0 language=eng -metadata:s:a:1 language=spa output.mp4
ffmpeg -loop 1 -r 1 -i "$in_img" -i "$in_a" \ -c:v libx264 -pix_fmt yuv420p -crf 22 -preset veryfast -tune stillimage \ -c:a copy -shortest "$out"
Source is 4K (3840x2160), 50fps progressive, 8 mono tracks.
Wanted output : HD 1920x1080, 25 fps, 1 stereo audio from source tracks 1 + 2.
ffmpeg -i "$in" -vf "scale=hd1080" -r 25 \ -c:v libx264 -pix_fmt yuv420p -tune film -crf 20 -g 50 \ -filter_complex "[0:a:0][0:a:1]amerge,channelmap=channel_layout=stereo[st]" \ -map 0:v -map "[st]" \ -c:a aac -b:a 192k \ "$out"
Sample output:
ffmpeg -i "$in" -t 300 -vf "scale=hd1080" -r 25 -c:v libx264 -pix_fmt yuv420p -tune film -preset fast -crf 20 -g 50 -filter_complex "[0:a:0][0:a:1]amerge,channelmap=channel_layout=stereo[st]" -map 0:v -map "[st]" -c:a aac -b:a 192k "$out" ffmpeg version 4.2.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers ... [mxf @ 0x6225a40] decoding for stream 0 failed Guessed Channel Layout for Input Stream #0.1 : mono Guessed Channel Layout for Input Stream #0.2 : mono ... Guessed Channel Layout for Input Stream #0.16 : mono Input #0, mxf, from 'fdv20190808pgm.mxf': Metadata: operational_pattern_ul: 060e2b34.04010101.0d010201.01010900 uid : bd7136e0-ba0f-11e9-8fed-ac1f6b48c8ac generation_uid : bd7136e0-ba0f-11e9-8fee-ac1f6b48c8ac company_name : oc product_name : OCtk product_version : 2.10 product_uid : 3a4fe380-0d01-11e4-869f-3cd92b5c1dfc modification_date: 2019-08-08T21:07:17.708000Z material_package_umid: 0x060A2B340101010501010D2013000000BD6EECF0BA0F11E98FB2AC1F6B48C8AC timecode : 21:07:16:08 Duration: 02:47:16.24, start: 0.000000, bitrate: 524301 kb/s Stream #0:0: Video: h264 (High 4:2:2 Intra), yuv422p10le(progressive), 3840x2160 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 50 tbn, 100 tbc Metadata: file_package_umid: 0x060A2B340101010501010D2013000000BD6AF550BA0F11E98F81AC1F6B48C8AC Stream #0:1: Audio: pcm_s24le, 48000 Hz, mono, s32 (24 bit), 1152 kb/s Metadata: file_package_umid: 0x060A2B340101010501010D2013000000BD6AF550BA0F11E98F81AC1F6B48C8AC Stream #0:2: Audio: pcm_s24le, 48000 Hz, mono, s32 (24 bit), 1152 kb/s ... Metadata: file_package_umid: 0x060A2B340101010501010D2013000000BD6AF550BA0F11E98F81AC1F6B48C8AC Stream #0:16: Audio: pcm_s24le, 48000 Hz, mono, s32 (24 bit), 1152 kb/s Metadata: file_package_umid: 0x060A2B340101010501010D2013000000BD6AF550BA0F11E98F81AC1F6B48C8AC Stream #0:17: Data: none Metadata: file_package_umid: 0x060A2B340101010501010D2013000000BD6AF550BA0F11E98F81AC1F6B48C8AC data_type : vbi_vanc_smpte_436M Stream mapping: Stream #0:1 (pcm_s24le) -> amerge:in0 (graph 0) Stream #0:2 (pcm_s24le) -> amerge:in1 (graph 0) Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264)) channelmap (graph 0) -> Stream #0:1 (aac) ...