Reading through the documentation of ffmpeg and some old code I thought that it should be relatively easy to write a small key-frame accurate file cutting tool based on ffmpeg.
basically one would do the following steps:
instead of using the segment option one could also use something like ffmepg -i "path input" -ss 00:00:01 -t 00:00:03 "path output1" -ss 00:00:05 -t 00:00:04 "path output2"... to lower the amount of overhead. (command line length restrictions might cause a problem if a lot of cuts happen,..)
- Collect the key frame positions using ffmpeg or ffprobe
- let the user decide which gops to keep and which to remove
- use ffmpegs segment-options to a. split the content into parts and at the same time create a .ffconcat list
- modify the .ffconcat list to not include the unwanted gops
- use ffmpegs concat-demuxer to concatenate the wanted gops into a new file (and remux to the target container you want)
- clean up
since this is doesn't seem really complicated, I wonder:
- 'Is there some software out there that already does this?`
- 'Did I miss some caveat?'
I know vfr content and subtitles can't probably be processed properly by ffmpeg, but for normal files this should work, shouldn't it?
Only real downside is that the temporary space requirement is rather large.
-> Any thoughts? Is there an easier way to do steps 3.- 6. ?
Cu Selur
Ps.: may be I'll add this some time in the future to Hybrid or write a small separate tool. Looks like a easy cross-platform compatible way for cutting at key frames,...
Try StreamFab Downloader and download from Netflix, Amazon, Youtube! Or Try DVDFab and copy Blu-rays! or rip iTunes movies!
+ Reply to Thread
Results 1 to 30 of 31
Thread
-
-
i was playing around with this exact same idea, to add a crude but workable .ts cutter to snip out any last minute sections and i needed something freeware'ish. but i don't know how to set ffmpeg to automatically always cut at the "I" frame so that there are no artifact before and/or after the cut clips. each clip would have a different i frame placement. not sure how to work that out in avc clips. but i'm still working on the add this piece to the my gui in my hdpvr_io tool. this is the code i last tested. it works fine, except for some artifacts. not sure if ffmpeg is re-encoding and causing the artifacts or that the in/out cuts are not in the best place.
Code:ffmpeg -i "h:\video.ts" -ss 00:00:00 -t 00:00:02.000 -vcodec copy -acodec copy -y "h:\video_cut.ts"
-
well, the other issue i see is with a working "preview" and ability to step backword/forward per frame.
-
how to set ffmpeg to automatically always cut at the "I" frame so that there are no artifact before and/or after the cut clips.
well, the other issue i see is with a working "preview" and ability to step backword/forward per frame.- on windows: easy doable through avisynth
- cross platform: complicated (iirc. MLT-framework offered that) and probably only achievable by doing it similar to avidemux (and ffmpegsource): 1st index the whole stream 2nd navigate through the stream using a self written navigation based on the index and libav.
(side note: key frame stepping should be enough and should be doable with mplayer in slave mode )
Last edited by Selur; 13th Oct 2013 at 18:34.
-
Or does it distinguish between IDR/i frames now with pict_type ?
Under "select" documentation
http://ffmpeg.org/ffmpeg-filters.html#select_002c-aselect
‘pict_type (video only)’the type of the filtered frame, can assume one of the following values:
‘I’ ‘P’ ‘B’ ‘S’ ‘SI’ ‘SP’ ‘BI’
FFPICT_TYPE The picture type of the most recently requested frame as the ASCII number of the character listed below. Use Chr() to convert it to an actual letter in avisynth. Use after_frame=true in Avisynth's conditional scripting for proper results. Only set when rffmode=0. The FFmpeg source definition of the characters:
I: Intra
P: Predicted
B: Bi-dir predicted
S: S(GMC)-VOP MPEG4
i: Switching Intra
p: Switching Predicted
b: FF_BI_TYPE (no good explanation available) ?: Unknown -
thanks for the force_key_frames tip.
actually, i've been suing that (trick) technique myself with avisynth in other gui projects. however, with my .ts captures, they unpredictably crash just like they do in dgavc. i had a thread about this last year i think. unless there is a special ffmpegsource version i don't know about, well, stepping bw/fw will randomly crash on my through avisynth/ffmpegsource. -
@vhelp:
a. instead of ffmpegsource I would use LWLibavVideoSource
b. if your source is buggy (or has broken headers, which ts captures often do), it's not really a surprise when the avisynth source filter crashes
@poisondeathray: checked some code I got in Hybrid and the comments I added to it -> Type_I should be IDR frames; and yes switching intra frames are Type_SI. -
wow. thank you for the LWLibavVideoSource tip. (it took this long, between finding the correct version to get it up and running, and adding the step below to get working properly in my setup) its (video only) is flawless so far. that is, no crashes stepping bw/fw, jumping around anywhere and it loads up pretty quickly. no more (buggy) dgavc and ffmpegsource/ffms2 method for me.
Code:v = "h:\499.video.hdpvr.nbc.snl.MyLeyCyrus2013.full.9Mbpts.ts" LoadPlugin( "C:\PLUGINS\LSMASHSource.dll" ) LWLibavVideoSource(v, cache=True, threads=2).selectevery(2,1) AudioDub(last, LWLibavAudioSource(v, stream_index=1, av_sync=true))
Last edited by vhelp; 13th Oct 2013 at 21:16.
-
@vhelp: Happy it did work. Small warning about LWLibavVideoSource: It does like FFVideosource create an index, but it can create this index inside the RAM, problem with that is, that the index of LWLibavVideoSource is rather large, so it can kill the 3GB memory boundary of Avisynth. (-> read the L-Smash Source thread over at doom9).
Cu Selur -
MpegStreamClip works great for mp4.
Got my retirement plans all set. Looks like I only have to work another 5 years after I die........ -
I'd still like to use ffmpeg instead, though, because it can be scripted.
The following doesn't slice videos at keyframes, so the next slice starts looking funny (I guess it contains non-keyframes):
Code:ffmpeg -ss 00:00:00 -i input.mp4 -to 01:00:00 -c copy -shortest -f mp4 Part1.mp4 ffmpeg -ss 00:59:50 -i input.mp4 -c copy -shortest -f mp4 Part2.mp4
Thank you. -
Have you tried, leaving out the '-shortest'? (from my point of view it seems wrong to add it in the first place, but you probably know why you used it,...)
users currently on my ignore list: deadrats, Stears555 -
Try:
Code:ffmpeg -i input.mp4 -t 01:00:00 -c copy -f mp4 Part1.mp4 ffmpeg -i input.mp4 -ss 00:59:50 -c copy -f mp4 Part2.mp4
Got my retirement plans all set. Looks like I only have to work another 5 years after I die........ -
what with:
https://www.ffmpeg.org/ffmpeg-all.html#trim
https://www.ffmpeg.org/ffmpeg-all.html#atrim
shortest is to stop operation when one of stream components is shorter than others (i.e. video end before audio or opposite) -
shortest is to stop operation when one of stream components is shorter than others (i.e. video end before audio or opposite)users currently on my ignore list: deadrats, Stears555
-
Thanks much for the infos.
Code:ffmpeg -i input.mp4 -ss 00:59:50 -c copy -f mp4 Part2.mp4
If that's the case, how to tell ffmpeg to slice the first part at the last keyframe, and start the next part at the first keyframe?
I think MyMP4GUIBox does just that: If you slice at, say 1hr but it's a non keyframe, it will starts earlier so as to start at a keyframe.
As for "-shortest": I was using it by mistake thinking it meant that encoding would go faster (which doesn't make sense when just copying the video stream anyway). -
ffmpeg works perfectly with every video I throw at it, yours is an exception, not the norm. Probably many things wrong with your source. Use MpegStreamClip to cut that mp4 on key frames then.
Got my retirement plans all set. Looks like I only have to work another 5 years after I die........ -
Nope, since I had the same problem with other files I tried before.
MPEG StreamClip: "QuickTime is not installed!". No way I'm installing that POS on my computer.
Besides, googling for "ffmpeg split keyframe" returns very complicated solutions to something that (IMHO) should be as simple as:
Code:ffmpeg -i input.mp4 -onkeyframe -ss 00:59:50 -c copy -f mp4 Part2.mp4
Thank you. -
https://www.ffmpeg.org/ffmpeg-all.html#trim
start_pts
This is the same as start, except this option sets the start timestamp in timebase units instead of seconds.
end_pts
This is the same as end, except this option sets the end timestamp in timebase units instead of seconds. -
You are so right!
I solved it: Start with:
1
FFPROBE
ffprobe -skip_frame nokey -show_frames -select_streams v "Death in Paradise_BBC First HD_2017_03_01_07_20_00.ts">"Death in Paradise_BBC First HD_2017_03_01_07_20_00.txt"
2
ffmpeg -skip_frame nokey -i "Death in Paradise_BBC First HD_2017_03_01_07_20_00.wtv" -vf scale=640:360 -vsync 0 keyframes%01d.jpg
3
I wote a script in Yabasic to extract the best_effort_timestamp_time the aformentioned file and link het timestamp to the image-number write it in another file which I named edlfile.txt
4
to determine the cutpoints
another script in yabasic invokes FFPlay to display the images and store the timestamps in EDL file:
ffplay -exitonkeydown -hide_banner -loglevel quiet -loop 0 image.jpg
5
Final Yabasic sript to slice up the video at the cutpoints and concatenate them:
ffmpeg1$= ffmpeg -hide_banner -stats -y -i " video in " -ss " start -t duration -map 0 -vcodec copy -acodec copy -scodec copy "vide out"
you have to repeat this for every part.
ffmpeg2$ = ffmpeg -loglevel quiet -hide_banner -stats -y -f concat -safe 0 -i concat.txt -vcodec copy -acodec copy -scodec copy "video out"
Final note:
I am not happy using ffplay to navigate the images in order to get the cutpoints since it has no slave-mode like mplayer which to my knowledge does not handle images, so I'm stuck with it so far.
Hope this wil help and give someone the "eureka moment" and if you do please let me know. -
FWIW.. I am working on this feature but have not perfected it yet for some of the reasons listed here. I used the script shown to create a list for a variable bit rate MP4:
Code:ffmpeg.exe" -i "C:\Users\Bud\Desktop\Various test Formats\[dp]Manjandani-1.mp4" -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 2 -f null NUL -loglevel debug 2>&1| for /f "tokens=4,8,9 delims=. " %d in ('findstr "pict_type:I"') do echo %d %e.%f>>"C:\Users\Bud\Desktop\[dp]Manjandani-1_KeyFrames.txt"
This results in a list as shown below:
The problem remaining is that the list is off by a certain amount while the actual displayed type is correct in the viewer (Potplayer) using an avisynth script and remains off about the same amount:
Code:FFmpegSource2("C:\Users\Bud\Desktop\Various test Formats\[dp]Manjandani-1.mp4", atrack=-1).Crop(0,0,-0,-0) ScriptClip(Last, """Subtitle("[ "+Chr(FFPICT_TYPE)+" ]", size=(Height*56.0/720), align=2)""", after_frame=true) LanczosResize(864,368) Subtitle("C:\Users\Bud\Desktop\Various test Formats\[dp]Manjandani-1.mp4", x=864, y=204, font="Arial", size=24, text_color=$ff0000, align=3) Subtitle("This is Anamorphic video", font="Arial", size=24, text_color=$ff0000, align=5) ShowFrameNumber(scroll=true, x=10, y=27, font="Arial", size=24, text_color=$ff0000) ShowTime(x=72, y=44, font="Arial", size=24, text_color=$ff0000) ShowSMPTE(fps=23.976, x=68, y=61, font="Arial", size=24, text_color=$ff0000)
Seems to be a real need, at least for me, so still working on it. -
2 cents of thoughts from me:
- If you want to use avisynth on the whole clip, you should also use avisynth to extract the I-frame positions. (see: https://forum.doom9.org/showthread.php?p=1607578#post1607578)
- ShowTime will only show the correct time if your video has no a/v delay and is cfr.
- Instead of using ScriptClip it would be easier to use FFInfo.
users currently on my ignore list: deadrats, Stears555
Similar Threads
-
Cut MKV frame accurate
By Dimuk in forum Newbie / General discussionsReplies: 23Last Post: 29th Apr 2022, 10:20 -
Avidemux: The beginning frame is not a key frame. Please move the A marker
By devilcoelhodog in forum EditingReplies: 13Last Post: 8th Jun 2015, 13:38 -
Frame accurate cutting of H.264 files
By Ahari in forum Newbie / General discussionsReplies: 28Last Post: 15th Mar 2014, 21:10 -
Specifying maximum key frame interval and new resolution in ffmpeg?
By pxstein in forum Newbie / General discussionsReplies: 5Last Post: 17th Sep 2013, 12:06 -
Frame accurate cutting on m2ts files?
By stryker412 in forum EditingReplies: 3Last Post: 29th Jan 2012, 05:20