bartekmotyl / simple-video-cutter

Windows-based tool for efficient browsing and cutting video footage
MIT License
317 stars 42 forks source link

cut video - duration not adjusted #59

Closed 0lm closed 2 years ago

0lm commented 2 years ago

hi example: i have a video 7min long when i cut it from 6:10 - 6:30, then it works, and opening it with a video player it really only shows these 20 sec. but the time stampt starts at 6:10 to 6:30 and in the info it shows the video is in total 6:30 min long

basically i do have some dummy gap from 00:00 min - 6:09 min. why is this empty gab still added? i think the "start point" is not properly working. i did not change any settings in simple video cutter. i used it instantly when i downloaded it. the used file was an mp4 file.

what i usually expect: the video info says the video is now 20 sec long and timestamp of video bar will show 00:00 . 00:20 min duration.

bartekmotyl commented 2 years ago

Hi, can you try to replicate the issue on one of the sample movies that can be found here? If it doesn't work, can you provide some other file that runs into this problem ?

0lm commented 2 years ago

Hi, can you try to replicate the issue on one of the sample movies that can be found here? If it doesn't work, can you provide some other file that runs into this problem ?

Hey. I can try. I was going for the 320x180 mp4 file. But the downlaod speed is extremely slow from that site, eventually dropping down to 8 KB /sec. y any chance, are these files available on a faster host? or else the 64MB video takes 2-3h for me (my initial speed is 6 MB/sec usually)

bartekmotyl commented 2 years ago

Thanks. It doesn't have to necessarily be that file - can be any other file that works incorrectly for you and you can share it.

0lm commented 2 years ago

Thanks. It doesn't have to necessarily be that file - can be any other file that works incorrectly for you and you can share it.

Hey again. tested it again. Download the 1920x1080 one from here or alternatively the exact direct link to the video.

The video lasts 30 sec in total. My start point was around 20,xx sec and end point was 23,xx sec. (yes, i am performing cutting by ignoring keyframes. i am using cutting with re-encoding by not-sticking with keyframes, but basically cutting right through them)

so normally, the video must be 3 sec long now. but the file still says its now 23 sec long. and the time stamp bar while playing a video, also displayes 23 full seconds in any video player, and the play bar start at its 20 second. of course everything from 00:00- 00:22 sec is basically empty dummy space.

at first it doesnt sound like a big issue. but it can become one when i want to use the cut video for other editings/processings. for example, i tried to convert the cut mp4 video into a gif file with imagemagick. first i wondered why it still didnt give me a gif file after 1h, since the video was only 5 sec long. thats how i noticed that the time stamp of my own cut video still says 6min33sec long (i cut it from 6min28sec-6min33sec, its inital uncut length was 7min something) so, while cutting with simple video cutter , it recognizes the "end point", but it seems not to really consider the "start point" in the time stamp/duration.

this also could be an issue with ffmpeg, when i think about it. but im not sure. maybe anything changed with the newest fmpeg build. (its the 23rd May 2022 build the software auto-downloaded)

after re-encoding/remuxing with handbrake for example, i can fix the wrong duration. but would be convenient, if simple video cutter would do it right from start. i hope its now possible/easier to reproduce this bug with the given information and the example file i linked. and thanks for this awesome tool by the way!

0lm commented 2 years ago

any news about the fix-ability of this bug? would be happy if it was possible, and hopefully it is not too hard/inconvenient to fix it. anyways, regardless of it can be fixed or not, thanks for the useful tool!

m42cel commented 2 years ago

I'm facing the same issue. I've only tested with mp4 files, doing a single cut somewhere in the middle of the video without re-processing. It seems like the end of the video is set correctly but the start is not adjusted.

I have some examples here: https://drive.google.com/drive/folders/1hCBon196zCyCEica1_rPxEIcFrl9KaxM (you'll have to download the files since the preview is already re-processed by Google Drive).

The original video is 50 seconds long and I cut from second 15 to second 27. I would expect the new video having a length of 12 seconds but when playing it starts with second 15 and ends with second 27. If you navigate to earlier than 15 seconds it jumps right back to 15.

bartekmotyl commented 2 years ago

Hi, thanks for the feedback. I am currently focused on other projects but once I have some free time I will investigate it further.

m42cel commented 2 years ago

I did a little debugging session and found the issue, however I don't know what's the best solution.

It seems to only happen when input seeking is used (you've also added a comment regarding input / output seeking, referencing https://trac.ffmpeg.org/wiki/Seeking).

Using output seeking, i.e. placing the -ss option after the -i, seems to not have this issue with the start time.
This might be the case since for output seeking it says:

As of FFmpeg 2.1, the main advantage is that when applying filters to the output stream, the timestamps aren't reset prior to filtering

For lossless processing output seeking also doesn't have any noticeable performance impact, however with re-encoding you'll wait a few seconds for the seeking.

I've also tried to combine input and output seeking by setting it to the same time before and after the -i option, which first seemed fast and did not have the time issue, but instead I noticed what is described at the bottom of the ffmeg seeking site:

Seeking while doing a codec copy 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.

(I tested the exact same cut with only input seeking and the combined seeking but that described issue of leading audio with no video was only present with the combined seeking)

Not sure if the issue is resolvable with input seeking but I don't mind waiting a few more seconds (that I also only have to wait when it's re-encoding which I try to prevent anyways and where the encoding time itself will shadow the output seeking time).
So my suggestion would be to just switch to output seeking and placing the -ss option after -i.

I've just built a binary with that change for myself. If you like I could create a PR for it (if it's worth doing so for two lines and you don't intend finding a solution using input seeking).

Regardless of that, thanks for the great tool!

bartekmotyl commented 2 years ago

@mkaeufler thank you very much for investigating the issue! I will try to integrate your change and release a new version ASAP, but probably not before next week.

bartekmotyl commented 2 years ago

I have investigated the problem further and although switching to output seeking does indeed solve the problem, it is extremely slow for larger files (one can try e.g. with Big Buck Bunny videos)

I have performed several experiments and found out, that adding -avoid_negative_ts make_zero option to ffmpeg actually solves the problem (at least for me). I have tested both lossless as well as lossy and both worked fine for me. I will include the change in next release (v0.23) and would like to ask you guys for verificatino whether it also solves the problem for you. Additionally, I have added undocumented config properties:

        public bool LosslessInputSeeking { get; set; } = true;
        public bool LosslessOutputSeeking { get; set; } = false;
        public bool LossyInputSeeking { get; set; } = true;
        public bool LossyOutputSeeking { get; set; } = false;

that can be used to decide whether to use input or output seeking (but not both!).

m42cel commented 2 years ago

Thank you for looking into it again. I did not know about the avoid_negative_ts option, so I learned something new today :) I could also verify that the new release does not show the issue anymore. Thanks!