ffmpeg useful commands

ffprobe

# show streams infos
ffprobe -loglevel 16 \
  -show_streams \
  -show_private_data \
  -print_format flat \
  -i input.mp4
 
# display the frame timestamps with their associated coded picture number (== encoding order)
# /!\ coded_picture_number != frame number
# If there are no B-frames, the coded_picture_number is the same as the frame number
ffprobe input.mp4 \
  -select_streams v \
  -show_entries frame=coded_picture_number,pkt_pts_time \
  -of csv=p=0:nk=1 \
  -v 0 \
  -pretty \
  | less
 
# check if a video has B-frames (0: no b-frames, 2: has b-frames)
ffprobe -loglevel 16 -show_streams -show_private_data -print_format flat -i input.mp4 | grep has_b_frames
 
# check I/P/B-frame type for each frame
ffprobe -loglevel 16 -show_frames input.mp4 | grep pict_type | less

ffmpeg

# extract only video
ffmpeg -i input.mp4 -an -c:v copy output.mp4
 
# extract audio only
ffmpeg -i input.mp4 -vn -c:a copy output.mp4
 
# cut video without from 10s to 20s
# using "-vcodec copy" to take the input codec => no re-encoding
# may only work if the video do not contain any B-frame
ffmpeg -ss 10 -to 20 -i input.mp4 -vcodec copy out.mp4
 
# concatenate images from folder into a video
for f in *.jpg; do echo "file '$f'" >> to_video.txt; done
# -r 0.5: show every image for 2 seconds
ffmpeg -r 0.5 -f concat -i to_video.txt -vcodec libx264 video.mp4
rm to_video.txt
 
# generate video with timestamp & pts drawn behind black screen
ffmpeg \
  # libavfilter input virtual device, needed to generate the black background
  -f lavfi \
  # read source at its native frame rate
  -re \
  # create a black background
  -i color=size=1280x720:duration=20:rate=25:color=black \
  # settb=AVTB: force timestamp to default AVTB which is 10e-6 to have timestamp in us
  # setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)': truncate
  # credit: https://stackoverflow.com/a/47551016/3612053
  -vf "settb=AVTB,setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)',drawtext=text='%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}':x=(w-text_w)/2:y=(h-text_h)/2:fontsize=80:fontcolor=white,drawtext=text='%{pts}':x=(w-text_w)/2:y=500:fontsize=50:fontcolor=white@0.8" \
  output.mp4
 
# live stream video with timestamp indefinitely (need a RTMP server)
ffmpeg \
  -stream_loop 1 \
  # libavfilter input virtual device, needed to generate the black background
  -f lavfi \
  # read source at its native frame rate
  -re \
  # create a black background
  -i color=size=1280x720:rate=25:color=black \
  # settb=AVTB: force timestamp to default AVTB which is 10e-6 to have timestamp in us
  # setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)': truncate
  # credit: https://stackoverflow.com/a/47551016/3612053
  -vf "settb=AVTB,setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)',drawtext=text='%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}':x=(w-text_w)/2:y=(h-text_h)/2:fontsize=80:fontcolor=white" \
  # use the libx264 for producing an optimized h264 file, with the "High Profile" setting, which is
  # the primary profile for broadcast and disc storage applications, particulary for high-definition
  # tv applications, and by using the veryfast preset
  -c:v libx264 -profile:v high -level:v 4.1 -preset veryfast \
  # produce a file that stays in the 3000-6000 video bitrate range (required by YouTube for example)
  -b:v 3000k -maxrate 3000k -bufsize 6000k \
  # use a specific chroma subsampling scheme named 4:2:0 planar, used for compatibility reasons,
  # since output must be playable across differet players and platforms
  -pix_fmt yuv420p \
  # abide to required 2s keyframe interval, this will set a value of 50 Group Of Pictures
  # value must be = frame rate * 2
  -g 50 \
  # minimum distance between I-frames and must be the same as -g value
  -keyint_min 50 \
  # Scene Change Threshold
  # option to make sure to not add any new keyframe when content of picture changes
  -sc_threshold 0 \
  # live stream to rtmp server
  -f flv rtmp://localhost:1935
 
# change resolution to 720p
ffmpeg -i sample.cut.mp4 \
  -vf scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1,setsar=1 \
  sample.720p.mp4
 
# download authenticated HLS stream
ffmpeg -headers "Authorization: Bearer abcd" \
  -i https://some.live.stream/playlist.m3u8 \
  -protocol_whitelist file \
  -c copy output.mp4
