Monday, December 8, 2008

QuickTime Player in Internet Explorer

I've recently been working on getting QuickTime player to work in Internet Explorer (and Firefox and Safari), and as you might expect there are some catches to getting a rich QuickTime UI to work with IE. By rich QuickTime UI, I mean a UI you've built yourself that embeds a QuickTime window. Furthermore, to keep your UI updated to the state of the player, you're using DOM events. I thought I'd do a brain dump to refresh my own memory and potentially help some others. So here we go:

Question 1: Why don't my DOM events work in Internet Explorer?

Answer: They work, but they don't work properly, that's for sure. The Apple documentation provides an example the just doesn't work. QuickTime DOM events won't get sent unless you add a [relatively simple] hack, the essence of which requires you to reload the clip you're playing. Pseudocode looks like this (in javascript):

load clip in QuickTime
wait until plugin status is loaded (or complete )

// begin hack
// end hack

So essentially, you have to generate your object/embed code, load the quicktime player once (by setting innerHTML somewhere), and then do a setURL with the same clip before registering for DOM Events. If you don't do the setURL, you won't get DOM events.

Note that for other browsers you don't have to do this. So I suggest you wrap this code up in an if(IE) block.

Question 2: With the hack above (in IE), why does my app hang when loading long (15 minutes plus) clips?

Answer: Your app is hanging because the QuickTime plugin didn't get time to stabilize before you called setURL. I didn't find a way around this, but a solid solution is to use a dummy clip (1 or 2 seconds of black) that you load up before loading your real clip. Once you've got DOM events registered, you can use setURL to switch to other clips. Pseudocode looks something like this:

function initQuickTime()
[code from answer 1 loading a dummy clip]

function loadClip(clip)

And you're good to go. setURL can be used from here on in if you need to switch clips.

Other Notes:

1. You can't resize the QuickTime window without reloading the clip. I really want to be wrong about this, but if you need to change the size of the video window, you have to redo your object/embed code. Kind of a pain, but resizing has to be done almost never, so it's workable.

2. If you're writing debug code, make sure all your test clips are on your http server. I made this mistake and wasted a couple hours. If, for example, you're working my pseudocode in question 2 and your dummy clip is on your PC, but your app accesses clips on an http server somewhere, it just won't work. QuickTime player has some initialization in it that defaults to either local files or http files (I don't really know the details).

That's about it. Overall I really like QuickTime player. Compared to the directshow work I've done, it's a lot easier to use. There are a lot less corner cases you have to deal with (if you're trying to get frame accuracy, for example). The compatibility issues in diffferent browsers come with the turf, and they're realtively easy to deal with elegantly if you know what you're up against.


jalpino said...

Thank you so much for posting this!! I've been banging my ahead against the wall for a long time trying to understand why QT in IE wouldn't post DOM events using my stream from Darwin. Your post was a life saver.

Anonymous said...

Good post

website design nyc

SB said...

I struggled with this for a long time as well. Although your solution *does* work, as you said its pretty ugly and there is an easier solution. The actual problem here isn't that IE doesn't post DOM events correctly, its that IE does some funky stuff with them until the page load is complete.

With Firefox, Safari, etc. they will start firing events as soon as they occur and the listeners are ready to go.

What I found with IE is that it doesn't start firing the events (or holds on to them or something) until the page load is complete. I was able to use identical code on all browsers by moving the registering of event listeners into a function that gets called by the body's onload handler. So rather than the following, which doesn't work in IE:

<object src="">
<script type="text/javascript">

I did the following, which works in IE:

<body onload="registerEvents()">
<object src="">

Luke Rymarz said...


Wow, very cool! That's a much better solution.