Web standards compliant Javascript Quicktime detect and embed

Due to the popularity of my FlashObject embed, I decided to create a helpful little Javascript file for doing detection and embedding QuickTime movies.

Embedding QuickTime movies in websites presents many of the same problems as embedding Flash. Since QuickTime relies on a third party plugin, your users will need to have this plugin installed before they can view your content. If they don’t have the plugin, they will be greeted by either an AcitveX install window (Internet Explorer) or an ugly ‘broken plugin’ image on other browsers. I prefer using Javascript to detect the presence of plugins because it gives you more control over what your users see when they visit your site. Most web browsers handle plugin installs terribly, often giving the user cryptic looking placeholders (broken puzzle pieces) or strange sounding legal notices on ActiveX install dialogs (of which people may have been trained to always say ‘no’ to since the same dialog box will often install spyware).

Anyway, enough chit-chat. On to the Javascript:

To use the QTObject embed, you simply create a new QTObject, add the parameters you want, and then write it to the page. The script will check to see whether the QuickTime plugin is available and write the embed code to the page or the alternate content if the user doesn’t have the required plugin. Here is an example of what a simple movie embed would look like (I used a fun little video I found floating around the Internet as a sample movie, but it can be any .jpg, .gif, .png, or even another .mov file.): (View Example)

var myQTObject = new QTObject("bushuncensored.mov", "bushfinger", "320", "255");
myQTObject.addParam("autostart", "false");
myQTObject.write();

In this example the ‘myQTObject.addParam()‘ isn’t needed, but it’s a nice addition that will keep the movie from starting before the user figures out what they are looking at.

The parameters from left to right are the path to the mov file, the ID of the mov file, the width, and then the height of the file. If you are showing the QuickTime controls, you need to add 15 pixels or so to the height of the movie or the controls will be pushed down and the user won’t be able to see them.

If you want to do some more advanced embedding, such as the method Apple uses on their QuickTime site, your code would look something like this: (View Example)

var myQTObject = new QTObject("bushplaceholder.jpg", "bushfinger", "320", "255");
myQTObject.addParam("href", "bushuncensored.mov");
myQTObject.addParam("target", "myself");
myQTObject.addParam("controller", "false");
myQTObject.write();

This uses a few extra parameters that allow you to use a placeholder image that will load in the place of your movie until the user clicks on it. Your movie would then load in the place of the image and start when it has loaded enough to start playing. You simply replace the mov source from the first example with your placeholder image (you remembered to add 15 pixels to the height of the image to account for the QuickTime controls, right?) and then an extra few parameters to tell the QuickTime embed where to find the real movie, the target QuickTime object, and finally telling it to hide the controls before the real movie loads.

There is also the option of redirecting the user to another page if there is no QuickTime plugin found by using this code: myQTObject.redirect = "upgradepage.html";, and there is a built in bypass of the detect script by including detectqt=false in the query string when you request the page. This link is included in the ‘upgrade’ notice so if for some reason a user has QuickTime installed but the Javascript detect fails, they can still attempt to view the QuickTime content.

Also, be sure you use this in combination with <noscript> tags just in case some of your users have Javascript disabled.

That’s it! Since it uses Javascript to create the embed and object tags, it will validate as XHTML 1.0 (strict or transitional). Please note that it will not work with pages sent as application/xhtml+xml since it uses innerHTML and document.write(). Another note: I’m not checking for the version of the QuickTime plugin installed, and I couldn’t find any older QuickTime players for testing, so I’m not sure how this will treat users who are using QuickTime 4 to view content that requires QuickTime 6. I seem to remember QuickTime having an auto-update feature or some built in notification if you need to upgrade, so I’m not too worried about it, but if anyone has some experience in this area, I’d love to hear how this embed method behaves under those circumstances.

I’ve tested this on IE 6, 5.0, 5.5 on PC, Firefox on Mac and PC, and Opera and Safari on Mac. It has worked great every time, but everyone knows there can always be little bugs that pop up, so if anyone finds something wrong with the code, let me know.

Download source and example files (1.09MB)

