back

Trim, keyframes and compression

Keyframe seeking

When using offset time like this you might get black frames at the beginning of the video:
ffmpeg -i in.mp4 -ss 00:01:00 -t 20 -c:v copy -c:a copy -shortest out.mov
 -ss : offset time from beginning. Value can be in seconds or HH:MM:SS format.
 -to : stop writing the output at specified position. Value in seconds or HH:MM:SS format.
 -t : duration. Value can be in seconds or HH:MM:SS format.
Black frames are caused by lack of keyframes. So move the -ss command before -i in the script.

It is essential for all files to have the same length, I used this for the actual video/audio:
ffmpeg -ss 00:00:00 -i 2tmix097.mp4 -t 20 -c copy -shortest tmix.mov
ffmpeg wiki: cutting small sections

When -ss comes first, it will adjust to the nearest keyframe of the video. It will also reset the start time from that keyframe, so both  -t and  -to will give duration of the trim.
https://www.arj.no/2018/05/18/trimvideo/

Video compression picture types

wikipedia: Video compression picture types

The three major picture types used in compression are I, P and B. They are different in the following characteristics:

I‑frames are the least compressible but don't require other video frames to decode.
P‑frames can use data from previous frames to decompress and are more compressible than I‑frames.
B‑frames can use both previous and forward frames for data reference to get the highest amount of data compression.

The information below is from the video "tmix.mov":

frame index size (bytes) type
0 0 5090 I
1 1 240 B
2 2 1348 P
3 3 138 B
4 4 1867 P
... ... ... ...

The video has a frame rate of 25 fps with an I-frame every 250 frame = every 10 seconds.


Making an I-frame only video: set the -bf parameter to 0 (-bf stands for B-frame) and the -g (keyint) parameter to 1.
ffmpeg -i tmix.mov -c:v libx264 -profile:v main -g 1 -crf 9 -bf 0 -pix_fmt yuv420p -shortest output.mp4
Produces a 10.1 MB file from the 20s 637 KB mov file.

I'm just thinking of the video and audio stream length in seconds, here is a way to show it:
ffprobe -v quiet -print_format json -show_format -show_streams -i 2tmix097_7.mp4 > streams.json

I used the Musical Gestures Toolbox for Python for the table and plot.

back