Sunday, 6 January 2008

Simple QuickTime Movie Embedding

QuickTime has a very useful "Export for Web" feature that can produce a number of different versions of the same movie targeted at different devices. As well as the different versions of the exported movie it produces a web page with instructions and an example of how to embed the movie in your own website. This is a great but, as far as I am concerned, the way Apple have chosen to embed QuickTime movies in web pages has a number of drawbacks:
  • The markup needed to embed a single movie is quite extensive, requiring a JavaScript function call and a noscript tag to manually embed a player when JavaScript is disabled.
  • Their solution uses two rather large JavaScript files and a style sheet. These files are not ridiculously large but they seem very over engineered for solving what is in essence a very simple problem.
  • The appearance of the embedded movie when JavaScript is disabled is different, most notably no clue is given that it is in fact a movie which can be played by clicking upon it.
  • There is no simple way of customizing the way in which the movie is embedded in the web page.
So I've put together a solution which attempts to address all of these issues making it both easier to embed QuickTime movies into pages within your website as well as giving you more control over their appearance.

I've put together a demo page with a number of examples, but to give you an idea of what you can do, how about the option to watch the trailer for Fracture or WALL-E.

Click to play 'Fracture'Click to play 'WALL-E'

Updated 26/10/2008: I've added a check to see if QuickTime is installed so that we don't even try to embed it if it isn't there.

Updated 07/11/2008: I've removed code that worked around the Eolas patent as a) I don't think it is really needed and b) it was causing two instances of QuickTime to be embedded in IE which resulted in audio problems. Thanks to Jonathan for pointing out the IE problem.

Updated 27/11/2008: Added the ability to provide either a re-direct URL or a function to be called when the user clicks to play a movie if they don't have QuickTime installed.

Updated 30/11/2008: A very minor update to allow the URL of the QuickTime movie to contain parameters.

Updated 02/12/2008: Added the ability to place links to the QuickTime movies outside of the DIV in which they will be played. Thanks to Stephen for the suggestion.

Updated 14/10/2009: Updated the CSS styles to include the standard CCS3 opacity as new versions of Firefox no longer respect the -moz-opacity setting. Also the script now ensures that the DIV in which the movie will be played is fully within the viewable area by scrolling the page if necessary.

Updated 26/11/2010: Added support for showing alternative HTML content if QuickTime is not installed. Thanks to Niklas Olofsson for the suggestion.
7 November 2008 at 04:05 , Jonathan said...

Hi there! Love the way this script works. Have you had any problems with the movies "playing twice" in Internet Explorer...well at least the audio portion?

I would love to use it, but that's holding me back

7 November 2008 at 09:28 , Mark said...

Jonathan, thanks for pointing that out, it is a really nasty flaw.

I'm not sure exactly what is causing the problem but it seems as if two instances of QuickTime get embedded one on top of the other and because loading the file takes a while they end up out of sync and hence the audio plays twice.

Strangely the IE developer tools show only one instance of the Object tag being embedded so I'm assuming it is actually an IE or QuickTime bug rather than a problem with my script.

I'm going to investigate it further though so if you could leave me a comment detailing which version of Windows, IE and QuickTime you are using that would be helpful.

7 November 2008 at 12:16 , Mark said...

OK, the IE issue should now be fixed. Basically when I originally wrote the code I added a work around for the Eolas patent. At the time this worked OK in IE, but something has changed. The work around was causing two copies of QuickTime to be embedded one on top of the other hence the sound continuing to play when you hit pause or an echo due to the two movies being out of sync.

I've removed the work around as I don't think it is needed anyway. The Eolas patent is only triggered for JavaScript embedded in the HTML page and as this is a separate JS file it shouldn't cause a problem. I've left the work around in the file but commented it out so that if it is needed in some weird browser we can add it back in with appropriate version checking.

Anyway the upshot of all this is that it now works in IE again (also now tested in Safari, Opera, Firefox and Google Chrome).

Let me know if you have any further problems.

19 November 2008 at 22:07 , Gareth said...

Hi Mark,

First of all congratulations on a great article - one of the few if not the only decent one I could find on the web.