UPDATE (02-11-2005): Just fixed a few bugs – one that was giving problems if the user didin’t have QuickTime installed on Internet Explorer for PC, and adjusted the default Alternate text.

UPDATE (02-16-2005): Not sure how something like this slipped past, but Thiago found a little bug in the VB Script that was giving some problems in IE on a PC. The files have all been updated.

54 thoughts on “Web standards compliant Javascript Quicktime detect and embed

  1. Great use of javascript to embed AND detect. One question, i am going to try and implement this (when i get a chance to study it more)and add the ability to link to the external QT player. I’ve been searching without result for a way to be able to use an image link (with rollover) and launch a movie in the external player, while also opening a seperate page in an iframe. Before i started code mashing, i was wondering if you had any tips and or ideas?

    thanks for the code posted hear and any feedback if you want to give some.

  2. I’m not sure it’s possible to get a QuickTime movie to play in the standalone player from a website link. I know if you link directly to a movie, the browser will try to play it (usually as a movie in the center of the browser window), but if you want it to play in the external player, I think you need to download it and then open it using the player application.

  3. you can do it with the object tag by having a placeholder QT media file load in the page (like a button or a “cllick here” image) and giving it an href param that links to the target movie, with quicktime player as the target. eg.


    <param name="src" value="image.qtif" /> (a quicktime specific image format, but it can be any QT supports)
    <param name="href" value="movie.mov" />
    <param name="target" value="quicktimeplayer" />

  4. I must be missing something here. The embed tag is not a part of XHTML, but by putting the embed tag in a javascript, you are just fooling the validator into thinking it is valid. But the non-IE browsers are STILL executing an embed tag, it’s just in javascript instead of the html.
    Is it not possible to use an object tag for both IE and non-IE?

    Maybe something like this:

    QTObject.prototype.getHTML = function() {
    var qtHTML = "";

    if (navigator.plugins && navigator.plugins.length) { // Not IE browser
    qtHTML += '<object type="video/quicktime" data="' + this.mov +
    '" width="' + this.width + '" height="' + this.height +
    '" id="' + this.id + '">';

    // this.addParam("src", this.mov);
    if (this.getParamTags() != null) {qtHTML += this.getParamTags()};
    qtHTML += '</object>';
    }

    else { // IE browser
    qtHTML += '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" ' +
    'width="' + this.width + '" height="' + this.height +
    '" id="' + this.id + '">';
    this.addParam("src", this.mov);
    if (this.getParamTags() != null) {qtHTML += this.getParamTags()};
    qtHTML += '</object>';
    }
    return qtHTML;
    }

    Don’t know if that will work for all cases though.

  5. Hello Geoff,
    Thanks for posting this as it seems it will solve my problem. I have about eight pages
    with quicktime as primary conent on my site, which are not viewable to PC users.
    Can you recommend someone I can hire to re-code these?
    Thank you Thank you Thank you.

  6. Eric,

    Your’re right, it’s not really XHTML, in that it’s using Javascript (specifically innerHTML or document.write()) to write the embed tag to the page, so this will fail if you are sending your page with a mime type of application/xhtml+xml, but will work fine otherwise. Very few websites are currently taking advantage of XHTML as it was intended, and are still serving their content as text/html. This embed will work with any text/html page (and will validate as far as the validators are concerned)

    If you want to use object tags that will validate, you will have to use all kinds of extra workarounds – the Safari browser for one will ignore your param tags and Opera will be very picky about the attributes you put on your object tag.

    Even if you get past all the little quirks, you still have the problem of people not having the plugin installed, and having to figure out what that broken puzzle piece means, or trying to figure out if it’s safe to install the plugin their IE browser is asking for… which is why I prefer to use Javascript to embed things that require plugins.

  7. Hey, cool stuff.

    Does anyone know the cause of, or solution to this problem I’m having with embedding multiple quicktime movies on one page? It might not even be a multiple movie issue, just an embedded quicktime movie issue. Problem: When I scroll around the page, the quicktime movie(s) frames lag behind / leave artifacts on parts of the page. I’ve seen this in Safari and Firefox. I’m embedding ala the following:

    <embed src="poster_movie.mov" width="400" height="416" autoplay="false" href="movie.mov" target="myself" controller="false">
    </embed>

    Thanks

  8. Thanks for the response Geoff. It’s really frustrating as the particular page I’m working on looks really neat w/ multiple movies lined up in columns and rows, and playing next to each other for comparison (different renders of same data sets etc.). However, when you scroll things sometimes get so muddled…and it’s not like they pop back into place after a bit, sometimes things just stay muddled.

  9. This is the best solution I’ve found — and have I been looking! The biggest single problem with this is Firefox on the Mac. The solution works fine in blank test pages, but when I put it into my css-styled page there’s a big chunk cut out the same size as the movie. This box is blank and covers my header allowing the background pattern of the page to peek through. Anyone else have this problem or know what might be causing it?

    The box that blanks out everything except the background appears in the top left corner of the page.

    Oddly, the page loads perfectly in that browser. The problem occurs when I try to click the image (from the advanced method) to link to the movie. I’ve tried the simple method, and still get this box problem.

    Good thing is movie play, bad part is that it kills the design.

    Page validates and css validates.

    Thanks!

  10. Ok – Got it. In case anyone else has this problem with Firefox where a background image shows through other styled content on the page here’s what I found.

    Let’s say you wrap your SCRIPT for the video in a DIV with and ID of VIDEO — you must declare #VIDEO {position:relative;}.

    That’s it. Not sure if other positioning schemes work too, but this IS a fix for the problem I described above.

    Thanks again…your script ROOOOCKS!

  11. Pingback: Schutzsmith: life, love, and everything in between

  12. Hi Geoff,

    I came out to find a new issue with your great script. I tried it today in a Xoops module still under development that will be used on an intensively multimedia website. You can check the result here.

    As you can see, it works fine but with MSIE 6 for Windows the video layer freezes when you go from one sequence to the next one (“Clip suivant” bottom link ). This problem does not happen with Firefox hopefully and I don’t have tried yet other browser/OS combinations.

    Any idea for a quick fix ?

  13. I am sorry but I will uninstall the script from the website reffered above. There were too many issues on several platforms. It works fine for an isolated clip but problems arise in certain circumstances when you chain several clip pages together. I will try to replicate the issue on another website but for now I need to get back to the basics and work on the content. Sorry about that!

  14. I checked the page you linked in Firefox, IE 5.01 and IE 6 on PC and all of them worked fine. Maybe it’s a video driver or QuickTime issue?

  15. hi, this works well.
    question though.
    how do I add more parameters using the advanced method…. to the actual source media? When I add more parameters, it only gets applied to the placeholder image.
    do I need to hack the js file instead?
    thanks

  16. I’m not really sure – I would assume that the parameters for the first image would apply to the next one loaded in since they are using the same embed.

    How would you do it without the js embed?

  17. Hi,
    I wonder if you can help me with something?
    Instead of the place holder linking to the movie file, how can I have links from some other elements in the page (for example, hotspots on an image on the page next to where I want the movie to appear).
    So that when I clicked each one I could have different corresponding movies appear in the placeholder.
    Do you have any ideas?
    Thanks

  18. Geoff – would your work in this area be useful to help me control an embedded QT window in SAFARI using Javascript? The standard document.movie-object.Play() and Stop() controls work fine in Netscape/Mozilla but don’t do anything at all in Safari. Will your code help at all or do you have a pointer for help? -th

  19. Great script, works terrific! I need to add a parameter though. How can i get the movie to loop endlessly? Thank you for this great script.

  20. Parameter for looping would be written like this for the script
    myQTObject.addParam(“loop”, “true”);

  21. Actually, I already tried that and several other variations. Still does not loop. Javascript hates me :P

  22. Is there a way to use this .js AND have the autoplay functionality? I’m on broadband, and the wait for a 2.8 MB movie is undesirable. Long ennough for a visitor to think something was wrong.

    When I add:

    myQTObject.addParam(“autostart”, “true”);

    The clip simply does’t play. Can I have the best of both worlds: autostart AND the benefit of the embed script?

    *** Note: even as I write this, it seems like it _is_ working with autostart. THought I’d throw out my 2 cents just the same..

  23. When QT is loaded, all works perfectly, but when it is not installed I want a button (jpeg/gif) which will pop open a window and play the media when clicked. ( Don’t worry about this player).
    So the user will see a button either way. At the moment without QT the redirect opens another URL, which would be great if it waited until a button had been clicked.

    Any ideas?

  24. Hmm… I’m not 100% sure what you want, but it sounds like you could put the button in the altTxt var and have the QTObject write the button to the page if there is no quicktime installed?

  25. The altvar text works fine (when QT is not available), I am having problems adding a button to it and then writing it as I haven’t really got a clue about javascript.
    My next issue will be that there are multiple buttons on a page. So I can use the same graphic for the buttons, but they need to link to different URL’s.

    Thanks for the help

  26. I have noticed a bug in the latest version of Safari when it comes to embedding QT’s. Let me explain. I have a portfolio section where depending on which button the user clicks a QT or WMV is embedded. The bug happens when you click the “Play QuickTime” button again and now another instance of the movie will be playing over the previous (you can hear the audio overlap). The WMVs work fine (go figure) :)

    Here’s a sample to check out:
    http://www.rhedpixel.com/thework/commercials/01_arc_tsunami.html

    In Safari, click “Play QuickTime”, let it play for a bit then click the button again. You’ll hear the audio overlap. Click it again and it’s even worse! This does NOT happen in FireFox on Mac for the QTs. So I’m assuming this is a Safari specific issue. If there’s anyone who cares to test and report back that would be appreciated.

    \m/

  27. I think someone may have posted this before, but I am looking to trigger multiple videos to be played in a single box on my page. The URL is below if you want to check my design and get an idea of what it looks like. There are 3 video links on the side that I would like to use to trigger the video being played in the middle box:

    http://www.theboxerrebellion.net/indexnew.htm

    If anyone could help that would be great. Not overly familiar with javascript either.

    Todd

  28. I am trying to create a link within a swf that will replace a de-concept embeded swf file with a de-concept embedded qt file…link in swf says watch video or similar, when clicked it drops the swf and loads up a quicktime into that same div…any suggestions?

  29. This has been a tremendous help. However, I don’t have any of the buttons on the player. It just loads as an image and you have to double-click it to start. What am I missing to make it a full embedded player?

  30. Thank you for a great script Geoff Stearns! Works perfect!
    Had some trouble with path’s first but solved it easy..

    Paths:
    /qtobject.js
    /movie.html
    /graphics/clicktoplay.png
    /graphics/movies/movie150k320.mov

    var myQTObject = new QTObject(“graphics/clicktoplay.png”, “movieflic”, “320”, “255”);
    myQTObject.addParam(“href”, “movies/movie150k320.mov”);

    For some strange reason the “href” parameter refused to work with a full path so I simply cut the first directory and now it works just perfect!

    John

  31. Thank you very much for this great detection script.

    I would like to submit this little code snippet for people that try to embed the javascript within an XSL stylesheet. I found this to work (with libxml through PHP) after trying several methods:

    
    <script type="text/javascript">
     <xsl:comment>
      <xsl:text disable-output-escaping="yes">
       <![CDATA[
       // javascript code here
       //]]>
      </xsl:text>
     </xsl:comment>
    </script>
    

    I hope that helps someone,
    DrTebi

  32. I’ve got a problem with the script I can’t figure out. Your example works fine for me on Mac OS X with both Firefox 1.5 and Safari. But when I use the same code in my site except for a link to my own movie and placeholder, it continues to work with Safari but not with Firefox 1.5. With Firefox when I click on the JPEG placeholder the movie comes up (I think it’s showing the poster frame), but the movie will not play, even when I click on the play button. If I go directly to the movie URL it plays fine in both browsers. It also works fine with IE 5.3.3. Any ideas why it would not be working with Firefox 1.5 in particular?

  33. Hmm, I’ve never seen an issue like that. It sounds like it may just be a bad video? I’m not sure why it would work in safari/IE but not Firefox, though.

    Maybe try downloading another .mov file from somewhere else and embed that on your page? You could try it with the test movie I use – you can right click and ‘save as’ from here.

  34. Can I suggest a small change to the isQTInstalled function so that it returns the version and not just true/false? Something like:

    function isQTInstalled() {
    var qtInstalled = false;
    qtObj = false;
    var checkCode = ‘set qtObj = CreateObject(“QuickTimeCheckObject.QuickTimeCheck.1”)\nif IsObject(qtObj) then\nif qtObj.IsQuickTimeAvailable(0) then\nqtVersion = Round((Hex(qtObj.QuickTimeVersion) / 1000000), 1)\nend if\nend if’;
    if (navigator.plugins && navigator.plugins.length) {
    for (var i=0; i < navigator.plugins.length; i++ ) { var plugin = navigator.plugins[i]; if (plugin.name.indexOf("QuickTime") > -1) {
    qtInstalled = parseFloat(plugin.name.substring(18));
    }
    }
    } else {
    execScript(checkCode, ‘VBScript’);
    qtInstalled = qtVersion;
    }
    return qtInstalled;
    }

    (inspired by http://www.dithered.com/javascript/quicktime_detect/example.html).

  35. With only IE needing these changes to embed content
    http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp

    and some people not wanting to use javascript & embed tags in non-IE browbers
    I put together the following from various Web Sites for possible uses.

    <head>
    <!-- Javascript from Apple http://developer.apple.com/internet/ieembedprep.html -->

    <script src="[path]/AC_QuickTime.js" type="text/javascript"></script>
    </head>

    <body>

    <!--[if !IE]>-->

    <object type="video/quicktime" data="sample.mov" width="320" height="256" >
    <param name="movie" value="sample.mov" /> <!-- add this to 'data=' above for Netscape -->
    <param name="autoplay" value="true" />
    <param name="align" value="middle" />

    <!--<![endif]-->

    <!-- IE will only look at this middle part -->

    <script type="text/javascript">
    QT_WriteOBJECT_XHTML('sample.mov', '320', '256', '',
    'autoplay', 'true',
    'emb#bgcolor', 'black',
    'align', 'middle');
    </script>

    <!--[if !IE]>-->

    </object>

    <!--<![endif]-->

    </body>

    Ideas are from these sites

    http://developer.apple.com/internet/ieembedprep.html
    http://realdev1.realise.com/rossa/rendertest/quicktime.html
    http://www.alistapart.com/stories/flashsatay/
    http://ww2.cs.fsu.edu/~steele/XHTML/appletObject.html

  36. Thanks for QTObject embed, I now use it on my site.

    To answer a Comment by sirpineal — March 19, 2005
    advanced method of using a placeholder image
    parameters only get applied to the placeholder image.

    for the href movie to use the original settings add SaveEmbedTags=”True” A QuickTime 5 addition.
    http://lists.apple.com/archives/QuickTime-Users/2002/Sep/msg00380.html

    var myQTObject = new QTObject(“bushplaceholder.jpg”, “bushfinger”, “320”, “255”);
    myQTObject.addParam(“href”, “bushuncensored.mov”);
    myQTObject.addParam(“target”, “myself”);
    myQTObject.addParam(“controller”, “false”);

    myQTObject.addParam(“loop”, “true”);
    myQTObject.addParam(“autostart”, “true”);

    myQTObject.addParam(“saveembedtags”, “true”);

    myQTObject.write();

    This may also answer the loop and autostart comments

  37. advanced method of using a placeholder image
    parameters only get applied to the placeholder image.

    I just found a better method to pass new settings to the following movie
    http://developer.apple.com/documentation/QuickTime/WhatsNewQT5/QT5NewChapt1/chapter_1_section_32.html

    var myQTObject = new QTObject(“bushplaceholder.jpg”, “bushfinger”, “320”, “255”);
    myQTObject.addParam(“controller”, “false”);

    myQTObject.addParam(“href”, “<bushuncensored.mov> T<myself> E<CONTROLLER=true AUTOPLAY=true LOOP=true>”);

    myQTObject.write();

    This sets these five(5) settings in the one href parameter

    HREF=”bushuncensored.mov”
    TARGET=”myself”
    CONTROLLER=”true”
    AUTOPLAY=”true”
    LOOP=”true”

    I tried it with QuickTime7 it works.

  38. hi friends my problem is i have to play 5 movie parts togather from different urls i want the code to put in my page
    if any one knows the code or he can generate the cade for me then please mail it to me i want the movie play without any
    gap between the two parts.i will be very thenkful to you

  39. HI – I’m missing something. How do I establish an ID for the movie? Your using “bushfinger”.
    Thanks,
    Josh

  40. 1) In response to Nishit’s request to automatically play one movie after another… Head on over to Apple’s documentation for a look at an awesome parameter which you can include… “QTNEXT”. Apple’s documentaton

    2) Aldo Hoeben has posted a different solution to this problem. Aldo’s doesn’t empower you to dynamically write in tags and parameters, but it does provide a quick (if hack-y) fix. Check it out

    Cheers,

    Patrick

  41. Hello
    I’ve been trying Geoff’s embedding method for qtvr with mixed results.
    I can get panos to work full-size but not full-screen. This is the setting I’ve been using:

    var myQTObject = new QTObject(“vp1.mov”, “vp1”, “100%”, “100%”);
    myQTObject.addParam(“autostart”, “false”);
    myQTObject.write();

    It produces a pano at its full-size (in this case 1048 x 768) but on a large monitor it gives a white border rather than expanding to fill the screen. I’ve tried adding the usual ‘full-screen’ javascript in the header but that has no effect.

    Tested on Safari & explorer mac, explorer win ok, but behaves poorly on firefox (letterbox effect on both mac & win)

    Suggestions welcome!

  42. RE: john law (ha, if that’s your real name ;-) )

    Hard to say without seeing the rest of your HTML — it probably isn’t your object/embed code. The only way to for sure have your QTVR stretch from edge to edge of a browser window is to style it a bit. Feel free to peek at source code of VR display at http://www.cheathamlane.net or http://spincontrol.cheathamlane.net .

    Also, for QTVR embedding, you don’t need the “autostart” parameter…

    Cheers,

    Patrick

  43. To the 26.01.2006 comments: QuickTime has three additional values for URL targeting, “myself”, “quicktimeplayer”, “webbrowser”. To open a link in the player from a website, target “quicktimeplayer.” There’s also the T method of targeting via an URL.

  44. I’ve got a small query: I’m getting warnings using the script.

    I’ve bundled the script into a function “playMovie()” called by an onclick handler on several thumbnails. It works fine, but when the page loads I get a javascript warning that there is an “assignment to undeclared variable QTObject”, while on clicking a thumbnail it’s “assignment to undeclared variable qtObj” (per FireBug)

    Only having an understanding of javascript through coding actionscript I’m not sure what’s wrong, or how to debug the issue (I’ve tried isolating the elements to no avail)

    You can see it here… I’d be really grateful if someone could help me understand what’s going wrong.

    Meantime, many thanks for providing such a hugely useful script Geoff!

  45. hey Antti Tuppurainen! schnazzy work on the WMV version… feel inclined to do a .rm iteration?

  46. I have a question. I’m coding a page that has upwards of 20 linked .mov files along the navpanel. From these links I would like to embed the quicktime movie in a main content div. The key here being to embed those movies using onclick on the links – without reloading the page. I’ve looked at various ways to do this. I can successfully pass parameters and get the script to write my embed tag, but what I face is an inability to pass the script and execute it using innerHtml. I’m looking at using the DOM and createElement, which I’m willing to do, it just defeats the purpose of this lovely script that does all my work for me, and I still fear won’t execute the script without onload. This may be a bit off topic given it’s more of a javascript question – but I’ve searched high and low for this kind of info on the AJAX pages for executing scripts but all of them seem to require execution at the pages onload, or onclick. I believe this is what “Comment by Todd — August 4, 2005 @ 8:41 am” was trying to achieve, but it doesn’t look like he pulled it off in looking at the popup solution he has currently. Thanks!

Comments are closed.