So a while back, you might remember me bitching about AV Foundation and presenting as my use-case for where the AVF-based QuickTime Player X comes up lacking, the technique by which I pull individual episode files out of DVD rips that produce a single two-hour title.

After my epic bitch-fest, I wrote:

But I also have a list on my whiteboard of fun projects I’m saving up to do as livestream code-alongs someday, and one is an AV Foundation based episode-splitter that would replace my cut-copy-paste routine from way above. Because really, it would be pretty simple to write an app that just lets me razor-slice the big file at each episode break, and then mass export them into separate files using some programmatic file-numbering system.

So, since writing that, I’ve allowed new anime DVDs to pile up without using my old QuickTime copy-and-paste technique, because I’ve wanted to actually write this app. Which means that True Tears and Lupin the Third: The Woman Called Fujiko Mine are sitting unwatched on the shelf, because they’re just DVDs and not .m4v‘s compatible with iPad and Apple TV. Not cool! I need my tragic schoolgirls and super sexy thieves!

So, on and off over the last week, I wrote DVDivvy

DVDivvy splitting up a ripped title

So, the workflow of this OS X 10.8 app is:

  1. Use the Open menu to choose a long video file, presumably an m4v ripped from a DVD.
  2. Play the video or use the scrubber to move around and find the episode breaks. There are also frame forward/back buttons, and the left- and right-arrow keys also do frame advance, which in turn means they work with the jog wheel on the Bella USA video editing keyboards.
  3. When you’re on an episode break, click “add slice” to split up the output at this point. The table on the right shows all the episodes you’ve split up by slice time and duration. You can also remove slices (but can’t edit. Also, deleting the last slice crashes, sorry).
  4. Use the “Destination” button to choose an output directory.
  5. Click “Export” to divvy up the episodes at the slice points into this directory. They’ll maintain the original filename and type, with “-part00” (etc.) appended to their file names. This uses pass-through export, so the audio and video data is just copied over, not re-encoded.

When you’re done, collect the -partNN files in the finder, drop ’em into iTunes, and tag away.

DVDivvy results folder

This is not at all polished, and I bet there’s lots of things I could add — and if anyone uses it, will probably ask to me add — but for about 8 hours on and off over the last week, it’s not bad.

Here’s the source code. License is CC0, i.e., no rights reserved. Use it as you see fit and don’t complain to me about it.

I’ve been doing lots of AV Foundation over the last couple months for a client, and in particular using CIImage filters to apply a series of effects (chroma keys, alpha masks, actual useful stuff!) to captured video, show it on the screen, and write it to a file, all in realtime. While I maybe should do a brain-dump-style blog on that, it’s more likely something I’ll just turn into a CocoaConf session for next year, perhaps called “Stupid Video Tricks”. This also might be particularly well-suited to teaching in a class format, so watch for that (even if you don’t come to CocoaConf, I”ll eventually post the session/class code here).

What I take away from this project is that I’ve personally pretty much figured out my way around AV Foundation, though there are still a few traps that result from badly unfortunate naming choices — AVComposition for a programmatically-assembled asset leads to confusion with the completely unrelated AVVideoComposition, which describes video compositing via an array of AVVideoCompositionLayerInstructions that include opacity ramps, crops, affine transforms, etc., and which in turn don’t have anything to do with AVPlayerLayer, the CALayer subclass that you use to present a playing movie.

See, I know my way around this stuff, but the class naming is borderline sadistic, and I’ve got nothing but sympathy for the newcomer to this framework.

The other thing I found tricky this time is dealing with the Core Media structs CMTime and CMTimeRange. Not because they’re problematic, per se, but because of the problems of mixing C structs with Automatic Reference Counting (ARC) code. In a lot of my Core Audio work, I could just mentally switch and write methods or entire classes in a C idiom or an Obj-C idiom, but AV Foundation wants you to pass these C structs around in your Obj-C code, and it can become difficult to hold on to them in things like collections. Probably the best default approach is to just make heavy use of the AVTime.h category on NSValue that gives you valueWithTime: / timeValue and so forth.

At one point in DVDivvy, I needed to pass a locally-created array of CMTimeRanges to another class, and realized I couldn’t just pass the array (pass-by-reference), because the class needed to live long enough to do all the exports, but the array was on the stack and would die as soon as the method passed off its work to the SNFExportDivvy class and the array went out of scope. So I did a stupid thing where I copied that off to an ivar (because you can’t have a C array of structs as a property in ARC, IIRC), and it’s kind of ugly and stupid, so I feel like I have some more thinking to do to come up with idioms that make me feel like I’m doing right by both Obj-C and C.

But anyways, it works now, so I’ve got some DVD rips to slice up and tag and watch. Oh, and I told myself I could buy the True Tears opening song on iTunes when I got this done, so I need to go do that next.

Happy slicing and divvying, everyone.

Comments (2)

  1. BTW, here’s the known bug list that may or may not get addressed (the link in this blog will always go to the latest source, which is just a on my Dropbox)

    Known bugs to fix:
    * Deleting last segment raises exception
    * Table should clear when a different movie is opened
    * Destination button’s NSSavePanel sheet’s directory dialog button shouldn’t say “Export” (suggests that export will begin immediately)
    * On window resize, would be more useful for preview to stretch horizontally than table

  2. Now on GitHub as invalidstream / dvdivvy. Clone away, and send me pull requests if you fix something and want to share.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.