QtzRendang in action

Announcing QtzRendang, a little utility app for rendering Quartz Compositions to movie files. I cobbled this together from example code for my own purposes, and since I couldn't find anything on the web. "My own purposes" typically involve rendering a loopy composition to a six or seven minute movie to make simple but effective videos for Cartoon Beats releases.

By the way, there is another app for this purpose developed by the Kineme crew - QuartzCrystal - which supports spatial and temporal oversampling to reduce temporal and visual jagginess. At US$18 this is a great little app, but as I'm a bit of a nerd and a cheapskate, and there wasn't an open source solution, I decided it was worth writing QtzRendang.

CoGe is another great project on Google code. It's an open source visualisation/VJ mixer/live sequencer.

Back to QtzRendang


Drag & drop a composition, specify frame resolution, duration, and frame rate & output filename. Optionally tweak composition parameters, then click render.

Why is it called QtzRendang? Well it renders .qtz files to movies, and the instant noodles I had that week were rendang flavour. Rendang is a slow-cooked Indonesian dish which seems like it would be pretty yum. I've never had it.

Any questions about the software itself please feel free to ask in the comments.
It seemed like it should be easy, and it was, but finding out how was hard. So I am posting what I did here in the hope that the next person wanting to do it finds the info they need here.

What I wanted to do


I had a Cocoa document-based app. I.e. I had followed my nose with Cocoa, and ended up with an app that supported multiple documents. Documents are represented by in subclass of NSDocument called MyDocument.

I wanted to support viewing and changing properties of the document from AppleScript.

Note that I wanted to support 10.5+, so the techniques here may not be appropriate for older versions.

How I ended up getting it working


  1. Specify things in the app's Info.plist:
    NSAppleSriptEnabled = YES

    OSAScriptingDefinition = MyApp.sdef


  2. Made an sdef file, which includes all the framework supplied stuff, and that MyDocument extends the framework document, and has a property, refered to by the key numBananas:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">

    <!-- declare the namespace for using XInclude so we can include the standard suite -->
    <dictionary xmlns:xi="http://www.w3.org/2003/XInclude">

    <!-- use XInclude to include the standard suite -->
    <xi:include href="file:///System/Library/ScriptingDefinitions/CocoaStandard.sdef" xpointer="xpointer(/dictionary/suite)"/>

    <suite name="MyApp Suite" code="LfMS" description="MyApp application specific scripting facilities.">

    <class-extension extends="document" code="docu">
    <cocoa class="MyDocument"/>
    <property name="number of bananas" code="Bana" type="integer" access="rw" description="The number of bananas in this document" >
    <cocoa key="numBananas"/>
    </property>
    </class-extension>

    </suite>

    </dictionary>

  3. Implement KVC accessors for the property. These looked (sortof) like:
    -(NSNumber*)numBananas
    {
    return [NSNumber numberWithInt:bananas];
    }

    -(void)setNumBananas:(NSNumber*)value
    {
    bananas = [value intValue];
    }



This was all that it took, and now I can enumerate all the docs, set their number of channels etc etc.

Apologies to all my regular readers if this is slightly outside your sphere of interest!