-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change ffmpeg argument order so that it correctly cuts at keyframes #13
Conversation
I've had this problem too. Thanks for the work on the fix @avh4! |
Hmm... well, I'm not sure this is actually better yet... After this change, the resulting mp4 files play correctly on Mac, but if I process them further with ffmpeg, there are still problems with the initial few seconds. I will try to experiment with this further. |
So I'm having the best results atm with
I'll try to set up a script to compare the effect of some of the different changes here to see what's actually best. |
Good job! I've got some test videos/audios that I used to test with: |
So it seems that the So I guess I'm not sure lossless-cut would want to add the I'm still investigating ways to generate a keyframe at the desired cutpoint in order to produce an output that both is cut accurately and starts with a keyframe. |
Will the audio be shifted to be in sync with the video when using -noaccurate_seek and -avoid_negative_ts ? I don't think it's a problem that the actual cut time is different from what you specified. Because as you say without it the part before the keyframe is useless anyways, so it has the same effect. I actually thought about recreating the lost part after the first keyframe too, by maybe doing a re-encoding of the part between the cutpoint and the first keyframe, and then losslessly merge this part with the cut part. But then it would have to be encoded using the same parameters as the original video. Edit: Regarding |
So the problem with using |
So is there any difference between using -noaccurate_seek and not using it? from what i can understand from your last comment, you will get the first part without video in both cases? There has to be a faster way of detecting keyframes. If you look propietary software, they are able to generate thumbnails (presumably from keyframes) almost instantly throughout the timeline. |
From the user experience side of things, you might want to play with how the Avidemux approach feels. They "encourage" the user to split on keyframes by having the video slider automatically jump to keyframes. They also make the more obvious forward/reverse buttons be keyframe jumps. However, there are also frame-by-frame advance arrows. No idea what's going on at the backend, I'm just a "user." |
Thanks for the input. I agree that we should snap to or show keyframes somehow, but I don't know how to quickly and easily get keyframe positions from the video. Using ffprobe is very slow as previously discussed. |
I'm wondering if Smart Rendering could be implemented to solve this problem in the best possible way. In the past I tried to script |
How did you do it in your python script? I was thinking about doing something like this: However the same problem arises, which is that ffprobe is very slow. |
The idea is the classic Smart Rendering approach, e.g.:
Assume A, B, C and D are I-frames:
It was almost working, then I realized not every I-frame is a keyframe (some GOPs contain back references even across I-frames) and you can only cut on "true" keyframes. But you cannot determine what the real keyframes are with
What I did was to cut 2 minutes of video around my point of interest (e.g. |
Great explanation, thanks. That's the same way I thought of doing it. I tried to use the read_intervals options for ffprobe, which acheives the same by seeking before printing, but it's still very slow. Just printing frame info for 10 seconds of video takes like 20 seconds on my MBP, which is way too slow.
|
Have you tried with a video file which is actually 10 seconds long? |
Yes, I tried with a DJI footage. it took 15 sec. |
I see. Well, personally I would happily wait 1 or 2 more minutes when cutting a hour long video, if I knew I would get smart rendering... but of course other people might have different opinions on this. 😄 Also, maybe you could run |
Maybe. But it complicates things a bit. Best would be to figure out how to somehow read all keyframes superfast like Avidemux apparently does. I found a way to speed up ffprobe a bit btw. By providing -skip_frame nokey |
If this is of any help, FFmpegYAG also known as FFmpeg Hi GUI has a way to distinguish I/P/B frames seemingly instantaneously just like Audacity, except... well, it uses FFmpeg. |
I've tried to use the ffmpeg command line to cut by first using ffprobe with I also discovered that One option might be to use the "segment" format in ffmpeg, as it seems to cut by keyframe. but it complicates things. |
I tried to use the ffmpeg segment output format with the default segment time, but it also produces segments with the wrong length (empty video in the end of each segment), similar to cutting with |
Your findings about ffmpeg match my experiments I did in the past. That's also because not every I-frame is a keyframe, unfortunately... 😭 |
I think we need add two tool icons, which jump to last/next keyframe. like in avidemux. |
Yes that should be fairly trivial to implement but not very useful until we figure out how to actually cut on keyframes |
FYI, I believe there is a slightly hacky way to get even closer to what you're trying to accomplish. While it's true that you must trim at GOP boundaries, you don't necessarily need to display all of those frames. In the mp4 headers that you write, you can "mute" frames at the beginning and end by setting their duration to 0 in the These 0-duration frames will be available for reference by other frames, but will not play. (Make sure to drop audio frames appropriately, too.) The "right" way to do this is with mp4/mov Edit List metadata ( |
🆕🆕In the newest version 1.13.0 I've added a button to the leftmost of the right button row, called 👆 Would be nice if people can try this feature and see if this causes any trouble when processing files further! I will probably make this the default in the future, as it seems to be working nicely. Unless someone reports some trouble with it. |
So far from my observations it seems that new feature works perfectly fine. Audio is synced with video 👍 I didn't check on too many files as most of my stuff is in HEVC. Soon I'll test more. Thank You :) |
The new functions is very good. But those small buttons are too small and a little hard to understand. Would you like to change them into menu mode, tick menu? At least the menu text is more clearer than hover one. |
@eexpress I agree, the buttons are a bit tricky. A menu would be really nice, but I have to figure out how to easily dynamically update menu state. Thinking about something like https://github.com/SamyPesse/react-electron-menu but it seems a bit unmaintained. |
For a consistent user interface, maybe put those options here (just your help interface) is more easy (maybe temporarily), and it also easy to dynamically update those text. |
Works for me. Full HD 60FPS .mov files from an Olympus Stylus. I agree the interface is a bit confusing, and I would easily forget to set the kc option every time. Still, thanks for implementing this. |
|
To summarize, the nc (normal cut) & kc (keyframe cut) cutting modes correspond respectively to the following examples:
The next link suggests combining seeking ( Here, I use also To be checked and tested on your application cases, with your video players, to see if combining seeking really helps... |
Regarding "finding keyframes", there's a way other than ffprobe. I'm not sure if it is much faster, but it also allows selectively searching (as opposed to processing the whole file in one attempt):
select documentation, including more examples
This yields output like this (which apparently can't be further customized), but at least it includes the timestamp. The frame number can't be trusted, because they get renumbered after the filter.
|
@GeoDecouvreTout whats the Point of -ss both before and after? |
@ccoenen yea we could run this +- a few seconds around current time when moving the cursor and update a separate list of known keyframe times |
From my understanding: With kc ( With nc ( With |
I stumbled upon this extremely relevant thread while trying to resolve very similar problems discussed above, the difference being that the seeking functionality is being implemented within my c++ code and not via the ffmpeg command line. So I am working with av_seek_frame and the AV_FLAG_BACKWARD flags. I am running into a/v sync issues and inaccurate seeking. Any pitfalls to avoid here or any relevant prior results/ findings shared will be really helpful. |
people are having success with this so make it default See discussion in #13
ffmpeg order error and no reencoding options
This is really helpful, using -ss ... -i ... -t ... gets them much closer to the keyframe. Is there a way to repair movie files that have been cut using -i ... -ss ... -t ... ? I have lot of files cut using this method, and wondered if there was an easy way to fix them |
If you mean repairing movie files cut with the However, you can try to apply the
Besides, this second ffmpeg pass could be implemented as a I have also noticed that the |
This works! Thanks |
according to mifi/lossless-cut#13 I've changed arguments order
- Implement an Export summary/confirmation sheet when pressing export - Move output option buttons to export sheet - Add config option to disable use_metadata_tags (default to false) #463 #402 #99 - Add config option for avoid_negative_ts #13 - Escape key to close sheets - Change from mousetrap to hotkeys.js (better unbind - more compatible with react)
closing in favor of #1216 |
When I run ffmpeg with the arguments in this order
-i ... -ss ... -t ...
, it produces a video file that has no video for a few initial seconds. (as far as I can understand this is because it doesn't seek to a keyframe?)If I change the order to
-ss ... -i ... -t ...
, then the resulting cut videos play properly.My `ffmpeg -version`