= ffmpeg in=... ; out=... # or eg. out="${in/%.mov/-small.mov}" ffmpeg -i "$in" ==webm to mp4 Example: ffmpeg -i "$in" -tune film -crf 20 -preset slow -b:a 192k -movflags +faststart "${in%%.webm}.mp4" ==h264 -c:v libx264 -pix_fmt yuv420p -tune film -crf 20 -g 50 -preset slow # (veryfast fast medium slow slower veryslow) ===Limit bitrate Can be used with ''-crf'' -maxrate 6M -bufsize 6M Or set an average bitrate, without using ''-crf'' (see [[https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate|Limiting the output bitrate]]) -b:v 4M -maxrate 6M -bufsize 10M ==prores * Prores proxy: -profile:v 0 * Prores LT: -profile:v 1 * Prores SQ: -profile:v 2 * Prores HQ: -profile:v 3 -c:v prores_ks -profile:v 1 -vendor apl0 -c:a pcm_s16le ==resize 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. ==Deinterlace 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" ==Extract part 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. ==Extract single frames 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 [[https://trac.ffmpeg.org/wiki/Create%20a%20thumbnail%20image%20every%20X%20seconds%20of%20the%20video|Create a thumbnail image every X seconds of the video]]. ==Images to video With numbered frames, the numbering must start at 0: "frame0000.png", "frame0001.png", "frame0002.png", ... ===Animated webp 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 [[https://ozzyczech.cz/bash/convert-gif-to-web-m-with-ffmpeg/|Convert GIF to WebM with ffmpeg]]) ffmpeg -i my-animation.gif -c vp9 -b:v 0 -crf 41 my-animation.webm ===Jpegs to mp4 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'' ==Audio ===Audio AAC -c:a aac -b:a 192k ===AC3 5.1 to Stereo 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 ===Remap 2 mono audio 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]" === FLAC ==== FLAC to MP3 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. ==== WAV to FLAC Can be done with ''flac'' instead of ffmpeg: for f in *.wav; do flac "$f" --keep-foreign-metadata -V -o "${f%%wav}.flac" done === Detect silence ==== volumedetect 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" ==== astats 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 ==== EBU stats 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 ==faststart Move "moov" atom to start of file (https://ffmpeg.org/ffmpeg-formats.html#Options-8). (Implies file copy after encoding) -movflags faststart ==Change framerate ''-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 == Add pseudo-timecode Example with Fuji .MOV files, to add the "Create Date" time as a timecode: * Check file extensions find . -type f | perl -ple 's/^.*\.(\w+)/$1/' | sort -u * Prepare destination dest=/mnt/share/temp mkdir -p "$dest" * Extract time, add as TC, preserve original file date 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" 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}'); ==Diff 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? Or see https://stackoverflow.com/questions/25774996/how-to-compare-show-the-difference-between-2-videos-in-ffmpeg : ffmpeg -i "$f1" -i "$f2" $t \ -filter_complex "blend=all_mode=difference" \ -c:v libx264 -crf 18 -c:a none "$out" And [[https://trac.ffmpeg.org/wiki/FilteringGuide|FFmpeg Filtering Guide]] 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" ==Stream MD5 $ 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: * http://ffmpeg.org/ffmpeg-formats.html#hash * https://trac.ffmpeg.org/wiki/framemd5%20Intro%20and%20HowTo * https://stackoverflow.com/a/897594/111036 * https://stackoverflow.com/questions/63608312/how-to-md5-the-video-track-only-in-ffmpeg ==Other options -nostdin Verbosity: -hide_banner -loglevel warning -stats # or -hide_banner -loglevel info -stats ===Edit metadata=== See [[https://superuser.com/questions/834244/how-do-i-name-an-audio-track-with-ffmpeg/835069|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 ==Examples ===Audio + still image to video 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" ===Resize, remap audio, change fps 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) ... {{tag>public ffmpeg}}