Cut a video based on start and end time using FFmpeg
You probably don’t have a keyframe at the specified second mark if you can’t cut a video at a particular moment.
Non-keyframes need all of the data beginning with the previous keyframe because they encode variations from other frames.
Using an edit list, it is possible to cut at a non-keyframe with the mp4 container without re-encoding.
In other words, if the closest keyframe before 3s is at 0s, the video will be copied starting at 0s, and FFmpeg
will use an edit list to tell the player to begin playing 3 seconds in.
If you’re using the latest version of FFmpeg
from git master, it’ll use an edit list when you run it with the command you give.
If this does not work for you, it is you are likely using an older version of FFmpeg or that your player does not support edit lists.
Some players can disregard the edit list and play the entire file from beginning to end, regardless of the edit list.
If you want to cut specifically at a non-keyframe and have it play at the desired point on a player that doesn’t support edit lists, or if you want to make sure the cut section isn’t in the output file (for example, if it includes sensitive information), you can do so by re-encoding so that a keyframe is present at the desired start time.
If you don’t mention copy, re-encoding is the norm.
Consider the following scenario:
ffmpeg -i input.mp4 -ss 00:00:07 -t 00:00:18 -async 1 output.mp4
- The
-t
option defines a length rather than an end time. - The command above will encode 18 seconds of video beginning at 7 seconds.
- Use
-t
8 to start at 7 seconds and end at 15 seconds. - If you’re using a recent version of FFmpeg, you can also use
-to
instead of-t
in the above command to make it end at the required time.