My question is that I'm using your method to embed a .mp4 movie instead of .mov. It all works fine on my local machine (because I have quicktime installed). However on a clients machine they didn't have quicktime installed and the computer proceeded to download the full movie to play it in RealPlayer. So, if there a way I can force the movie to only open in quicktime and if quicktime isn't available stop it proceeding with the download?

Thanks!

19 November 2008 at 23:55 , Mark said...

Hi Gareth, glad you think the script is useful. I've updated it so that you can specify a URL to redirect to if QuickTime isn't installed. Simply set the QuickTime.upgrade variable to the URL you wish to be displayed when the user clicks to load a movie if QuickTime isn't installed. You can of course do nothing simply by specifying # to reload the current page.

Hope that helps, but if you have any other thoughts/suggestions let me know.

1 December 2008 at 21:01 , Stephen said...

This looks very useful. However I would like to have a list of movies on the page that when clicked would display in the "quicktime" div. As it is now links must be in the div to work correctly and are then replaced by the movie.
Might this be a simple modification?
Thanks for posting this.

1 December 2008 at 21:19 , Mark said...

Hi Stephen. I think adding the functionality you are looking for is a good idea.

I'm thinking of doing it by adding a playin attribute to the link so I know where the movie should go when the link is clicked.

The only problem I can see is that this would stop the HTML from validating, but that isn't really an issue as long as you know why. I could shoehorn it in using the rel attribute but that also seems like a nasty subversion of the HTML standard.

Anyway, watch this space over the next day or so for a new version you can test.

2 December 2008 at 13:30 , Stephen said...

Hey, that's great Mark. I'll be watching.

2 December 2008 at 18:58 , Mark said...

Hi Stephen. I've now added the functionality you were looking for and uploaded the new version.

You can see full details of how it works on the demo page. I've also updated the complex example in the demo to show it in action.

I've gone for a slightly different approach then I thought about yesterday. Instead of adding an attribute to the link, which would have been against the HTML spec, I've used non-existent CSS classes to encode the ID of the DIV to play in instead. Hopefully this should be easy to use and shouldn't conflict with anything else.

If you could have a play and let me know what you think that would be great.

3 December 2008 at 15:14 , Stephen said...

Geez, what service!! This is great.
I had been using another Ajax type script but it didn't work in IE. Your script is much cleaner and easier to implement.

Thanks!!

7 December 2008 at 20:48 , Vince said...
This comment has been removed by the author.
7 December 2008 at 20:48 , Vince said...
This comment has been removed by a blog administrator.
7 December 2008 at 21:04 , Mark said...

Vince, not sure exactly what you mean by a different source file. Do you mean across frames or windows? Could you give a specific example?

7 December 2008 at 21:13 , Mark said...

Vince, sorry for deleting your comment, we obviously both noticed it had appeared twice and tried to delete different ones at almost the same time. For everyone who didn't see Vince's comment it read:

How would you target a movie to a certain div tag from using the embed code from a different source file?

7 December 2008 at 22:18 , Vince said...

This is my javascript file :
"item.addEvent('click', function(e)
{
drop.removeEvents();
drop.empty();
var a = item.clone();
var myQTObject = new QTObject("d/uploads/video_pic/cactage.jpg", "480", "375");
myQTObject.addParam("href", "d/uploads/videos/cactage.mov");
myQTObject.addParam("target", "myself");
myQTObject.addParam("controller", "false");
myQTObject.write();
a.inject(drop);
dropFx.start('7389AE').chain(dropFx.start.pass('ffffff', dropFx));

});"

Im trying to have this code excute in a div tag called large. (which is on a different page). All that happens is that the video shows up, but does not appear in the div, it just opens a new window.

8 December 2008 at 10:25 , Mark said...

Vince, given that you don't actually appear to be using my script it is difficult to know exactly what the problem is. In theory I could extend my script to work across frames (and possibly named windows) but it would mean searching through the frame structure and checking each page which would be quite slow (especially given that the feature wouldn't be used much).

