Using -ss as input option together with -c:v copy might not be accurate since ffmpeg is forced to only use/split on i-frames. Though it will—if possible—adjust the start time of the stream to a negative value to compensate for that. Basically, if you specify "second 157" and there is no key frame until second 159, it will include two seconds of audio (with no video) at the start, then will start from the first key frame. So be careful when splitting and doing codec copy.
To avoid this, I’ve tried first finding the timestamps of the frames needed for -ss
and -to
by building a tile of all nearby frames. I’ve generated the tiles using
ffmpeg -i "INPUT.mkv" -ss 09:55 -t 3 -vf "drawtext=fontfile=I\\:\Misc\\\\~Software\\\\~OS\\\\I386\\\\arial.ttf: fontsize=60: text='F%{n}\(%{pict_type}\)\@%{pts\:hms}': x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1,scale=320:-1,tile=layout=12x10" tiles%03d.png
and according to them the needed keyframe should be starting from 00:09:56.012, and the last needed frame should be at 00:10:00.224. However, the fragment created when cutting with these timestamps
ffmpeg -i "INPUT.mkv" -map 0:0 -map 0:4 -map 0:5 -map 0:6 -ss 09:56.012 -to 00:10:00.224 -vcodec copy -acodec copy J01.mkv
starts at a non-key frame (sound only) and ends at a wrong place as well. In contrast, cutting the same fragment in Avidemux works fine even with Video- and Audio-output settings set to Copy
(IIUC, no re-encoding and start from a no-key frame). Displayed timestamps in Avidemux are also different (-ss 09:56.346 -to 10:00.558
v.s. -ss 09:56.012 -to 10:00.224
).
I’ve also tried cutting by pkt_dts_time (https://stackoverflow.com/questions/14005110/), but that didn’t work either.
p.s. Another similar procedure to what I am trying to do (to abovementioned Avidemux) is when in Sony Vegas you zoom in into the timeline until you can step from one frame to another, then set the first frame after scene change (which is also a keyframe) as the starting point and the last frame of the same scene (after which comes the next keyframe that is not needed) as the endpoint and then render. Something like this can also be done in Avidemux while also copying the video and audio streams.
edit1: Here’s the log for -copyts
version: pastebin . com /Cxzrc8Er. Should I do others as well?
edit2: Here are results for "PATHTO\ffprobe.exe" -select_streams v -show_entries packet=pts_time,flags -of compact -read_intervals 580%600 "INPUT.mkv" | findstr K
.
packet|pts_time=578.160000|flags=K
packet|pts_time=581.205000|flags=K
packet|pts_time=583.499000|flags=K
packet|pts_time=585.042000|flags=K
packet|pts_time=588.671000|flags=K
packet|pts_time=594.885000|flags=K
packet|pts_time=596.012000|flags=K
I’ve also tried the whole combo of commands (tiles, listing frames this way, cutting fragment two different ways) on another 2 videos, and the results are similar. Keyframe times listed in terminal using your suggested command match the ones in tiles made by mine; and generally cutting by my method leaves a small frozen section (~1s) in the beginning and sometimes several unwanted frames at the end and cutting by your method leaves a longer empty video-stream at the beginning.
I’ve also found a better video fragment for experimenting because it’s visually easier to determine how much of the wanted frames are missing and of the unwanted have been added (imgur.com /a /DTzmt, relevant part can be downloaded at bit.ly /Kmnz112f1). Your solution worked better on it as well.
Also, just to make sure: Did you mean -ss 09:56.013 and not -ss 09:56.012 in your original solution? And, am I right to guess that it generally works on videos you’re cutting and that it doesn’t on mine is out of usual?
Try
ffmpeg -ss 09:56.013 -i "INPUT.mkv" -map 0:0 -map 0:4 -map 0:5 -map 0:6 -to 00:10:00.224 -vcodec copy -acodec copy -avoid_negative_ts make_zero J01.mkv
One solution could be to:
copy
as layer 2This might be slower than just copying.
Another solution could be to find the first keyframe, and concat two clips:
copy
.I did not try either (yet).
User contributions licensed under CC BY-SA 3.0