# to concat multiple videos, we need to create a text file containing all the videos to concatenate in order
cat << EOF > files.txt
file 'gap.mp4'
file 'original_left.mp4'
file 'original_right.mp4'
EOF
ffmpeg -f concat -i files.txt -c copy concatenated_video.mp4

# To extract the sound from a video and save it as MP3:
ffmpeg -i <video.mp4> -vn <sound>.mp3
 
# To convert frames from a video or GIF into individual numbered images:
ffmpeg -i <video.mpg|video.gif> <frame_%d.png>
 
# To combine numbered images (frame_1.jpg, frame_2.jpg, etc) into a video or GIF:
ffmpeg -i <frame_%d.jpg> -f image2 <video.mpg|video.gif>
 
# To quickly extract a single frame from a video at time mm:ss and save it as a 128x128 resolution image:
ffmpeg -ss <mm:ss> -i <video.mp4> -frames 1 -s <128x128> -f image2 <image.png>
 
# To trim a video from a given start time mm:ss to an end time mm2:ss2 (omit the -to flag to trim till the end):
ffmpeg -ss <mm:ss> -to <mm2:ss2> -i <video.mp4> -codec copy <output.mp4>
 
# To convert AVI video to MP4. AAC Audio @ 128kbit, h264 Video @ CRF 23:
ffmpeg -i <input_video>.avi -codec:audio aac -b:audio 128k -codec:video libx264 -crf 23 <output_video>.mp4
 
# To remux MKV video to MP4 without re-encoding audio or video streams:
ffmpeg -i <input_video>.mkv -codec copy <output_video>.mp4
 
# To convert MP4 video to VP9 codec. For the best quality, use a CRF value (recommended range 15-35) and -b:video MUST be 0:
ffmpeg -i <input_video>.mp4 -codec:video libvpx-vp9 -crf <30> -b:video 0 -codec:audio libopus -vbr on -threads <number_of_threads> <output_video>.webm
 
# -----------------------------------------------------------------------------
 
##
# To join/concatenate two mp4 videos (use double-quotes in Windows):
# 
# http://www.kolor.com/wiki-en/action/view/Autopano_Video_-_Concatenate_several_mp4
##
ffmpeg -i one.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts one.ts
ffmpeg -i two.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts two.ts
ffmpeg -i "concat:one.ts|two.ts" -c copy -bsf:a aac_adtstoasc combined.mp4
# cleanup
rm -f one.ts two.ts
 
 
# To print file metadata:
ffmpeg -i path/to/file.ext
 
# To convert a video to compatible HTML5 video format (mp4): (https://gist.github.com/yellowled/1439610)
ffmpeg -i infile.ext -acodec aac -strict experimental -ac 2 -ab 128k -vcodec libx264 -preset slow -f mp4 -crf 22 outfile.mp4
 
# To convert all m4a files to mp3:
for f in *.m4a; do ffmpeg -i "$f" -acodec libmp3lame -ab 320k "${f%.m4a}.mp3"; done
 
# To generate a 10-second audio clip:
#
#         -ss : start time
#         -t  : seconds to cut
#   -autoexit : closes ffplay as soon as the audio finishes
ffmpeg -ss 00:34:24.85 -t 10 -i path/to/file.mp4 -f mp3 pipe:play | ffplay -i pipe:play -autoexit
 
# To generate a 5-second video clip (from the beginning "-ss 0" of video):
#
#   -ss : start time of clip (position)
#   -t  : duration of clip
ffmpeg -i video.mp4 -ss 0 -t 5 -vcodec copy -acodec copy clip.mp4
 
# Get media file info
ffmpeg -i video.avi
 
# Turn X images to a video sequence
ffmpeg -f image2 -i image%d.jpg video.mpg
 
# Turn a video to X images
ffmpeg -i video.mpg image%d.jpg
 
# Encode a video sequence for the iPpod/iPhone
ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
 
# Extract 2 images for each second of the video starting at 30-seconds and ending 40-seconds
ffmpeg -i video.mp4 -r 2 -ss 00:00:30 -t 00:00:10 img%d.jpg
 
# Extracting sound from a video, and save it as Mp3
ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 sound.mp3
 
# Convert a wav file to Mp3
ffmpeg -i son_origine.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 son_final.mp3
 
# Crop an audio file
#
# "`-acodec copy` is to keep the original sound, `-ss 00:00:25` is to tell where
# to start cropping and `-t 00:02:00` is the length of the cropped output file.
ffmpeg -i input.mp3 -acodec copy -ss 00:00:25 -t 00:02:00 output.wav
 
