What I am attempting it to do is cut and join videos such as a video with parts a------- b---------- c--------. Most of the time I wish to remove part b. Using ffprobe, I have a list of all the frame types, scene change, and I frames (pts/dts times and frame numbers) All the parts start with a scene change with an I frame.
I have been trying every combination I can google and search this forum of -ss, -t, -to, input times specification, output time specification and combination of -ss input -t -to output. I would like to use -c copy since I know where the I frames are but the closest I can come is specifying some time setting that makes no sense and then I obtain a video that does NOT start at the right time, or has audio alone at the beginning, or has no video, and more failures but never what I want.
More information that might help if anyone knows of a ways to achieve what I want: I have 4 parts listed below with the timing shown in the file name of the last 3.
0 - 3.546
3.587 - 6.549
6.590 - 9.719
9.760 - 14.981
Each frame is listed in ffprobe as .0417 ms. in duration I would be very happy if anyone can tell me how to use ffmpeg to extract a working video with only the part from key frame to key frame for say part 3 (6.590 - 9.760). So far the closest I have found isIf I useCode:ffmpeg -i input.mp4 -ss 6.506 -to 9.677 -c copy output.mp4.. I get segment 2 (3.587-6.549) included in the output. The frames near the start cut point are:Code:ffmpeg -i input.mp4 -ss 6.504 -to 9.677 -c copy output.mp4
Frame Type pkt_pts_time
B 6.465
B 6.507
P 6.549
I 6.59
B 6.632
Does anyone know why the cut points do not achieve what I am trying to do? I thought it should be straight forward sine the key frames are know but I haven't found a way yet. Any help would be greatly appreciated. Thanks
+ Reply to Thread
Results 1 to 12 of 12
-
-
It cold be OpenGOP which can't be easily splitted. Upload the file or try a different software like e.g. SolveigMM Video Splitter or VideoReDo. (That said, I haven't actually tested how ffmpeg reacts to OpenGOP.)
-
The -codec copy option forces cuts on I frames only; the demuxer backs up from your requested seek time to the nearest I frame and that's why you're getting more than you asked for. If you want to cut on non-I-frames, you must re-encode.
-
I understood that ffmpeg cuts to nearest I frame but when trying to cut 6.590 - 9.760 , 6.504 is not nearer 3.587 but still picks up that segment or at least the audio. 6.506 IS closer to 6.590 but if i use 6.590 or even 6.589, it skips that segment completely. Im checking on the open GOP situation in csse that is it. Thanks
-
Did you try -ss 6.591? Requesting -ss 6.591 should go back to the 6.590 I frame
-
Update so far... progress but not perfect...
Did you try -ss 6.591? Requesting -ss 6.591 should go back to the 6.590 I frame
These are my latest results cutting at 2 frames before Start I frame and Stop I frame shown in parenthesis. I have no idea why this works best when all the documentation states that ffmpeg seeks to the nearest I frame unless Encoding takes place. Its as close to working as I've gotten so far. The TTime(Total Duration), VTime(Video Duration) and ATime(Audio Duration) were gotten from Media Info. One thing I added was adding the frame rate before input and it seems to work better with less variation from the original video.
Code:ffmpeg -i "Manjandani 1.mp4" -ss 9.676 -to 14.139 -c copy "Manjandani 1 Trim 1.mp4"
3.587(3.503) 6.590(6.506) 3.003 71.999 72 3.003 3.003 2.987
6.590(6.506) 9.760(9.676) 3.170 76.003 76 3.179 3.170 3.179
9.760(9.676) 14.223(14.139) 4.463 107.004 107 4.463 4.463 4.459
------------------------------------------------------------------------------------------------
Code:ffmpeg -r 23.976 -i "Manjandani 1.mp4" -ss 9.676 -to 14.139 -c copy "Manjandani 1 Trim 23976.mp4"
9.760(9.676) 14.223(14.139) 4.463 107.004 108 4.463 4.463 4.459
Main problem now is the start frame of the cut segments start with PTS time of .084001. I tried to use -set_timestamps 1 but it made no difference what-so-ever.
If anyone knows how to set the timestamps back to 0.000 start I would appreciate it. -
Not sure (about ffmpeg reporting capabilities and related behaviour) but I frame in h.264 doesn't mean it is IDR frame... (this where i have no doubt - IMHO clean cut is possible only on IDR frames which are real I frame - some software report non-IDR frames as 'i' opposite to real IDR reported as 'I')
-
That's not quite true according to https://ffmpeg.org/ffmpeg.html#Main-options.
-ss position (input/output)
When used as an input option (before -i), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. -
Not sure (about ffmpeg reporting capabilities and related behaviour) but I frame in h.264 doesn't mean it is IDR frame... (this where i have no doubt - IMHO clean cut is possible only on IDR frames which are real I frame - some software report non-IDR frames as 'i' opposite to real IDR reported as 'I')
-ss position (input/output)
When used as an input option (before -i), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position.
ffmpeg -ss 6.638 -i "Manjandani 1.mp4" -to 6.600 -acodec copy -vcodec copy -y "Manjandani 1 trim ss before.mp4"
This resulted in a segment before the one i wished, the one I wished and the one after that. So I attempted to use -T and got better results but I have no idea why the settings had to be as they were.
ffmpeg -ss 6.638 -i "Manjandani 1.mp4" -t 3.039 -acodec copy -vcodec copy -y "Manjandani 1 trim ss before.mp4"
153 6.382000 P
154 6.424000 B
155 6.465000 B
156 6.507000 B
157 6.549000 P
158 6.590000 I
159 6.632000 B
160 6.674000 B
161 6.716000 B
162 6.757000 P -ss 6.637 -> picked up back to 3.587 -ss 6.638 picked up forward to -> 6.590
-----------------
227 9.468000 P
228 9.510000 B
229 9.552000 B
230 9.593000 B
231 9.635000 P
232 9.677000 B
233 9.719000 P
234 9.760000 I
235 9.802000 B
236 9.844000 B
237 9.885000 B
238 9.927000 P
239 9.969000 B
240 10.01000 B
241 10.05200 B
242 10.09400 P (-t 3.039 (Up to 9.629) -> yields up thru 9.719) (-t 3.040 (Up to 9.630) -> to include 9.760-14.223 segment)
Duration Total 3s 179 ms --- Video Duration 3s 170 ms --- Audio Duration 3s 179 ms
None of these failures resulted in choosing the NEAREST I-Frame unless the nearest has a different meaning to FFMPEG rather that DTS Time. -
You could try to add -strict 2 option to your command line, secondly IMHO you can perform clean cut on h.264 and other codecs sharing same stream concept only on IDR frames (real I frames). I don't know if ffmpeg distinguish between those two types of frames ( i mean 'i' and 'I' a.k.a IDR).
---
https://video.stackexchange.com/questions/19250/how-to-identify-i-frame-from-idr-frame...-frames-output
seem you need to cut on frames where 'key_frame=1' is flagged -
May be an (unfixed) issue that came up before:
https://trac.ffmpeg.org/ticket/6315
https://forum.videohelp.com/threads/383216-FFMpeg-cutting-without-re-encoding-AviDemux...ect-ratio-info -
UPDATE
I found a video that is al IPPPPPPPPPPPPI format and it cuts perfectly to the I frame. Im going to create normal libx264 video and one with the -cgop option and compare ffprobe output and cutting results.
Okay, first I used ffmpeg to create Open and Closed GOP videos from the above video. There were conflicting posts on the internet as to what was the default X264 type of GOP and the default FFMPEG GOP so I tried 3 methods. Not specifying Type of GOP and -flags +cgop and -flags -cgop. The results were:
---------------------------
ffmpeg -i "C:\Users\Bud\Desktop\Batch files\Beta Test\xxinput1_IPPP.mp4.m4v" -acodec copy -vcodec libx264 -crf 20 nothing.mp4
weightb=1 / open_gop=0 / weightp=2
IBBBPBBBP//BBBPBBPI
---------------------------
ffmpeg -i "C:\Users\Bud\Desktop\Batch files\Beta Test\xxinput1_IPPP.mp4.m4v" -acodec copy -vcodec libx264 -crf 20 -flags +cgop Plus_cgop.mp4
weightb=1 / open_gop=0 / weightp=2
IBBBPBBBP//BBBPBBPI
---------------------------
ffmpeg -i "C:\Users\Bud\Desktop\Batch files\Beta Test\xxinput1_IPPP.mp4.m4v" -acodec copy -vcodec libx264 -crf 20 -flags -cgop minuscgop.mp4
weightb=1 / open_gop=1 / weightp=2
IBBBPBBBP//BBBPBBI (Number of trailing/leading BB's vary)
---------------------------
SUMMARY if you want Open GOP then specify -flags -cgop (no_closed_GOP)
================================================== ====
Next I used one Closed GOP (Both closed GOP were identical in timings, frame count, etc.) and the Open GOP video with 2 different methods to pick a sequence that is easily detectable going frame by frame as to the results. I used the "-t xx" option because, apparently, -ss before input (-i ), resets the timecode to 0 so if you use what you think would be the next I frame, you are usually telling it too far. E.G. This test video is 7 minutes and 27 seconds long. If I had used -ss 327.1271 -i video.mp4 -to 335.4688 output.mp4, I am actually telling it 0 to 335.4688 or more than 5 minutes after the 5 minutes and 27 seconds start cut. What I received after several attempts to use -ss prior to input and after input resulted in files that I have no idea why they were the length they were or unplayable and around 187kbits. I may revisit this later but for now the results were better below.
Key Frame to Key Frame using "-t" option
KEY FRAMES LOCATED AT 05:18.7855(318.7855) -- 05:27.1271(327.1271) -- 05:35.4688(335.4688)
===========================
for %a in (*.mp4) do ffmpeg -ss 05:27.1271 -i %a -t 8.3417 -acodec copy -vcodec copy %~na_sskik.mp4
---------------------------
Closed_X264_GOP.MP4 (alias plus_cgop.mp4)
Original 327.1271(I-frame@9804) 335.4688(I-Frame@10054) 251 Frames
Cut 00.0000(I-Frame@0) 8.3416(I-Frame@250) 251 Frames but pickedup one extra B frame 252 08.4084
Last Frames -> PBBPPBPIB
Evidently my math is wrong or 8.3417 goes past 8.3416 and picked it up also
---------------------------
Open_X264_GOP.MP4 (alias minus_cgop.mp4)
Original 327.1271(I-frame@9804) 335.4688(I-Frame@10054) 251 Frames
Cut 00.0000(I-Frame@0) 8.3416(I-Frame@250) 251 Frames but pickedup one extra B frame 252 08.4084
Last Frames -> PBBPPBBIB
METHOD 2 Cut 2 frame before I-Frame and end 2 Frames before next I-Frame
===========================
for %a in (*.mp4) do ffmpeg -ss 05:27.0603 -i %a -t 8.3417 -acodec copy -vcodec copy %~na_sskik.mp4
Closed_X264_GOP.MP4 (alias plus_cgop.mp4)
Original 327.0603(I-frame@9802) 335.4020(I-Frame@10052) 250 Frames
Cut 00.000(I-frame@0) 08.3750(P-Frame@251) 252 Frames
Last Frames PBBPPBBPPP
---------------------------
Open_X264_GOP.MP4 (alias minus_cgop.mp4)
Original 327.0603(I-frame@9802) 335.4020(I-Frame@10052) 250 Frames
Cut 00.000(I-frame@0) 08.4084(I-Frame@252) 252 Frames
Last Frames BBBPBBPPBI
---------------------------
Summary Closed GOP started at previous I-Frame and went through the -t time.
Open GOP started at previous I-Frame and continued through -t, adding an I-Frame at the end due to the preceding B-Frame before it, which occurs in an Open GOP format.
FINAL SUMMARY:
Using -ss before input and -t output options, Key Frame to Key Frame (Some type of I Frame) works well. Figuring the -t time can result in an extra frame. I'm not sure if this because of something like adding the time on AFTER the Starting I-Frame but seems to be the case.
Using -ss before input and -t output options, cutting at a frame in between I Frames will result in the start point being the earlier I-Frame and continue through the -t option for Closed GOP and through the -t option, but changing the last Frame to I-Frame due to being Open GOP and preceding B-Frame..
Hope this helps anyone that has asked about cutting at an I frame or not at an I frame and not re-encoding and what the results were. I know this may be a junk post to some but in my searches (not here of course,LOL) , I found hundreds of requests to cut video and many many answers that contradicted each other or were unclear. Since I needed to know myself for a project, I thought I would try to help others in the process by posting here.
Thanks
Budman1Last edited by Budman1; 2nd May 2018 at 02:04.
Similar Threads
-
Cut MKV frame accurate
By Dimuk in forum Newbie / General discussionsReplies: 23Last Post: 29th Apr 2022, 09:20 -
Use ffmpeg to replace frame with previous frame if frames are X % different
By dkrichards16 in forum Video ConversionReplies: 0Last Post: 29th Apr 2017, 16:27 -
Looking for software to cut at exact frame
By axeon73 in forum Newbie / General discussionsReplies: 10Last Post: 2nd Dec 2016, 12:51 -
Can ffmpeg use frame numbers to cut a video?
By yetanotherlogin in forum EditingReplies: 4Last Post: 26th Jan 2015, 05:12 -
How to cut video with ffmpeg with the same quality without reencoding
By alexander121 in forum EditingReplies: 6Last Post: 8th Dec 2014, 02:36