FFmpeg - useful commands

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 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

# 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

# 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

# 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

# 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

# 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