# Crop a video file
#
# The only change in this command is that you need to define the video encoder
# when cropping video files, the usual option is "-vcodec copy" to keep
# the original video.
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:25 -t 00:02:00 output.flv
 
# Convert .avi video to .mpg
ffmpeg -i video_origine.avi video_finale.mpg
 
# Convert .mpg to .avi
ffmpeg -i video_origine.mpg video_finale.avi
 
# To convert the entire video to GIF, use the following command:
ffmpeg -i small.mp4 small.gif
 
# To convert a gif to video:
ffmpeg -f gif -i animation.gif animation.mp4
 
# To convert just a portion of a video clip to GIF, use the following command:
ffmpeg -t 3 -ss 00:00:02 -i small.webm small-clip.gif
 
# Mix a video with a sound file
ffmpeg -i son.wav -i video_origine.avi video_finale.mpg
 
# Convert .avi to .flv
ffmpeg -i video_origine.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv video_finale.flv
 
# Convert .avi to dv
ffmpeg -i video_origine.avi -s pal -r pal -aspect 4:3 -ar 48000 -ac 2 video_finale.dv
# Or:
ffmpeg -i video_origine.avi -target pal-dv video_finale.dv
 
# Convert .avi to mpeg for dvd players
ffmpeg -i source_video.avi -target pal-dvd -ps 2000000000 -aspect 16:9 finale_video.mpeg
 
# Compress .avi to divx
ffmpeg -i video_origine.avi -s 320x240 -vcodec msmpeg4v2 video_finale.avi
 
# Compress Ogg Theora to Mpeg dvd
ffmpeg -i film_sortie_cinelerra.ogm -s 720x576 -vcodec mpeg2video -acodec mp3 film_termin.mpg
 
# Compress .avi to SVCD mpeg2 (NTSC format)
ffmpeg -i video_origine.avi -target ntsc-svcd video_finale.mpg
 
# Compress .avi to SVCD mpeg2 (PAL format)
ffmpeg -i video_origine.avi -target pal-svcd video_finale.mpg
 
# Compress .avi to VCD mpeg2 (NTSC format)
ffmpeg -i video_origine.avi -target ntsc-vcd video_finale.mpg
 
# Compress .avi to VCD mpeg2 (PAL format)
ffmpeg -i video_origine.avi -target pal-vcd video_finale.mpg
 
# Multi-pass encoding with ffmpeg
ffmpeg -i fichierentree -pass 2 -passlogfile ffmpeg2pass fichiersortie-2
 
# Convert to wmv
ffmpeg -i winter_clip.mov -vcodec wmv2 -b 12000k -ar 44100 -ab 192k -ac 2 -y -s 720x406 output.wmv
 
# Write metadata `title` to mp4 clip (without re-encoding)
ffmpeg -loglevel quiet -v 0 -i clip.mp4 -metadata title="jon test clip" -acodec copy -vcodec copy -copyts cliptitle.mp4
 
# Gather stream information and print it in JSON format
ffprobe -loglevel quiet -show_format -show_streams -i clip.mp4 -print_format json
 
# Transcode to WebM with ffmpeg (http://paulrouget.com/e/funwithwebm/)
ffmpeg -i girltalk.mp4 -f webm -vcodec libvpx -acodec libvorbis -aq 90 -ac 2 girltalk.webm
 
# Convert to ipad
ffmpeg -y -i input.avi -acodec aac -ar 48000 -ab 128k -ac 2 -s 1024x768 -vcodec libx264 -b 1200k -flags +loop+mv4 -cmp 256 -partitions +parti4x4+partp8x8+partb8x8 -subq 7 -trellis 1 -refs 5 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 1200k -maxrate 1200k -bufsize 1200k -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 16:9 -r 30 -g 90 -async 2 output.mp4
 
# Create a single image video with audio
ffmpeg -loop 1 -i image.png -i sound.mp3 -shortest video.mp4
 
# Find all .flv files in a dir, grab the first frame and make a jpg.
for f in *.flv; do
    ffmpeg -y -i "$f" -f image2 -ss 10 -vframes 1 -an "${f%.flv}.jpg";
done
 
# Convert .wma files to .ogg with ffmpeg
find -name '*wma' -exec ffmpeg -i {} -acodec vorbis -ab 128k {}.ogg \;
 
# Synchronize audio with video by adding a 0.5 second (1/2 second) delay to the audio stream without re-encoding the file (https://alien.slackbook.org/blog/fixing-audio-sync-with-ffmpeg/):
ffmpeg -i out_of_sync_file.mp4 -itsoffset 0.5 -i out_of_sync_file.mp4 -map 0:0 -map 1:1 -acodec copy -vcodec copy synced_file.mp4
 
