O'Reilly    
 Published on O'Reilly (http://oreilly.com/)
 See this if you're having trouble printing code examples


Gotta love O'Reilly readers. Every time I publish one of my crackpot QuickTime or JavaScript experiments, you send me dozens of ideas for variations. In this article, I'll expand on the QuickTime poster movie trick, show you how to present multiple movies on a single webpage without bogging it down, reveal how to launch a movie in fullscreen mode, and even show an easy way to play a sequence of movies automatically.

Before we get started, test to see if QuickTime is installed on your computer. Version 7.2 just came out this week; it adds several security fixes and one long-requested feature. However, there have been reports of problems on some computers, so you may want to wait until the dust settles.

Poster Office

One of the most elegant techniques for embedding movies in webpages is with a poster movie, typically a single frame or a short looping segment sized to the same horizontal and vertical dimensions as your feature movie. Poster movies stake out space for other movies without gobbling up the bandwidth you'd need to embed the main movie. When a visitor clicks the poster, the main movie replaces it in the browser window and starts loading. On YouTube, default poster movies show up as a blurry mess with the triangular Play button inside. With the techniques I'm about to demonstrate, you can use a crisp, beautiful image instead and avoid the blurry mess.

As I explained in "Two Slick QuickTime Tricks," there are two main drawbacks with poster movies: you have to create a single-frame QuickTime movie rather than simply using a JPEG, and the poster movie doesn't trigger the hand cursor in a web browser, so it's not always obvious that it's clickable. In that article, I described a technique that solves both those problems, and I'll expand on it in a moment. However, my technique requires a bit of JavaScripting, and I've since found a commercial utility that creates poster movies—complete with hand cursors—with drag-and-drop ease. (See Figure 1.)

Pageot

Fig. 1: Drag a background image and a movie onto QTBridge Stampot and the program generates an elegant poster movie, complete with hand cursor. The left image shows the movie before it's clicked; the right shows it during playback.