There are, however, a couple of reasons why your script may simply be loading the movie rather than embedding it. Assuming the href of your link is to the movie then you must return false from the onClick event otherwise the link is followed regardless of the script in the onClick. Secondly if adding a "return false;" to the end of the function doesn't help then the script could be throwing an exception before it can return false. This would also trigger the href link. Try catching the exception to see what is happening.

8 December 2008 at 17:24 , Vince said...

Thanks for helping me out, Ill try that!

18 December 2008 at 17:45 , Stephen said...

Hi Mark,
What is the syntax for adding the movie parameters to the URL? I see you updated to include this but don't see any examples.
Thanks.

18 December 2008 at 17:55 , Mark said...

Stephen, I didn't really add any new functionality. Basically the original code looked for links where the href ended in ".mov". This worked in most cases but I was starting to use the code on in a web app where the movies were requested via a servlet as "movie.mov?id=10001" and the url parameter string meant the regular expression didn't match and hence the link wasn't updated by the script.

Hope that clears things up and explains why there wasn't a new example added to the demo page.

18 December 2008 at 18:03 , Stephen said...

OK I get it. Using your script is there a way to add the .mov controller?

18 December 2008 at 18:10 , Mark said...

By the .mov controller do you mean the bar at the bottom showing the location within the movie and the play/pause buttons?

If this is what you mean then it should appear by default. Although I think you can set the quicktime preferences to kiosk mode or something to hide it globally on your computer. I'll look into it and see if there is anything in the script that may be causing it to disapear.

18 December 2008 at 18:16 , Stephen said...

Yes that's what I mean. In your typical embed tags you can set various parameters for the player - controller, autoplay. I notice the controller is not present in your examples either. I wondered if this was a variable in your script.

12 October 2009 at 14:02 , Øystein said...

Hi, thanks for this script. Is there a way to have the browser jump to the top of the page when selecting a movie from a list, like on this page:

http://www.huggormfilm.no/3.0/main.html

øystein

12 October 2009 at 19:28 , Mark said...

Hi Øystein, a really simple way to achieve what you want is to add the line

if (div.scrollIntoView) div.scrollIntoView();

to the playMovie function just before the return false;

I believe this will work in most modern browsers but...

1. It will scroll the window even for links that are within the DIV which will be replaced by the player
2. The window is scrolled so that it's top matches the top of the visible window -- it would be better if it was centred
3. scrollIntoView isn't part of any recognised spec so there will be browsers that don't understand it

So if you need a solution now then use this one, but I'll be looking for a better solution over the next few days so keep checking back.

13 October 2009 at 16:04 , Ryan said...

Great tutorial, man. I've been looking on all sorts of forums for a way to do this. Thanks so much.

One question: I noticed in the javascript a code for ActiveX plugin. How do I link my button to the ActiveX object instead of the QT?

Bear with me, I'm new at this.

Thanks again.

14 October 2009 at 20:52 , Mark said...

Øystein, I've updated the script so that now it will ensure that the movei is fully visible when you click on the link. Hopefully this should give you what you want but if not let me know.

Ryan, I'm not entirely sure what you are trying to do. The reason there is an ActiveX object mentioned in the script is because the QuickTime plugin has two parts: an ActiveX object for IE and a 'proper' plugin for other browsers. So if you are using IE then you are using an ActiveX object. If you describe exactly what you are trying to do I may be able to help.

15 October 2009 at 20:25 , Øystein said...

Works great, thanks a lot!

17 December 2009 at 01:32 , jeremy said...

Hi Mark, what a great and simple solution you have. This issue has been bugging me for a while and I was always amazed at how complicated it seemed.

Anyway, I do have a question about your script. How can I set the movie to autoplay without having to click the play button first. This is a destination page and I already know the user wants to watch the video because they have clicked to this page from another link. I just want the movie to start playing once the page loads. Thanks again for the script and any advice on my question!

23 December 2009 at 11:27 , Mark said...

Jeremy, if you want the movie to play as soon as the page loads then you are probably better off putting the object embed code direct into the page rather than relying on this script to do the switch for you.

Having siad that it should be straightforward to add an autoplay option to the script, and I can see a use for that when you might have links to multiple movies on a page but want one to play on page load (a bit like chapter links in a DVD maybe).