# Removing syncronization problems between audio and video
#
# This assumes that there is a 10.2 sec delay between the video and the
# audio (delayed). To extract the original video into a audio and video
# composites look at the command on extracting audio and video from a movie.
ffmpeg -i source_audio.mp3 -itsoffset 00:00:10.2 -i source_video.m2v target_video.flv
 
# Cut Out A Piece Of Film From A File. Choose an arbitrary length and starting time.
ffmpeg -vcodec copy -acodec copy -i orginalfile -ss 00:01:30 -t 0:0:20 newfile
 
# Extract Audio And Video From A Movie
# Rips the audio and video stream of a movie. The two streams are stored separately.
ffmpeg -i source_movie.flv -vcodec mpeg2video target_video.m2v -acodec copy target_audio.mp3
 
# Rotate a video file 90 clockwise (http://stackoverflow.com/a/9570992):
ffmpeg -i in.mov -vf "transpose=1" out.mov
 
##
# ffmpeg, libx264 and presets (for web encoding)
#
# Here the source can be either mp4 or some other file format as FLV for instance
#   -- http://www.stoimen.com/blog/2010/10/26/ffmpeg-libx264-and-presets/
##
ffmpeg -i source.mp4 -acodec libfaac -ab 128k -ac 2 -vcodec libx264 -vpre normal -threads 0 -crf 22 output.mp4
 
###
# Convert Adobe Flash FLV Files to MP4 Files
# http://www.guguncube.com/1103/ffmpeg-convert-adobe-flash-flv-files-to-mp4-files
###
 
# Simple Conversion of FLV to MP4 using FFMPEG
find . -regextype posix-extended -iregex ".*.avi|.*.flv" -type f | while IFS= read -r file;
do
    fn="${file}";
    echo "###$fn###";
    dest="${fn%.*}.mp4";
    echo "###$dest###";
    if [ -f "$dest" ];then
        rm "$dest";
    fi;
    ffmpeg -nostdin -v 0 -i "$fn" -acodec copy -vcodec copy -copyts "$dest";
done;
 
# Convert FLV to MP4 through container copy
#   NOTE: only works if video content is H264 and audio AAC or MP3
ffmpeg -i input.flv -acodec copy -vcodec copy -copyts output.mp4
 
# Transcode FLV to MP4
ffmpeg -i input.flv -copyts output.mp4
 
# Re-encode Audio
ffmpeg -i input.ext -vcodec copy -acodec libfaac -ab 128k -copyts output.mp4
 
# Copy Directory FLV TO MP4 (Version 1)
for f in *.flv; do
  fn="${f%.*}";
  ffmpeg -i "$f" -acodec copy -vcodec copy -copyts "$fn.mp4";
done;
 
# Copy Directory FLV TO MP4 (Version 2)
for f in *.flv; do a=$(echo $f|sed -e 's/.flv/.mp4/ig');
    echo $a;
    ffmpeg -i "$f" -acodec copy -vcodec copy -copyts "$a";
done;
 
# It you want particular prefixes for the Android, something like:
ffmpeg -i source-video.avi -s 480x320 -vcodec mpeg4 -acodec libfaac -ac 1 -ar 16000 -r 13 -ab 32000 -aspect 3:2 output-video.G1.mp4
# My ffmpeg didn't want -aspect 3:2 and you can omit it.
 
# Convert FLV files in tree to mp4 -- preserve already existing files and MP4
find . -name "*.flv" -type f -exec ffmpeg -n -i '{}' -acodec copy -vcodec copy -copyts '{}.mp4' ;
 
# convert directory tree from AVI, FLV to mp4
find . -regextype posix-extended -iregex ".*.avi|.*.flv" -type f -exec ffmpeg -n -i '{}' '{}.mp4' ;
# -regextype posix-extended -iregex ".*.txt|.*.mp4"
for f in *; do fn="${f%.*}";echo "fn=$fn,f=$f"; done;
for f in *.flv.mp4; do fn="${f%.*}";echo "$fn,f=$f"; done;
 
# Remove FLV.MP4 double extensions
for f in *.flv.mp4; do fn="${f%.*}";fn="${fn%.*}";mv "$f" "$fn.mp4"; done;
 
# Converts flac files to mp3 (shell)
for FILE in *.flac;
do
    ffmpeg -i "$FILE" -ab 320k "${FILE%.*}.mp3";
done
 
##
# How to encode video in H264 format
#
# We have successfully been using ffmpeg/libx264 with two pass encoding using
# the following commands
#
# http://h264.code-shop.com/trac/wiki/Encoding#HowtoencodevideoinH264format
##
 
