www.vitenka.com | ToothyWiki | Vitenka | RecentChanges | Login | Webcomic I'm trying to strip adverts from recorded TV. Recompressing to a smaller file size would be nice too, but isn't essential. (Except it kinda is)
Comskip is the first half of the job. It does a great job of finding commercial breaks, and has a variety of output formats. The most useful seems to be 'edl'. Mplayer (and npvr) read this natively, and it all just works. It aint perfect, but it tends to err on the side of accepting adverts rather than cutting content; and it's pretty damn good. The automatic mode tries lots of different things to get a spam score, and works well. I'm most impressed by its scanning the video to find a watermark, and using the absence of that as an indicator of an ad-break. But it aint erfect (see later complaint about keyfreames)
Except I want to output stripped files so that other clients (i.e. my TV) can play advertless too.
First hurdle: _only_ mencoder appears to accept skip lists. I can't just throw it at handbrake and say 'done'. (And while I'm ranting, handbrake cli? Doesn't seem to accept the custom profiles I created in the gui)
So mencoder. Command option hell. Horrible! Problems I've hit:
My source files tend to have multiple audio tracks. There isn't an obvious and easy way to specify "The main one, please"; and left to its own devices it'll pick the wrong one half the time. You can at least use ffprobe to spit out json (ffprobe -show_streams -print_format json -select_streams a); parse that to find the one you want,and specify "-aid" to tell mencoder the audio stream you want. Simples?
You don't seem to be able to combine "-aid" and "-edl" options. The edl is silently ignored if you try. So you have to do two passes; first strip down to the single audio track, then apply the edl. (Luckily, "-oac copy -ovc copy -aid nnn" is really fast.)
So we're done? Not... quite. Apply the skip list on a second pass with oac copy/ovc copy? Kiiinda sorta works. Ish. Big macroblocking mess ups either side of the cut points, because of course you're just discarding raw rame data, and the cut isn't going to be at a keyframe. (Why the hell isn't the cut at a keyframe? SURELY the scene change to an ad break causes a key frame? COMSKIP!)
So - the obvious thing it to re-encode. Decode the otput to raw, skip, encode it back up again - should be seamless. And since I'm already re-encoding, lets output as something a bit more compressed.
Well, that pass aint fast - down to about half-realtime. And... it breaks. Oh it breaks in so many ways. My favorite has to be "Error while writing frame." and "Too large number of skipped frames 103223 > 60000" No indication of what the error was, or how to fix it. No indication of why it's suddenly skiped masses of frames (it's not the skip list, that doesn't count for this counter)
Here's another one - if you redirect output to a file; it somehow pushes the log to the top of that file; rather than staying in place!
And hey; even with "-idx" it often stops without writing an index at all; so you can't seek, so I can't even quickly check by eye whether it actually wrote a sensible looking file! So that's yet ANOTHER pass, just to add the index.
Gah. I really don't want to write another wrapper executable; the net's full of them already, and they're all just "Hey, let's run ffmpeg and add our own bugs to it".
And, of course, none of these problems show up in my quick test encodes of 30s files. No, only when I actually encode the real 2hour files. ARGLEBLARGLEGRAH!