I'll try and have a play around over the holidays and see what I can come up with.

27 January 2010 at 15:23 , Ryan said...

As others have said.. great page, man. It helps a lot. I do have some questions -- I'm a little new at all of this web developing.

On your demo page, you mention you can convert to Flash if the person doesn't have QT. How does that work?

Also, I've tested it out on a computer without QT and in IE, I get the proper prompts to download QT but in Firefox I don't get anything.

My friend has a similar site to mine (in design only - he had someone else do the code) and I tested his page in Firefox as well. If you click on his buttons, Firefox says "Click here to download plugin" where the player would be and QT is added. Again, my site says nothing. Do you know how I would get that to happen on my site as well?

www.ryankrumm.com

Thanks again for the great script though, I've been searching for some time.

27 January 2010 at 17:05 , Mark said...

Ryan, I'll try and answer both questions. First the easy one.

If you want to switch to Flash if the user doesn't have QuickTime installed then have a look at this other post of mine on bringing QuickTime to the Wii. It doesn't actually allow the Wii to play QuickTime movies but instead does an on-the-fly conversion to Flash and embeds a Flash player instead of the QuickTime player. The full example uses a Tomcat server and FFMpeg for converting and serving the Flash videos, but if you convert the videos in advance then you should be able to serve them from any web server you like.

Now on to the much trickier 2nd question. With this script you won't get the missing plugin message in Firefox as the script checks to see if QuickTime is installed and doesn't try using the plugin if it isn't. If QuickTime isn't installed then by default it doesn't modify the link, which means when you click to play you just get asked if you want to open or save the file. You can change this behaviour by setting the QuickTime.upgrade parameter of the script (there is an example on the demo page and this is also how the Flash switch works). The other option (which I haven't tested) would be to modify the javascript file so that the isQTInstalled function always returns true. This would mean that when someone clicked to play the video the script would try and embed QuickTime even if it wasn't installed, at which point I would assume you would get the missing plugin prompt.

Hope that helps, feel free to ask if anything still doesn't make sense!

28 January 2010 at 14:08 , Ryan said...

Thanks for getting back to me so quickly.

With flash portion, I would first have to convert my videos to flash, correct? I don't have my own server, I'm simply being host by a company.

Beyond that, I really have no idea which file from you zip bundle to upload to my site. Is it the ConvertToFLV.java? Also, what changes would I have to make to whatever file I upload so that it ignores FFMpeg and Tomcat and replaces the QT with the FLV's I converted and uploaded?

With the QT's, I'm not sure which portion of the quicktime.js I need to change to make it not download to movies. I am REALLY new to all of web designing so I changes ALL the Falses to True and even deleted portions of the script. Oddly enough, though I didn't make any difference at all to how it functioned.

Like I said, I'm really new to all of this so if it's way too much work to explain this all to me then I totally understand. However, I do want to understand how all of this works as opposed to you simply giving me the answers, for what that's worth.

30 January 2010 at 09:25 , Mark said...

Ryan, sorry my answer wasn't as helpful as I'd hoped. Let me take another shot at explaining things.

To get the script to always embed the QuickTime player (which will result in the missing plugin information) then you need to make sure that the isQTInstalled method always returns true. The easiest way is to change line 192 of the script so that instead of reading

return qtInstalled;

it reads

read true;

That should trick the script into always trying to embed QuickTime even if it isn't installed.

As for serving Flash if QuickTime isn't installed then that is much harder, especially if you are new to JavaScript development. Also if you modify the QuickTime script so that it always tries to embed then you won't be able to hook into the upgrade feature I used to switch to Flash. Anyway I'll try to explain a little clearer how the approach works.

Basically you need to look at index.html in the QuickTime for Wii file you downloaded. At the top of this file you will find some JavaScript. Basically there are two functions; one overrides the default upgrade method in my script and the other is used when someone clicks to play a QuickTime movie but serves Flash instead. This is overly complex as it deals with passing parameters to a server which will do the transcoding on the fly. If you can transcode the QuickTime files to Flash in advance then this could be simplified a lot -- maybe you would store the flash versions by simply adding .flv to the end of the file, so that movie.mov would become move.mov.flv then modifying the link would be easy. As I say if you don't have too much JavaScript experiance then customizing this to your specific needs is going to be difficult. Let me know if you need any more pointers on the Flash stuff or if forcing the missing plugin message is enough for you.