## Ffmpeg/x264 (profile High, level 3.0) (latest versions of x264)
infile="video.avi"
  tmpfile="video_tmp.mp4"
  outfile="video.mp4"
  options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256
     -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8
     -me_method hex -subq 7 -trellis 1 -refs 5 -bf 3
     -flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16
           -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10
     -qmax 51 -qdiff 4"
 
  ffmpeg -y -i "$infile" -an -pass 1 -threads 0 $options "$tmpfile"
  ffmpeg -y -i "$infile" -acodec libfaac -ar 44100 -ab 96k -pass 2 -threads 0 $options "$tmpfile"
  qtfaststart "$tmpfile" "$outfile"
 
## Ffmpeg/x264 (profile High, level 3.0) (older versions)
  options="-vcodec libx264 -b 512k -bf 3 -subq 6 -cmp 256 -refs 5 -qmin 10
           -qmax 51 -qdiff 4 -coder 1 -loop 1 -me hex -me_range 16 -trellis 1
           -flags +mv4 -flags2 +bpyramid+wpred+mixed_refs+brdo+8x8dct
           -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -g 250
           -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71"
 
## Ffmpeg/x264 (profile Baseline, level 3.0) (iPhone)
  options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256
     -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8
     -me_method hex -subq 7 -trellis 1 -refs 5 -bf 0
     -flags2 +mixed_refs -coder 0 -me_range 16
           -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10
     -qmax 51 -qdiff 4"
 
##
# Windows BAT script
#
# Encode XVID H.263 to H.264 video, copy source audio stream.
##
 
echo OFF
cls
 
for ~nf"
 
    ffmpeg -i "~nf.mp4"
)
 
pause "Done."
 
##
# Encoding for web
#
# In the following replace x in -pass x with 1 and 2 for the first and second
# pass/run respectively. We assume the original movie in.suffix has an aspect
# ratio of 16/9 and a frame rate of 25 frames per second.
#
# http://flowplayer.org/docs/encoding.html
##
 
# WEBM encoding sample
ffmpeg -y -i in.suffix -filter:v scale=640:360
       -vpre libvpx-720p -b:v 500k -r:v 25/1 -force_fps
       -c:a libvorbis -b:a 80k -pass 1 out.webm
 
# MP4 encoding sample
ffmpeg -y -i in.suffix -filter:v scale=640:360 -pix_fmt yuv420p
       -c:v libx264 -preset:v slow -profile:v baseline
       -x264opts level=3.0:vbv-maxrate=10000:vbv-bufsize=10000:ref=1
       -b:v 700k -r:v 25/1 -force_fps -movflags +faststart
       -c:a libfaac -b:a 80k -pass 1 out.mp4
 
##
# How to Make MP4 Progressive with qtfaststart (python wrapper for `qt-faststart`)
#
#  Quicktime atom positioning in Python for fast streaming
#  https://github.com/danielgtaylor/qtfaststart
##

Video Editing

Cropping

The following will create a 640x480 sized output video by copying a corresponding window at offset x=100px y=25px from the input video

ffmpeg -i <input> -filter:v "crop=640:480:100:25" <output>

Scaling

ffmpeg -i <input> -vf scale=640:480 <output>

Cutting a video part

ffmpeg -i <input> -ss 00:01:45 -t 00:02:35 -vcodec copy -acodec copy <output>ffmpeg -ss 00:00:30 -i orginalfile.mpg -t 00:00:05 -vcodec copy -acodec copy newfile.mpg

Fixing rotation

Do not recode for rotation but simple add a video metadate field for the rotation angle

ffmpeg -i <input> -c copy -metadata:s:v:0 rotate=90 <output>

H265 2-pass encoding

For H265 2-pass encoding you need to combine 2 ffmpeg calls. Example from ffmpeg:

ffmpeg -y -i input -c:v libx265 -b:v 2600k -x265-params pass=1 -an -f mp4 /dev/null && \
ffmpeg    -i input -c:v libx265 -b:v 2600k -x265-params pass=2 -c:a aac -b:a 128k output.mp4

Repacking

Extracting Audio Stream

Combine “-vn” (for no video) with “-acodec copy”. Note that the output file extension must match the audio codec in the input file for “-acodec copy” to work.

ffmpeg -i file.mp4 -vn -acodec copy output.aac 

Creating Thumbnails

To create a single thumb at 10s

ffmpeg -ss 10 -i <input file> -vframes 1 -vcodec png -an thumb.png

To create thumbnails every n seconds use “-vf fps=1/n” for example