As you can see in Figure 1, Stampot uses a text box for the poster movie, though, not an image, so there's room for improvement. If you have QuickTime Pro, you can open the poster movie and paste a correctly sized image into it, but let's examine the JavaScript approach, which allows more options. (Incidentally, Stampot triggers the hand cursor by inserting a sprite track into the poster movie. QuickTime guru Steven Gulie offers some premade sprites on his site, but I haven't found any that simply trigger the hand cursor.)

Better Posters Through DHTML

Basically, my poster movie technique wraps an image file in one div, which is visible, and Apple's QuickTime embedding JavaScript in another div, which is hidden. When you click the trigger image, an inline JavaScript command hides its div and unhides the movie player div. The code looks like this:

<div id="movieplayer" style="display:none" align="center">      
    <script language="JavaScript" type="text/javascript">

    <!-- Hide script from sad old browsers
    QT_WriteOBJECT_XHTML('reason-workshop.mov', 
    '320', '256', '');
    // -->
    </script>
</div>
    
<div id="trigger" style="display:block" align="center">
    <a href="reason-workshop.mov" target="_blank" 
    onclick="javascript:document.getElementById('movieplayer').style.display='block';
    document.getElementById('trigger').style.display='none';return false">
    <img src="QT-reason-poster.jpg" alt="Click to Play" width="320" height="256" 
    border="0" /></a>
</div>

Notice that the poster image is also wrapped in a link to the movie file, which is what makes it clickable and generates the hand cursor. Furthermore, because it's a standard a href link, the movie will still launch even if the visitor has JavaScript disabled. You can see it in action at the bottom of page 2 of the original article.

One reader reported that this technique solved a content management system (CMS) challenge he'd had for months: "This works beautifully with our CMS (stays in the CMS browser session) and all my JavaScript controls function better than ever. It's also cut down the coding of the parameters required."

Craig Smith in O’Reilly's European office wondered if there were a way to use the technique to play multiple movies on a long blog page. He'd found that simply duplicating the two divs resulted in each new trigger link playing back in the first movieplayer div on the page. I suggested he use unique IDs for each trigger/media pair, and he was back in business. Here's an example with three movies; Craig is also using the technique to play MP3s by setting the movie height to 16 pixels, the height of the QuickTime controller.

Poster Movie Weight Loss Program

However, typing out those long links for multiple movies is a bit of a pain. I realized I could simplify the code by moving some of the JavaScript to a function and calling it from the links. That produced this new link format. (The movieplayer div didn't change.)

<div id="trigger2" style="display:block" align="center">
<a href="reason-workshop.mov" target="_blank" 
onclick="loadMovie('movieplayer2','trigger2');return false">
<img src="QT-reason-poster.jpg" alt="Click to Play" 
width="320" height="256" border="0" /></a></div>

And here's the script:

<script type="text/javascript">
<!-- Hide script from sad old browsers
  function loadMovie(playerID,triggerID) {
  document.getElementById(playerID).style.display='block';
  document.getElementById(triggerID).style.display='none';
  }
  // end hiding script -->
</script>

Self-Effacing Posters

The revised poster code was a bit shorter, but it was still redundant. What if, instead of hiding the trigger and revealing the player, we rewrote the trigger on the fly? That idea led to this new link format:

<div id="trigger3"><a href="examples/movie3.mov" 
target="_blank" onclick="loadMovie(this.parentNode.id,this.href,'160','136');
return false"><img src="graphics/poster3.gif" alt="Click to Play" 
width="160" height="136" border="0" /></a> </div>

Here, the link passes the trigger div ID (this.parentNode.id), the movie URL (this.href), and the movie's height and width to the function loadMovie(). That function in turn calls a little-known function in the Apple QuickTime embedding script called QT_GenerateOBJECTText_XHTML, which returns the text of the embedding code without writing it onto the page. Finally, I use the innerHTML method to replace the contents of the trigger div with the movie embedding code:

<script type="text/javascript">
<!-- Hide script from sad old browsers
  function loadMovie(triggerID,movieURL,movieWth,movieHt) {
  var embedcode = QT_GenerateOBJECTText_XHTML(movieURL,movieWth,movieHt,'');
  document.getElementById(triggerID).innerHTML=embedcode;
  }
  // end hiding script -->
</script>

And here it is in action. The voice is from the Cepstral speech synthesizer. I made the music in Ableton Live and then generated the video in Boinx FotoMagico 2, which produces almost Flash-like text animations.

Click to Play
Click to Play
Click to Play

Multiple Movies, One Player

Here's an in-progress script to play multiple movies in a single player. I still need to figure out how to remove the currently playing movie so movies don't stack up.

<script type="text/javascript">

<!-- Hide script from sad old browsers
function insertMov(movpath, movwidth, movheight){
var theMov = QT_GenerateOBJECTText_XHTML(movpath, movwidth, movheight, '','scale','tofit');
var masterPlayer = document.getElementById('uniplayer');
masterPlayer.removeChild(masterPlayer.firstChild);
masterPlayer.innerHTML=theMov;
}
// -->

</script>

The links are very simple:

<a href="movie1.mov" target="_blank" onclick="insertMov(this.href,'320','256');
return false">Movie 1</a>
dummy pic

Movie 1 | Movie 2 | Movie 3 | Movie 4 | Movie 5

In the script above, notice that I added another parameter, scale, to the QuickTime function call. Its value is ToFit. That causes the small movies to scale up to the size of the container. You can also specify Aspect, which maintains the movie's proportions, or a number. (For example, 2 would double the size and 0.5 would halve it.)

There are dozens of QuickTime embedding parameters. A great way to experiment with them is with another QTBridge program, Pageot. It's free and runs on Mac and Windows. (Pageot is apparently a French pun for "embed.") The program shows you the javascript in real time as you change attributes, as you can see in Figure 2.

Pageot

Fig. 2: See QuickTime code appear before your eyes as you change parameters in Pageot. (Click to enlarge.)

One of the cool things about Pageot is how it simplifies the creation of movie playlists. In the example below, Movie 1 will call Movie 2 when it ends, and on to Movie5. Then the sequence will loop back to Movie 2. All of that plus much more is customizable.

Here's the code:

<script language="JavaScript" type="text/javascript">

<!--
QT_WriteOBJECT_XHTML('examples/movie1.mov', '160', '136','',
'controller','true',
'emb#bgcolor','FFFFFF',
'autoplay','false',
'showlogo','true',
'movieid','007',
'cache','false',
'qtnext1','<movie2.mov>T<myself>E<controller=true autoplay=true loop=false>',
'qtnext2','<movie3.mov>T<myself>',
'qtnext3','<movie4.mov>T<myself>',
'qtnext4','<movie5.mov>T<myself>',
'qtnext5','goto1',
'allowembedtagoverrides','true');
// -->
//]]>
</script>

Play It Large

For years, multimedia designers and viewers alike have wanted an easy way to present QuickTime movies in fullscreen mode without coughing up $30 for QuickTime Pro. Workarounds included substituting an old version of the QuickTime Player and invoking AppleScripts, but that required viewers to have technical savvy (and a Mac in the latter case). And it didn't work for movies launched from Web pages.

SoundScreen.com describes a elaborate solution for Web designers that involves creating an intermediate XML file. This text file, called a QuickTime Media Link, contains embedding code that instructs the QuickTime Player to present the movie in fullscreen mode. I tried the technique with various files and found it worked well on a Mac, but crashed QuickTime Player in Windows with a buffer overrun error. Thankfully, that bug is fixed in the latest version of QuickTime, 7.2. Even better, version 7.2 finally restores fullscreen playback to the non-Pros.

However, unless Apple adds a fullscreen parameter to the list of QuickTime embedding attributes, I don't think there's a way to specify fullscreen playback directly from a webpage. If you do have QuickTime Pro, there's a simple workaround, though:

  1. Open the movie in QuickTime Pro;
  2. Display its properties (by pressing Command-J or Control-J);
  3. Select the master track;
  4. Click the Presentation tab;
  5. Enable the checkbox beside "Enter fullscreen mode when opened."
  6. Set the webpage to launch the movie in the QuickTime Player by assigning the target parameter to quicktimeplayer.
QuickTime Properties

The easiest way to launch a movie from a webpage and have it fill the screen is to enable the movie's internal fullscreen parameter in QuickTime Pro. You then set the webpage's embedding code to open the movie in the QuickTime Player.

Here's what the code might look like. You can also tell the movie to start playing automatically by adding the attribute pair 'autoplay','true' here, but I opted to set that in the movie itself (see screenshot).

<script type="text/javascript">
    QTWriteObject('poster.mov','320','256','', 
                  'controller','false', 
                  'href','fullscreen.mov', 
                  'target','quicktimeplayer' );
</script>

Try it (you won't see a hand cursor, but click anyway): Note that fullscreen playback may crash some Windows browsers using old versions of QuickTime.

The amazing QTBridge gallery demonstrates a similar effect by opening the QuickTime movie in a self-expanding popup window and setting the QuickTime scale parameter to ToFit. Because the computer's menu bar and the browser's window frame remain in view, that presentation can be less startling to visitors.

The more I play with QuickTime, the more amazed I get at its capabilities. Check out the Reference and Examples sidebar links and you're sure to get inspired too.

Reference and Examples

SoundScreen Multimedia Resources—clear, concise QuickTime tutorials, plus links to ambitious experiments

Apple: QuickTime Embedding Attributes

Apple: QuickTime Tutorials

Apple: JavaScript for QuickTime — Apple says, "If you create QuickTime movies that are embedded in web pages, or if you create web pages that include QuickTime movies, you should read this document."

Apple: HTML Scripting for QuickTime — I found this one especially clear and useful.

Backstage Brennan Young's intriguing experiments on synchronizing movies

QTBridge — Makers of free and inexpensive QuickTime utilities for Mac and PC; be sure to visit the galleries, links, and tutorials.

David Battino is the audio editor for O’Reilly’s Digital Media site, the co-author of The Art of Digital Music, and on the steering committee for the Interactive Audio Special Interest Group (IASIG). He also writes, publishes, and performs Japanese kamishibai storycards.


Return to digitalmedia.oreilly.com.

Copyright © 2009 O'Reilly Media, Inc.