3

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?


13
  • Yes, 013. My command works on your sample. There's an I frame at 15.398 and using -ss 15.399 I get an output with the first frame being the first frame of the scene change from the escalator. With -ss 15.398, it cuts from the keyframe before.
    – Gyan
    May 14 '16 at 17:33
  • Could the discrepancy be a version issue? I get IF@15.811 using tiles (imgur.com/a/eIOX2), "Unsupported codec with id 98304 for input stream *" with KF-listing method, and IF@15.815 using ffplay+drawtext’s pict_type. Using -ss 15- .399 \ .816 \ .850 produces files with large black chunks at the beginning. Also, can you please upload the working cut for me to check if it works on my machine\players?
    – Imfego
    May 14 '16 at 18:32
  • datafilehost.com/d/ee6c6ca5 - uncheck the download manager option before dl.
    – Gyan
    May 14 '16 at 18:38
  • Which ffmpeg version are you using?
    – Gyan
    May 14 '16 at 18:39
  • Thank you. It does show extra frames (imgur.com/a/eIOX2); and when I was testing the commands on that scene before edit2, there were extra frames afterwards too (I told it to end at a right angle \ quarter-circle picture ~00:19.523, it went further into ~00:19.565). And ffmpeg version is 2.8.4 from ffmpeg-20160415-git-21acc4d-win64-static (pastebin.com/BMUzeTwA).
    – Imfego
    May 14 '16 at 18:59
0

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
5
  • That created a 10m11s317ms-long video with frame 09:55.970 (see tile) frozen for ~11s at the beginning. Trying to compensate for the timestamp reset with "ffmpeg -ss 09:56.013 -i "INPUT.mkv" -map 0:0 -map 0:4 -map 0:5 -map 0:6 -t 4.211 -vcodec copy -acodec copy -avoid_negative_ts make_zero testRec1.mkv" created a 15s222ms video with the same 11s-long frozen frame before the needed part. What made "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 -copyts -vcodec copy -acodec copy -avoid_negative_ts make_zero testRec2.mkv" was the same as testRec1.mkv.
    – Imfego
    May 13 '16 at 11:21
  • Paste the full console output for the cutting command into the Q.
    – Gyan
    May 13 '16 at 12:10
  • How are you checking playback?
    – Gyan
    May 13 '16 at 12:57
  • In VLC, MPC-HC and KMPlayer, though all on the same machine (Win7).
    – Imfego
    May 13 '16 at 13:21
  • Let's check your keyframes again: ffprobe -select_streams v -show_entries packet=pts_time,flags -of compact -read_intervals 580%600 input.mkv | findstr K
    – Gyan
    May 14 '16 at 5:14
0

One solution could be to:

  1. Cut the first, say, 5 seconds of the clip (i.e. where you want to cut)
  2. Encode it using the same codec as the input has
  3. Use it as layer 1
  4. Copy the clip with codec copy as layer 2
  5. Overlay the layer 1 over layer 2.

This might be slower than just copying.

Another solution could be to find the first keyframe, and concat two clips:

  • One from the clip start to the keyframe, encoded with the same codec
  • Other from the keyframe to the clip end, using codec copy.

I did not try either (yet).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.