ffmpeg -i <input file> -vf fps=1/60 thumbnails/thumb%03d.png

Handling id3 tags

Extracting

ffmpeg -i file.mp3 -f ffmetadata metadata.txt

Setting

ffmpeg -i file.mp3 -acodec copy -metadata title="<title>" -metadata artist="<artist>" -metadata album="<album>" out.mp3

More https://gist.github.com/eyecatchup/0757b3d8b989fe433979db2ea7d95a01

Resample/Convert Audio

ffmpeg -i file.aac -acodec mp3 -ar 44100 -ab 128000 output.mp3

Switching Containers

Change container from MKV to MP4

ffmpeg -i file.mkv -acodec copy -vcodec copy file.mp4

Video from Images

If you have multiple numbered images image1.jpg, image2.jpg… create a video from them like this

ffmpeg -f image2 -i image%d.jpg video.mp4

Split Video to Images

ffmpeg -i video.mp4 image%d.jpg

Codec Issues

AAC: “channel element not allocated”

Update: The workaround for the problem doesn’t work for ffmpeg versions more recent than 20.06.2011 as libfaad support was dropped in favour of the now stable native ffmpeg AAC encoder! If you still have a separate compilation of libfaad you can workaround using the “faad” encoder tool as described in the next section. If you are using recent ffmpeg versions to decode a .MOV file you might get the following error:

Stream #0.0(eng): Audio: aac, 48000 Hz, 2 channels, s16
Stream #0.1(eng): Video: h264, yuv420p, 1280x530, PAR 1:1 DAR 128:53, 25 tbr, 25 tbn, 50 tbc
Output #0, flv, to 'test.flv':
Stream #0.0(eng): Video: flv (hq), yuv420p, 400x164 [PAR 101:102 DAR 050:2091], 
q=2-31, 300 kb/s, 1k tbn, 25 tbc
Stream #0.1(eng): Audio: libmp3lame, 22050 Hz, 2 channels, s16, 64 kb/s
Stream mapping:
Stream #0.1 -> #0.0
Stream #0.0 -> #0.1
Press [q] to stop encoding
[aac @ 0x80727a0]channel element 1.0 is not allocated
Error while decoding stream #0.0
Error while decoding stream #0.0
Error while decoding stream #0.0
Error while decoding stream #0.0
Error while decoding stream #0.0
Error while decoding stream #0.0
[...]

The message “Error while decoding stream #0.0” is repeated continuously. The resulting video is either unplayable or has no sound. Still the input video is playable in all standard players (VLC, in Windows…). The reason for the problem as I understood it is that the ffmpeg-builtin AAC codec cannot handle an audio stream stream with index “1.0”. This is documented in various bugs (see ffmpeg issues #800, #871, #999, #1733…). It doesn’t look like this will be handled by ffmpeg very soon. In fact it could well be that they’ll handle it as an invalid input file. Solution: Upgrade to latest ffmpeg and faad library version and add “ -acodec libfaad “ in front of the “-i” switch. This uses the libfaad AAC decoder, which is said to be a bit slower than the ffmpeg-builtin, but which decodes the AAC without complaining. For example:

ffmpeg -acodec libfaad -i input.mov -b 300kbit/s -ar 22050 -o test.flv

The “-acodec” preceding the “-i” option only influences the input audio decoding, not the audio encoding.

AAC: “Can not resample 6 channels”

When you try to encode with ffmpeg and you end up with such an error

Resampling with input channels greater than 2 unsupported.
Can not resample 6 channels @ 48000 Hz to 6 channels @ 48000

you are probably trying to encode from AAC with 5.1 audio to less than 6 channels or different audio sampling rate. There are three solutions:

  1. As a solution either do not reduce the audio channels and change the audio sampling rate or do convert the audio with faad first.
  2. Apply one of the available ffmpeg patches to fix the AAC 6 channel issue…
  3. Split video and audio and convert audio separately.

The third solution can be done as following:

  1. Extract audio with ffmpeg:
ffmpeg -y -i source.avi -acodec copy source.6.aac
  1. Convert audio with faad:
faad -d -o source.2.pcm source.6.aac
  1. Merge video and audio again with ffmpeg:
ffmpeg -y -i source.avi -i source.2.pcm -map 0:0 -map 1:0 -vcodec copy -acodec copy output.avi

Update: As hinted by a fellow commenter the big disadvantage is the quality loss as faad can only convert into PCM 16bit.

Fixing Async Video

Correcting Audio that is too slow/fast

