VideoHelp Forum
+ Reply to Thread
Results 1 to 12 of 12
Thread
  1. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    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 is
    Code:
     ffmpeg -i input.mp4 -ss 6.506 -to 9.677 -c copy output.mp4.
    If I use
    Code:
    ffmpeg -i input.mp4 -ss 6.504 -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:

    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
    Quote Quote  
  2. 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.)
    Quote Quote  
  3. Member
    Join Date
    Aug 2010
    Location
    San Francisco, California
    Search PM
    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.
    Quote Quote  
  4. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    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
    Quote Quote  
  5. Did you try -ss 6.591? Requesting -ss 6.591 should go back to the 6.590 I frame
    Quote Quote  
  6. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    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
    Tried that but got a single I frame that played for the entire 3+ seconds

    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"
    Start Stop Duration FRMS@23.976 RealFrms TTime VTime ATime
    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"
    Start Stop Duration FRMS@23.976 RealFrms TTime VTime ATime
    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.
    Quote Quote  
  7. 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')
    Quote Quote  
  8. Member
    Join Date
    Aug 2010
    Location
    San Francisco, California
    Search PM
    Originally Posted by Budman1 View Post
    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.
    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.
    Quote Quote  
  9. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    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')
    The I Frames on my test file may or may not be Open/Closed GOP but all PTS times match DTS times and they are at a Scene change so I 'Assume' the files uses closed GOP. It really makes not much difference in the matter of using '-C copy' since the results are ridiculous unless I offset the -SS times by 2 frames and the -TO Times to 2 frames previous to the next I frame. Much further than that and it picks up another segment which is NOT the CLOSEST I frame.

    -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.
    I attempted to use -SS before input and -TO after input and the results were equally odd.

    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.


    f
    fmpeg -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
    PTS /DTS timings start at 0.000 with using -SS as input and -T for length of segment.

    None of these failures resulted in choosing the NEAREST I-Frame unless the nearest has a different meaning to FFMPEG rather that DTS Time.
    Quote Quote  
  10. Originally Posted by Budman1 View Post
    The I Frames on my test file may or may not be Open/Closed GOP but all PTS times match DTS times and they are at a Scene change so I 'Assume' the files uses closed GOP. It really makes not much difference in the matter of using '-C copy' since the results are ridiculous unless I offset the -SS times by 2 frames and the -TO Times to 2 frames previous to the next I frame. Much further than that and it picks up another segment which is NOT the CLOSEST I frame.
    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
    Quote Quote  
  11. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    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
    Budman1
    Last edited by Budman1; 2nd May 2018 at 02:04.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!