Add QuickTime support to cappuccino

Open source really rocks. The cappuccino web framework does not support the QuickTime plugin ? Well, write your first cappuccino component. It is really easy.

CPQuickTimeMovie : storing an url to a QuickTime movie

The class CPQuickTimeMovie is based on CPFlashMovie, just remplace "Flash" with "QuickTime". It simply holds a reference to the url where the QuickTime movie (normal movie or VR object) is stored. You can use relative url on your site (for example: var aFileName = [[CPBundle mainBundle] pathForResource:@"Biot01_3000.mov"]) or use a full url like : "http://www.nice-panorama.com/Cannes/Cannes17_3000.mov".

@implementation CPQuickTimeMovie : CPObject { CPString _fileName; } + (id)quickTimeMovieWithFile:(CPString)aFileName { return [[self alloc] initWithFile:aFileName]; } - (id)initWithFile:(CPString)aFileName { self = [super init]; if (self) _fileName = aFileName; return self; } @end

CPQuickTimeView : displaying a QuickTime movie in a Cappuccino view

The class CPQuickTimeView is based on CPFlashMovie. It holds a reference to a CPQuickTimeMovie. As you can see, we will have to create a DOM tree of nodes : an "object" node, multiple "param" nodes and a "embed" node.

@implementation CPQuickTimeView : CPView { CPQuickTimeMovie _quickTimeMovie; DOMElement _DOMEmbedElement; DOMElement _DOMMParamElement; DOMElement _DOMObjectElement; } @end

This is done in initWithFrame:. We retain a reference to some nodes in the tree since we will have to change them later.

- (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; if (self) { _DOMObjectElement = document.createElement("object"); _DOMParamElement = document.createElement("param"); _DOMObjectElement.appendChild(_DOMParamElement); _DOMEmbedElement = document.createElement("embed"); _DOMObjectElement.appendChild(_DOMEmbedElement); _DOMElement.appendChild(_DOMObjectElement); } return self; }

To change the attributes of node, you have two options.

_DOMEmbedElement.type = "video/quicktime"; _DOMEmbedElement.setAttribute("controller", "false");

Now, we are ready to modify the DOM tree to store reference to the url to the QuickTime movie. This is done in setQuickTimeMovie:.

- (void)setQuickTimeMovie:(CPQuickTimeMovie)aQuickTimeMovie { if (_quickTimeMovie == aQuickTimeMovie) return; _quickTimeMovie = aQuickTimeMovie; _DOMParamElement.value = aQuickTimeMovie._fileName; if (_DOMEmbedElement) _DOMEmbedElement.src = aQuickTimeMovie._fileName; } - (CPQuickTimeMovie)quickTimeMovie { return _quickTimeMovie; }

In order to response to mouse drag, mouse down or mouse up events, we need to add these magical methods. Well don't ask me why. You can send your questions to the developpers at 280 North !

- (void)mouseDragged:(CPEvent)anEvent { [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; } - (void)mouseDown:(CPEvent)anEvent { [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; } - (void)mouseUp:(CPEvent)anEvent { [[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES]; }

CAQuickTimeLayer : displaying a QuickTime movie in a Cappuccino layer

Well cappuccino offers a CAFlashLayer, so I had to write a CAQuickTimeLayer too. I wrote also a CPView subclass to test it (you can found the source in the zip file). The QuickTime VR movie does not response very well to user clics and drag & drop in Safari 4 beta (but it is working fine with either FireFox or Opera). With Safari 4 beta, I discovered than we can use the two fingers movement on the trackpad of latest Macintosh to move the QuickTime VR movie (this is not yet supported by Firefox or Opera). We can hope than the QuickTime VR bug in Safari 4.0 beta (only in CAQuickTimeLayer) will be removed from the final version.

The code of CAQuickTimeLayer is simple, we just write our html fragment as we would have done it in a normal html page.

- (void)setQuickTimeMovie:(CPQuickTimeMovie)aQuickTimeMovie { if (_quickTimeMovie == aQuickTimeMovie) return; _quickTimeMovie = aQuickTimeMovie; var html = "<object width = \"100%\" height = \"100%\" classid = \"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B%\" codebase = \"http://www.apple.com/qtactivex/qtplugin.cab\">"; html += "<param name = \"src\" value = \"" + aQuickTimeMovie._fileName + "\"></param>"; html += "<embed src = \"" + aQuickTimeMovie._fileName + "\" type = \"video/quicktime\""; html += " pluginspace = \"http://www.apple.com/quicktime/download/index.html\""; html += " width = \"100%\" height = \"100%\"></embed>"; html += "</object>"; _DOMElement.innerHTML = html; }

I hope that you found this tutorial interresting. You know now how to add support to your favorite plugin to cappuccino web framework.

If you'd like to see the complete code listing from the tutorial, you can download it all in a single file: Tutorial-QuickTime.zip. The web application is available online: Tutorial-QuickTime

Copyright © 2009 - Philippe Laval. Cappuccino and Objective-J are registered Trademarks of 280 North.