This can be done using the “-async” switch of ffmpeg which according to the documentation “Stretches/squeezes” the audio stream to match the timestamps. The parameter takes a numeric value for the samples per seconds to enforce. Example:

ffmpeg -async 25 -i input.mpg <encoding options> -r 25

Try slowly increasing the -async value until audio and video matches.

Correcting Time-Shift (Variant 1)

Case 1: Audio ahead of video: As a special case the “-async” switch auto-corrects the start of the audio stream when passed as “-async 1”. So try running

ffmpeg -async 1 -i input.mpg <encoding options>

Case 2: Audio behind video: Instead of using “-async” you need to use “-vsync” to drop/duplicate frames in the video stream. There are two methods in the manual page “-vsync 1” and “-vsync 2” and an method auto-detection with “-vsync -1”. But using “-map” it is possible to specify the stream to sync against. Interestingly Google shows people using -aync and -vsync together. So it might be worth experimenting a bit to achieve the intended result :-)

Correcting Time-Shift (Variant 2)

If you have a constantly shifted sound/video track that the previous fix doesn’t work with, but you know the time shift that needs to be corrected, then you can easily fix it with one of the following two commands: Case 1: Audio ahead of video:

ffmpeg -i input.flv -itsoffset 00:00:03.0 -i input.flv -vcodec copy -acodec copy -map 0:1 -map 1:0 output_shift3s.flv

Case 2: Audio behind video:

ffmpeg -i input.flv -itsoffset 00:00:03.0 -i input.flv -vcodec copy -acodec copy -map 1:0 -map 0:1 output_shift3s.flv

The difference is in the mapping parameters which specify which of the two supplied input files to map on which output channel. The “-itsoffset” option indicates an offset (3 seconds in the example) for the following input file. The input file is required to have exactly one video channel at position 0 and one audio channel at position 1. I added “-vcodec copy -acodec copy” to avoid reencoding the video and loose quality. These parameters need to be added after the second input file and before the mapping options. Otherwise one runs into mapping errors. Update: Also check the comment of an anonymous user below mentioning that he needed a different mapping with a more recent version of ffmpeg. The commands above were tested using ffmpeg 0.5/0.6

Frame Exact Splitting

When preparing videos for Apples HTTP streaming for iPad/iPhone you need to split your video into 10s chunks and provide a play list for Quicktime to process. The problem lies with frame exact splitting of arbitrary video input material. Wether you split the file using ffmpeg or the Apple segmenter tool you often end up with

  • asynchronous audio in some or all segments
  • missing video frames at the start of each segment
  • audio glitches between two segements
  • missing audio+video between otherwise audio-synchronous consecutive segments

When using the Apple segmenter the only safe way to split files is to convert into an intermediate format which allows frame-exact splitting. As the segmenter only supports transport stream only MPEG-2 TS and MPEG-4 TS do make sense. To allow frame-exact splitting on problematic input files the easiest way is to blow them up to consist only of I-frames. The parameter for this depends on the output video codec. An ffmpeg command line for MPEG-2 TS can look like this:

ffmpeg -i inputfile -vcodec mpeg2video -pix_fmt yuv422p -qscale 1 -qmin 1 -intra outputfile

The relevant piece is the “-intra” switch. For MPEG-4 TS something like the following should work:

ffmpeg -i inputfile -vcodec libx264 -vpre slow -vpre baseline -acodec libfaac -ab 128k -ar 44100 -intra -b 2000k -minrate 2000k -maxrate 2000k outputfile

Note: It is important to watch the resulting muxing overhead which might lower the effective bitrate a lot! The resulting output files should be safe to be passed to the Apple segmenter.

Metadata Tagging Tools

This is a comparison of the performance of different tools for MP4 tagging. Here you can select between a lot of tools from the net, but only a few of them are command line based and available for Unix. The MP4 test file used is 100MB large.

Name

Duration

Command

AtomicParsely

0.6s

AtomicParsley test.mp4 –artist “Test” –genre “Test” –year “1995”

mp4box

0.6s

MP4Box -itags Name=Test:Artist=Me:disk=95/100 test.mp4

ffmpeg 0.6

0.8s

ffmpeg -i test.mp4 -metadata title=”Test” -metadata artist=”Test” -metadata date=”1995” -acodec copy -vcodec copy test2.mp4

Solving Runtime Errors

av_interleaved_write_frame() I/O error

If you are unlucky you might see the following ffmpeg error message:

Output #0, image2, to 'output.ppm':
Stream #0.0: Video: ppm, rgb24, 144x108, q=2-31, 200 kb/s, 90k tbn, 29.97 tbc
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop encoding
av_interleaved_write_frame(): I/O error occurred