2 June 2010 at 21:49 , Studio Jay said...

Mark, great site. It's nice to find someone who can communicate to the point.


I have been testing your code and find that under Safari 4.0.5., I'm having a timing problem. I've used the poster with a standard button. After pressing the button, the black video screen with the controller comes up after a beat with the audio. After about two beats, the video then shows up as a brief static image while the audio continues and then the video catches up. It makes for a choppy viewing. Any ideas how to fix this?



Thanks in advance.

3 June 2010 at 13:33 , Mark said...

Studio Jay, I'm not sure which OS you are using (although I'll guess you are on a Mac given how few people use Safari on Windows) so I'm not entirely sure what the problem is.

Having said that I've seen choppy playback under Windows in both Firefox and Safari. It seems to occur when either the movie hasn't been fully cached or if the machine is under heavy load. It also seems to happen with Flash movies as well as quicktime so I'm assuming it is more of an OS/CPU/resource issue than a problem with this script.

Sorry I could be more helpful.

10 June 2010 at 19:14 , qmartin said...

Thanks for the helpful info on the Multiple links into a div tag!

How would you do the "Complex Version With Multiple Links" for mobile Safari for the iPad? I want to be able to have many links outside the div, and want to load each one (H.264) into it? How do I achieve this?

It works fine for .mov but that is not supported on the ipad. Any clue?

Thank you

11 June 2010 at 14:26 , Mark said...

qmartin, not sure why it isn't working properly on the iPad.

As far as I know using the script should work on the iPad as long as the video you are trying to play uses a supported codec.

From what I can gather the only codec supported on the iPad is H264, so the mov file will have to use that for it to play properly.

Could you check with a H264 encoded mov and see if it works. If not then let me know and I'll see if I can find a different solution

28 June 2012 at 13:46 , Grab a Web - Webdesign & Grafische vormgeving said...

Hello,
Thanks for your codes. Can you explain to me why the top of my button disappears in IE9? In firefox it's perfect...
http://www.bekijk-website.nl/any1els/index.php
Thanks in advance

28 June 2012 at 15:58 , Grab a Web - Webdesign & Grafische vormgeving said...

Hello,

Thanks for the codes. I do have a minor problem in IE9. Why does the button upperpart disappear? Firefox is perfect.
link: http://www.bekijk-website.nl/any1els/index.php

.standard
{
background-color: #EA5B0C;
font-size: 12px;
color: white;
zoom: 100%;
opacity: .8;
-moz-opacity: .8;
-webkit-opacity: .8;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
-moz-border-radius: 1em;
-webkit-border-radius: 1em;
border-radius: 1em;
border: 2px solid #FFF;
font-family: Arial, sans-serif;
padding-top: 1em;
padding-right: 2em;
padding-bottom: 1em;
padding-left: 2em;
font-weight: bold;
position: relative;
top: 50%;
text-decoration: none;
}

30 June 2012 at 14:43 , Mark said...

Not sure why the top of the link should be disappearing in IE9. I'll try and find a machine with IE9 on to test (I'm an Ubuntu user and don't tend to test in IE too much these days -- if Microsoft can't stick to the standards then...). One thing I would try first would be to remove the -ms-filter and see if that is messing up in IE9. Also I'm not sure if the zoom attribute is strictly necessary either (although I guess that will depend on what styles are inherited).

7 November 2012 at 12:28 , Mischa Büttler said...

What works in IE9 is this:
.standard
{
background-color: rgba(20,20,20,0.8);
font-size: 1.25em;
color: white;
padding: .5em 1em;
border-radius: 1em;
border: none;
font-family: Arial, sans-serif;
}
I included the opacity in the background-color value using rgba() instead of rgb().

But what happens on my page is that when I click the button, no video is displayed in IE, only audio. All other browsers work fine.

11 June 2014 at 13:29 , jamie hamill said...
This comment has been removed by the author.

Post a Comment