Open mifi opened 5 years ago
Have you guys taken a look at StaxRip? It is able to do lossless cuts in between keyframes. I think it uses Avi/Vapour Synth to do so.
Reporting my experience with the smart cut feature. For my files, recorded with the default settings of OBS it never works, the output is a file composed by:
Reading online I thought it was a limitation of ffmpeg, but I tried to do what I think lossless cut is doing under the hood, directly with ffmpeg, and it worked.
My file had a very long black part in the beginning that I wanted to cut, but lossless cut was unable to do it, it either kept all of it, or cut too much (or present the weird behavior described above with smart cut). With this command I discarded the first 9.5 seconds and re-encode from there to the nearest keyframe.
.\ffmpeg.exe -i "input.mkv" -ss 9.5 -to 10.468 -o -c:a copy "part1.mkv"
Then I created this txt file for the concat command:
file 'part1.mkv'
file 'input.mkv'
inpoint 10.468
And merge the re-encoded part and the original file with:
.\ffmpeg.exe -f concat -i "input.txt" -map 0:v -map 0:a -c:a copy -c:v copy "output.mkv"
Mb7iuu7u7
On Sat, Oct 1, 2022, 12:13 PM flagg19 @.***> wrote:
Reporting my experience with the smart cut feature. For my files, recorded with the default settings of OBS it never works, the output is a file composed by:
- the re-encoded, precisely cut part
- the not re-encoded part but it does not start at the cut point, much earlier
Reading online I thought it was a limitation of ffmpeg, but I tried to do what I think lossless cut is doing under the hood, directly with ffmpeg, and it worked.
My file had a very long black part in the beginning that I wanted to cut, but lossless cut was unable to do it, it either kept all of it, or cut too much (or present the weird behavior described above with smart cut). With this command I discarded the first 9.5 seconds and re-encode from there to the nearest keyframe.
.\ffmpeg.exe -i "input.mkv" -ss 9.5 -to 10.468 -o -c:a copy "part1.mkv"
Then I created this txt file for the concat command:
file 'part1.mkv' file 'input.mkv' inpoint 10.468
And merge the re-encoded part and the original file with:
.\ffmpeg.exe -f concat -i "input.txt" -map 0:v -map 0:a -c:a copy -c:v copy "output.mkv"
Here are the original file's media info
General Unique ID : 329460729124114956463710958428421807938 (0xF7DBD4102F9C88DDD61B13ADED82DF42) Format : Matroska Format version : Version 4 File size : 1.53 GiB Duration : 47 min 30 s Overall bit rate : 4 608 kb/s Writing application : Lavf59.16.100 Writing library : Lavf59.16.100 ErrorDetectionType : Per level 1
Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : @.*** Format settings : CABAC / 4 Ref Frames Format settings, CABAC : Yes Format settings, Reference frames : 4 frames Codec ID : V_MPEG4/ISO/AVC Duration : 47 min 30 s Width : 1 920 pixels Height : 1 080 pixels Display aspect ratio : 16:9 Frame rate mode : Constant Frame rate : 23.976 (24000/1001) FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Default : Yes Forced : No Color range : Limited Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709
Audio ID : 2 Format : AAC LC Format/Info : Advanced Audio Codec Low Complexity Codec ID : A_AAC-2 Duration : 47 min 30 s Channel(s) : 2 channels Channel layout : L R Sampling rate : 48.0 kHz Frame rate : 46.875 FPS (1024 SPF) Compression mode : Lossy Delay relative to video : -67 ms Title : simple_aac_recording Default : Yes Forced : No
— Reply to this email directly, view it on GitHub https://github.com/mifi/lossless-cut/issues/126#issuecomment-1264410414, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXECBFCA5R3EN2LUSSVMWJDWBBPJJANCNFSM4GWMKI2A . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Is this supposed to be working? I'm trying to smart cut a small segment but I'm only getting an audio output and not video
@derickso see my OP. try with different file with a different codec (like h264) and see if it works
Where is the option to Smart Cut?
Thanks
I'm having the same issue as flagg19 with the latest release. Using ffmpeg directly works
Is it possible to have the re-encode be lossless? Every time I using it, the re-encode is really low quality.
Is it possible to have the re-encode be lossless? Every time I using it, the re-encode is really low quality.
No, re-encode can not be lossless for most codecs. However if you're seeing really low quality on the re-encoded part, maybe there is something wrong with the code that detects bit rate from the input: https://github.com/mifi/lossless-cut/blob/125112e6c099aa930737308e4dd00e086da9be53/src/smartcut.js#L50
in your dev tools do you see the warning message Unable to detect input bitrate
?
No, re-encode can not be lossless for most codecs.
Wouldn't crf 0 mean lossless? Or at least close enough to lossless?
in your dev tools do you see the warning message
Unable to detect input bitrate
?
My mistake, just tried it with a different file and I see the Unable to detect input bitrate
error.
Wouldn't crf 0 mean lossless? Or at least close enough to lossless?
close to lossless yes, but also very high bit rate. I imagine it could cause problems if the bitrate of the re-encoded part is much higher than the rest of the video. that's why the code tries to match the bitrate to the existing video's bitrate.
maybe the ffprobe-reported bit rate of your video stream is wrong (too low), and that's why you're getting the low quality encode. Not sure what's the best way to solve it
Add a way to override the re-encode bitrate in the settings? Or a default lower bound could be calculated from file format & image size?
Where is the option to Smart Cut?
Thanks
Where is the option to Smart Cut?
Thanks
It shows up in the Export screen:
in your dev tools do you see the warning message
Unable to detect input bitrate
?
Sorry, made a mistake, I do have this error. I thought it appears when the video was added not when exporting, my bad :laughing:
smartcut.js:52 Unable to detect input bitrate
py @ smartcut.js:52
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
(anonymous) @ useFfmpegOperations.js:369
(anonymous) @ index.js:57
await in (anonymous) (async)
m @ index.js:54
(anonymous) @ index.js:59
await in (anonymous) (async)
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
m @ index.js:54
(anonymous) @ index.js:59
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
m @ index.js:54
(anonymous) @ index.js:59
processTicksAndRejections @ node:internal/process/task_queues:96
await in processTicksAndRejections (async)
m @ index.js:54
(anonymous) @ index.js:59
await in (anonymous) (async)
m @ index.js:54
(anonymous) @ index.js:74
e.exports @ index.js:12
(anonymous) @ useFfmpegOperations.js:436
await in (anonymous) (async)
(anonymous) @ App.jsx:1297
onClick @ ExportConfirm.jsx:242
Pe @ react-dom.production.min.js:54
Ge @ react-dom.production.min.js:54
(anonymous) @ react-dom.production.min.js:55
Fr @ react-dom.production.min.js:105
Br @ react-dom.production.min.js:106
(anonymous) @ react-dom.production.min.js:117
cc @ react-dom.production.min.js:274
Re @ react-dom.production.min.js:52
Yr @ react-dom.production.min.js:109
Wt @ react-dom.production.min.js:74
Ht @ react-dom.production.min.js:73
After cutting several hundreds of h.264 videos with smart cut, I noticed that an average of over 50% of them does not work very well.
I thought I know the basic workflow when the starting point is not a keyframe:
This process has two issues:
Issue 1 is not really a big deal. My samples are almost always key-framed per 5 seconds, and 5% of my time I need to cut a very small piece from within the 5-second range. I can workaround this issue by simply cutting a range from a keyframe to the next keyframe, then manually cut and re-encode the range I need with raw ffmpeg
commandline.
Issue 2 is what annoys me the most. I have no idea what is happening. I could only guess that probably the ending time of the re-encode segment is not accurate enough. It does not always happen, though.
I hope this isn't related, but I'd thought I should share it: The video may have a bad timecode (a decimal framerate that isn't precise): https://blog.frame.io/2017/07/17/timecode-and-frame-rates/. Example:
Other interesting notes from the article:
Hello guys, I'm working since many years in a company that provide equipment made to generate Live TV, especially in TS output format (Sat, Terrestrial, IPTV, ...). So I know this format quite well... ;) I was an audio engineer, now working in the Sales Engineering department.
I'm a newbie on LossLessCut, that I start using to edit my Terrestrial movie recordings. LossLessCut + SmartCut feature is really a great combination. Many thanks @mifi for working on this !
When I read @JokerQyou issue report, something immediately pops-up in my mind : as you know, a live TS stream is made of successive video and audio frames, but these frames have generally not the same duration, so we could say they are "keyframed" at different (asynchronous) positions. As a result, when a video KeyFrame is selected on LossLessCut for cut/merge there's indeed high chances that the transition occurs inside an audio frame. A common result is that when you cut a file, a portion of the segment-to-be-removed remains in the start/end audio frame. Another consequence is that "gluing" two audio packets will cause audio "glitches" at playback, as they contain unwanted audio samples.
@mifi, maybe you already know this. Do you have implemented a strategy to manage "portions" of audio frames at cutting points ?
Again, many thanks, Best regards, and Happy New Year 2023 !
I'm not aware of how exactly this works. And i'm not aware how ffmpeg implements cutting when it comes to this TS issue, nor how to work around it. What if you remux the TS to something else like MP4 or MKV? Does the glueing issue go away then?
How is ffmpeg even able to losslessly cut a video+audio file if the audio can't be split at a video keyframe? This question seems tangentially related but it's only just crossed my mind after years of using LosslessCut...
Do the common encoders force the audio to be separable at video keyframes?
Correct me if I'm wrong but I think audio units (keyframe intervals) are much shorter than video, so it generally works out, but there might be some glitches as described above when merging two such cuts?
Also I think ffmpeg will offset the timestamps of the resulting (cut) audio/video streams to make sure they match up correctly. (e.g. to make sure the player will delay or advance the audio by a few ms when playing back)
Why does Smart Cut change the framerate to variable when original is constant 60 fps?
Smart cut: Frame rate mode : Variable Frame rate : 59.421 FPS Minimum frame rate : 14.925 FPS Maximum frame rate : 60.000 FPS Original frame rate : 60.000 FPS
Non-smart cut: Frame rate mode : Constant Frame rate : 60.000 FPS
This seems to happen with every clip. I've seen it report a 50 fps video as 250fps and I've even seen in metadata it claiming to be 1.5 million fps. This tends to make advancing frame by frame backwards insanely buggy, atleast in MPC-HC. Like with the 50 fps becoming 250, when skipping frame by frame backwards, it should go 20ms but instead does 4ms, because it really thinks it's 250 fps. But only when skipping backwards for some reason, forward still goes 20ms.
Smart Cut also seems to often repeat a section of the video for some reason instead of doing what it's supposed to, but the repeated section is often also significantly lower quality. Also even when that bug doesn't happen, Smart Cut is very often much lower quality than the parts within the keyframes. Please give us an option like Smurfix asked https://github.com/mifi/lossless-cut/issues/126#issuecomment-1347939349 Or atleast give us an option to set CRF manually, because whatever math Smart Cut is doing isn't working out. Nor should it try to match the bitrate, because a re-encode will always have lower quality unless you increase the bitrate.
smart cut uses ffprobe to detect the fps it will use when encode. you could try to run ffprobe and see which fps it reports for your file. Maybe when detecting bitrate, we should slightly increase the smart cut encoded bitrate to counteract the loss of quality when re-encoding. I agree it also makes sense to allow customising the bit rate of smart cut
May I ask why does it detect the bitrate of some files but not others? I've tried smart cut on a lot of different videos but its always unsuccessful when detecting the bitrate of the file and the re-encoded part is always lower in quality.
if you can provide the text from "report an error" in the help menu, then i can look into it
Thanks. It seems that your file is missing the bit_rate
metadata in the video stream. This is why you're getting the error.
We fallback to estimating bitrate based on file size, but it seems that the estimate could be too low, see comment above: https://github.com/mifi/lossless-cut/issues/126#issuecomment-1602266688
could you try to open your file in another tool like for example MediaInfo and see if it reports a bitrate for the video stream? if so, maybe it's an issue with ffprobe
Of course.
I noticed in the logs that it does show bitrate
"mainFileFormatData": {
"filename": "/run/media/metabox/bcbf4852-097a-4fc3-9106-3b9e7fdae001/yt-dlp/[OZC-Live]OOO · Den-O · All Riders - Let's Go Kamen Riders [720p][NAFmux] [A7564FE8].mkv",
"nb_streams": 7,
"nb_programs": 0,
"format_name": "matroska,webm",
"format_long_name": "Matroska / WebM",
"start_time": "0.000000",
"duration": "5585.664000",
"size": "2664904698",
"bit_rate": "3816777",
"probe_score": 100,
"tags": {
"encoder": "libebml v1.4.2 + libmatroska v1.6.4",
"creation_time": "2022-03-04T20:43:10.000000Z"
}
Yes, but that’s the bitrate of the whole file, not the video stream. (Probably same as dividing file size by duration). If a file has multiple streams (esp video), it will be incorrect.
could you try ffprobe version 6 on your file and see if it is able to fetch the bit rate? Something like ffprobe -show_streams file.mkv
Sure thing. Using the system ffprobe not the one included with losslesscut, it's Arch so it's up to date.
it seems that
bit_rate=N/A
max_bit_rate=N/A
So I'm thinking this is a bug/limitation in ffmpeg (ffprobe). Seems other people are having the same issue:
Let's fork this discussion into a separate issue that I created now: #1649
I have to say that my first experience with Lossless Cut has been quite rough because of this and other UX issues.
At this point I gave up and just gave the raw file to my stakeholder, apologizing for the extra seconds.
@astrojuanlu I believe most of these issues are not related to the Smart Cut feature (which is experimental).
Please read https://github.com/mifi/lossless-cut/blob/master/issues.md and if you're still having issues, then you may submit a new discussion or issue with more of the requested details about your system and reproduction steps, to help me help you.
On macOS, I run into the issue that the smart cut feature works only if I remux the recording in OBS from mkv to mp4. This is fine, though it would be nice if it would just work with MKVs. Right now I'm not using any NKV-specific functionality such as multiple video or audio tracks, though maybe I want to do that in the future. With the MKV file I run into the issue of degraded video quality, and that the cut is not done correctly.
I'm using the "smart cut" a lot, with very good result. Except when using it on a video which is x265 encoded, then the result is distorted. Would it be possible to support the "smart cut" also for x265 encoded video's ?
smart cut does work on some x265 videos, but I don't know which codec parameter combinations are causing it to fail for some files, while others are fine. it's a quite complex issue.
Hello Mikael,
Thanks for your response :-) Until now I assumed that smartcut was not supported for x265 video's at all. Wrong assumption ... I will check the generated ffmpeg commands when it fails, and then experiment to see if I can find a potential solution. I'll let you know when I think I find something useful.
kind regards,
Bart De Ceulaer
On donderdag 17 augustus 2023 16:33:15 CEST Mikael Finstad wrote:
smart cut does work on some x265 videos, but I don't know which codec parameter combinations are causing it to fail for some files, while others are fine. it's a quite complex issue.
Unfortunately Smart Cut fails also on H264 files.
Sample: https://anonymfile.com/437/sample.mkv First 8 sec of original file: https://anonymfile.com/3aa/sampleorg.mkv
This is really strange: It starts with the correct frame, then a part of the cut out frames is shown and then it starts again. Goal was to cut out the SC ad.
A also cut something at the end. There it seems to include one frame too much. I set the cut out at the last frame before the Sony logo and that was still included.
VidCutter can handle the file but will only cut one audio.
So far, EVERY file failed with smartcut. It seems, the cut out segment is one keyframe too early.
I usually cut something at the beginning. So the reencoded part is placed first, then there is a part of one keyframe to the next from the part that should have been cut out and then it resumes normally. I can cut out the additional part in AviDemux but I would like to save that step.
The issue I have may be a little odd, so let me first give you a screenshot of the timeline:
(Don't mind the 204, I deleted the segment previously to see if that helps and then used "Fill gaps")
As you can see I need to cut between the two keyframes. The waveform is showing it pretty clear, there's a small piece of silence and I want/need to cut on that. The exported video (with smart cut of course) starts at the exact right time, i.e. the video starts quiet. Perfect! But oh wait, it's not, because at Keyframe 2 it starts inserting everything from Keyframe 1 onwards, effectively inserting the cut-away part and duplicating the wanted part. So the video goes:
smart-cut to keyframe 2 | keyframe 1-2 | keyframe 2-end segment
I'm not sure how to handle this :thinking:
Upon further experimenting I noticed something more. So I split Segment 19 1 frame after the keyframe (as per known issues.. shifting segments and whatnot), and then exported 19 and (the newly created) 20. Theoretically 19 should only contain the cut part, correct? But what it's doing is the same as I had in the full video: it inserts from the smart cut to keyframe 2 (now end of the segment), and then inserts everything from Keyframe 1 to 2 again :thinking: I'm not sure why it's inserting anything after the end of the segment at all :thinking:
Segment 19 export looks like this:
Segment 1 is what smart cut produced, Segment 2 is everything from Keyframe 1 to 2
Workaround:
... but actually not really because for some reason this produces 2 black frames at the cut point (music keeps going), and when playing back (in mpv) it actually seems even longer then that :disappointed: I should mention the "smart" portion of the cut also has visibly degraded quality even in the full Segment 19 file :/
Seems like the same issue I described the two entries before.
I just found out that even if I remove the duplicate part we will miss one frame. So in EVERY cut mode we have an off-by-one error.
Investigate using
aomav1
insteadaomav1
is already the default in ffmpeg when encoding as-c:v av1
using a real world section I trimmed earlier today that would have used smart cut (103 frames long @ 4K 8000kb/s) this is the encode times on my 5900x:
aomav1
: 19m28s @ 98.4953VMAFaomav1
-usage realtime
: 5s @ 93.8847VMAFaomav1
-cpu-used 8
: 31s @ 98.1873VMAFlibsvtav1
(no custom arguments): 8s @ 96.0291VMAFWhen av1 is detected when using smart cut it should either apply -cpu-used 8
to increase speed by 37 times or set the encoder to be libsvtav1
for an increase of 146 times
you could use -usage realtime
for an even faster encode but the quality is pretty large compared to the other two options
I'm using the latest development version of SmartCut and it works well, but I notice that the ffmpeg command to make the -smartcut-segment-encode
file does not appear in Last ffmpeg commands
, even though the commands to make -smartcut-segment-copy
and then concatenate the two files afterward do appear.
I'm also using smart cut with av1 and it's very slow. It should not take multiple minutes to encode (on a Ryzen 5700X) what adds up to a few seconds at most. Is there a way to manually change the encoder used in smart cut?
I'm also using smart cut with av1 and it's very slow. It should not take multiple minutes to encode (on a Ryzen 5700X) what adds up to a few seconds at most. Is there a way to manually change the encoder used in smart cut?
Even if you were to import the source file into Handbrake and select those frames/seconds to encode, you might find it takes a similarly long time. It doesn't just encode the selected portion; it moves through the file to that portion to find it. That is, it doesn't just jump to it and start encoding, but rather works its way to it. As for changing the encoder, I'd imagine it just automatically uses the same one the source file is encoded in, as using another would cause incompatibility, though I have no idea how it chooses the various settings for the encode beyond that. Given the chance to allow the user to customize this, that would provide the ability for using incompatible settings (not saying this shouldn't be done, just that it requires caution, and I've discussed this in another issue). I'd suggest importing your source file into Handbrake, selecting the same codec and as similar as possible quality settings as the source file, and having it encode the same portion of the file that you're trying to do with LC (i.e. the bit(s) at the beginning/end of the clip(s) you're editing. I'd wager that if you do this for the beginning and end of each clip, it's going to take a while, as for each one it's going to seek through the video up to that point before actually starting to encode. And while I can't say for sure, as obviously LC and HB are two different programs, I'm guessing they both use similar mechanisms to perform these operations, and that's likely why encoding a few pieces that are only a second or two, which seems like it should be very quick, are taking a while, because it's not the actual encoding that's taking so much time, but the encoder moving through the file to get to that point (or those points).
Well, I can see through task manager that a lot of the time of the total video processing is just disk operations which makes sense as LC is making a copy of a large video file, but I can also see when the disk operations go down to 0% and the CPU usage goes up which is where the smart cut takes place. When I say it takes too long I mean just the smart cut portion, as the rest is justified. I also tested it with shorter video files and the smart cut takes many times longer than running the entire video through handbrake AV1-SVT encoding (although I don't know if the handbrake settings are comparable, but still). I tested the same 10 second file converted with Handbrake from AV1 to 264/265 too. Smart cut goes through 264/265 files in like a second or two but takes minutes on AV1.
I'm also using smart cut with av1 and it's very slow. It should not take multiple minutes to encode (on a Ryzen 5700X) what adds up to a few seconds at most. Is there a way to manually change the encoder used in smart cut?
This is an issue I have brought up as well, Lossless cut uses whatever the default av1 implementation of ffmpeg is, this happens to be the original aomav1
encoder and that encoders default settings are molasses slow,
I've suggested using libsvtav1
in it's place because of the speed increade.
See my previous comment here for some numbers.
Hopefully this can be implemented some time soon as it would increase the speed of these encodings by a good amount especially for much slower machines
I also tested it with shorter video files and the smart cut takes many times longer than running the entire video through handbrake AV1-SVT encoding
And this is with just one clip? Even with that, it's encoding two pieces, and for each one it has to run through the file up to that point and then encode it, so for each clip it has to do this twice, and that will take more time. But if you're saying it takes that much longer to do just one clip/segment vs encoding the entire video in HB, then that does sound wrong. I wonder if it's LC or ffmpeg (or an external encoder?) taking that long. I suppose you could watch the output files and see how long each one takes to complete and see what part of the process is so slow.
We cannot cut between keyframes, it's a technical limitation of modern video codecs. So ffmpeg will choose the nearest keyframe, which will not be the exact time you requested.
Might be able to use avcut for h264 although it is experimental. See https://github.com/mifi/lossless-cut/issues/372#issuecomment-761844667
See also discussion in #13
Update: Have made an initial implementation of this. This experimental feature will re-encode the part of the video from the cutpoint until the next keyframe in order to attempt to make a 100% accurate cut while losslessly copying the rest of the segment.
VideoRedo
VideoRedo is a now-defunct software that had feature overlap with LosslessCut.
Smart Media Cutter
Recently built in order to replace VideoRedo
They open sourced their smart cutting algorithm, could take inspiration from it: https://github.com/skeskinen/smartcut
Remaining issues
Inaccurate seeking
Seeking is not always accurate, causing glitches and/or jumps in the stitch points. This is often because I haven't found a way to consistently seek to and cut on an exact frame. Sometimes it could be caused by the "audio samples" problem below. If you want to experiment, you can try to remove the audio track and cut only video to see if it makes a difference.
Audio samples problem
Cut time accuracy/glitches when audio samples are large? (try without audio and see if it makes a difference). A workaround seems to be to cut audio/video separately and then merge them, with the tradeoff of potential audio/video de-sync:
subtitles
Other improvements
Cannot find any keyframe after the desired start cut point
, see #https://github.com/mifi/lossless-cut/issues/1190#issuecomment-2027227599Done
aomav1
insteadlibsvtav1
instead ofaomav1
(ffmpeg default) (codec needs to compiled for mac in ffmpeg-build-script) #1825Limitations
size/duration
(may be wrong)