Usually that means that input file is truncated and/or corrupted. The above error message was produced with a command like this

ffmpeg -v 0 -y -i 'input.flv' -ss 00:00:01 -vframes 1 -an -sameq -vcodec ppm -s 140x100 'output.ppm'

There are several possible reasons for the error message “av_interleaved_write_frame(): I/O error occurred”.

  1. You are extracting a thumb and forgot to specify to extract a single frame only (-vframes 1)
  2. You have a broken input file.
  3. And finally: The target file cannot be written.

The above was caused by problem three. After a lot of trying I found that the target directory did not exist. Quite confusing.

Compilation Issues

x264: sched_getaffinity()

If compilation fails with an error about the numbers of parameters in common/cpu.c you need to check which glibc version is used. Remove the second parameter to sched_getaffinity() if necessary and recompile.

x264: Linking

ffmpeg configure fails with:

ERROR: libx264 not found
If you think configure made a mistake, make sure you are using the latest
version from SVN.  If the latest version fails, report the problem to the
ffmpeg-user@mplayerhq.hu mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.err" produced by configure as this will help
solving the problem.

This can be caused by two effects:

  • Unintended library is used for linking. Check wether you have different ones installed. Avoid this and uninstall them if possible. If necessary use LD_LIBRARY_PATH or –extra-ldflags to change the search order.
  • Incompatible combination of ffmpeg and libx264. Older libx264 provide a method x264_encoder_open which older ffmpeg versions do check for. More recent libx264 add a version number to the method name. Now when you compile a new libx264 against an older ffmpeg the libx264 detection that relies on the symbol name fails. As a workaround you could hack the configure script to check for “x264_encoder_open_78” instead of “x264_encoder_open” (given that 78 is the libx264 version you use).

x264: AMD64

ffmpeg compilation fails on AMD64 with:

libavcodec/svq3.c: In function 'svq3_decode_slice_header':
libavcodec/svq3.c:721: warning: cast discards qualifiers from pointer target type
libavcodec/svq3.c:724: warning: cast discards qualifiers from pointer target type
libavcodec/svq3.c: In function 'svq3_decode_init':
libavcodec/svq3.c:870: warning: dereferencing type-punned pointer will break strict-aliasing rules
/tmp/ccSySbTo.s: Assembler messages:
/tmp/ccSySbTo.s:10644: Error: suffix or operands invalid for `add'
/tmp/ccSySbTo.s:10656: Error: suffix or operands invalid for `add'
/tmp/ccSySbTo.s:12294: Error: suffix or operands invalid for `add'
/tmp/ccSySbTo.s:12306: Error: suffix or operands invalid for `add'
make: *** [libavcodec/h264.o] Error 1

This post explains that this is related to a glibc issue and how to patch it.

x264: x264_init

ffmpeg compilation fails with:

libavcodec/libx264.c: In function 'encode_nals':
libavcodec/libx264.c:60: warning: implicit declaration of function 'x264_nal_encode'
libavcodec/libx264.c: In function 'X264_init':
libavcodec/libx264.c:169: error: 'x264_param_t' has no member named 'b_bframe_pyramid'
make: *** [libavcodec/libx264.o] Error 1

This means you are using incompatible ffmpeg and libx264 versions. Try to upgrade ffmpeg or to downgrade libx264.

video4linux

/usr/include/linux/videodev.h:55: error: syntax error before "ulong"
/usr/include/linux/videodev.h:71: error: syntax error before '}' token

Workaround:

--- configure.ac.080605 2005-06-08 21:56:04.000000000 +1200
+++ configure.ac        2005-06-08 21:56:42.000000000 +1200
@@ -1226,6 +1226,7 @@
 AC_CHECK_HEADERS(linux/videodev.h,,,
 [#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#include <sys/types.h>
 #endif
 #ifdef HAVE_ASM_TYPES_H
 #include <asm/types.h>

http://www.winehq.org/pipermail/wine-devel/2005-June/037400.html oder Workaround: –disable-demuxer=v4l –disable-muxer=v4l –disable-demuxer=v4l2 –disable-muxer=v4l2

Old make

make: *** No rule to make target `libavdevice/libavdevice.so', needed by `all'.  Stop.

Problem: GNU make is too old, you need at least v3.81 http://www.mail-archive.com/ffmpeg-issues@live.polito.it/msg01284.html

make: *** No rule to make target `install-libs', needed by `install'.  Stop.

Problem: GNU make is too old, you need at least v3.81 http://ffmpeg.arrozcru.org/forum/viewtopic.php?f=1&t=833