Rocking Mars with Streaming Shockwave
A streaming Shockwave tutorial
By Bob Schmitt
January 9, 1998
Since the introduction of Shockwave in 1995, CD-ROM-quality multimedia has always seemed out of place in the low-bandwidth world of the Web. Just like Web designers coming from the print world, Shockwave developers coming from the world of CD-ROM multimedia have had to learn a variety of techniques to reduce the file sizes of their media. They have had to make numerous sacrifices in the quality of their presentations in order to balance the richness and depth of their projects against the patience of the end user in downloading it.
The initial releases of Shockwave offered some help in reducing the required bandwidth with an excellent compression scheme, but large projects still required a lot of patience on the part of the end user. When Shockwave was first developed, Macromedia's engineers were primarily concerned with merely providing playback for Director movies on the Web. Director, being originally designed for disc-based delivery, didn't address the special requirements of the Web. With Director 6, Macromedia has designed many new features to address the unique needs of the Web while freeing developers from time-consuming tricks and workarounds.
A Look at Streaming Shockwave
A Shockwave movie isn't streamed in the definitive sense of the word — a more descriptive phrase would be selective, or preferred, downloading. In a way, a Web page is "streamed." The HTML file is downloaded first and "read" by the User Agent (UA). The UA (a browser in this case) interprets the file and calls for the rest of the media (typically images), displaying it on the page as each element is fully downloaded. This is how Shockwave "streams" — the Score of the movie is downloaded first, and is then interpreted by the UA (the Shockwave plug-in or ActiveX control) and media is downloaded and displayed in the order it appears in the Score.
As with an HTML document, media elements only become available when they have fully downloaded. That is different from true streaming technologies, which allow access to partial "chunks" of media elements.
How well a Shockwave movie streams is based on how well the movie is structured. Understanding how Shockwave streaming works will help you determine the best way in which to construct your movie. Let's look a few techniques for setting up a streaming Shockwave project.
Setting Streaming Playback Options in Director
Director offers several basic options for streaming playback of Shockwave movies. To access the settings, from the menubar select Modify/Movie/Playback. This opens the Movie Playback Properties dialog box show below.

The Movie Playback Properties Window.
There are three options under Streaming: Wait for All Media, Use Media as Available, and Show Placeholders. The default setting is Wait for All Media, which basically means "No Streaming," as the movie will wait for all the media to download before starting. With Use Media as Available, playback of the movie begins immediately. The empty Stage appears first, and as each piece of media finishes downloading, it appears in place on the Stage. The next option, Show Placeholders, indicates missing or partially downloaded media with thick-bordered boxes that take on the size and shape of the missing graphic.
Take a look at these three examples of a streaming movie which demonstrates these settings:
The final streaming setting is Pre-Fetch. This option allows you to specify a number of frames to download before playback of the movie begins. This allows you to display the first frames of a movie while the rest of the movie downloads. This option could be used to display a message to the user, such as "Be patient the movie is downloading" or a short animation to entertain them before the real show begins. In a later section, I'll show how you can use this option to create a status bar in the first frame of your movies.
That's it for streaming options with Director itself. Pretty basic stuff, huh? With such basic control over the order in which elements stream, how can you get control over what aspects of the movie your users will be able to access and when? That's where Lingo comes in. Introduced with Director 6 are several new Lingo commands created to give some control over your streaming Shockwave movies. Let's take a look at how to use these new commands and some discuss some techniques in constructing streaming movies.
Using frameReady and mediaReady
Just as its name would indicate, the first of these commands,
frameReady, tests whether or not all the media needed for a
particular frame is ready. By using this command, you can determine
which parts of the movie are ready and display them to the user.
Let's use the Mars Rocks! sample above to show how this command can be used.
In Mars Rocks!, I offer the user a choice of four thumbnails of the
rocks of Mars. Clicking on any of the thumbnails takes the user to a
larger image of the rock. This is an example of the simplest form of
branching in Director — clicking on a thumbnail issues a go
frame command jumping the movie to the proper frame with the bigger
photo in it.
For example, on the "Yogi" thumbnail, I have attached a sprite script with the command:
on mouseUp go frame "yogi" end
FrameReady
In a streaming movie, if a user clicked on a
thumbnail that lead to a frame that was not yet ready, they'd get a
blank screen. Using frameReady, we can check to make sure that
the Yogi frame is ready and alert the user if it is not. Like so:
In this case, when the Yogi thumbnail is clicked on, Lingo checks to see if all the media for the frame called "yogi" is ready. If it is, it sends the movie to the yogi frame — if not, it pops up an alert box informing the user that the frame is not ready.
See this sample in action:
MediaReady
MediaReady is similar to frameReady but, where
frameReady only checks whether an entire frame is ready,
mediaReady lets you be a little more selective by allowing you to
test whether media is ready on a Cast member by member basis.
To illustrate this, in this next sample, I've constructed the movie a
little differently. Instead of sending the user to a different frame
when they click on the thumbnail, I'm keeping them in the same frame and
just turning the larger images of the four rocks visible when they are
clicked on. In order to make sure the large image is completely
downloaded before making it visible, I use the mediaReady of
member syntax as seen here:
As you can see the structure is very similar to the frameReady
usage, but in this case I'm checking to see if the media for the large
photo of Yogi is completely downloaded. If it is, I make the sprite
channel that holds the image visible; if the media is not ready, I alert
the user.
See this sample in action:
In the sample above, if you clicked around a bit, you may have noticed that the image of Yogi was the first to arrive followed by Barnacle Bill, Little Matterhorn and Flat Top. This is a good example of the order of loading I mentioned at the beginning of this article. Media is downloaded in the order in which the Cast members appear in the score — starting with frame 1, sprite channel 1 and moving down through the channels and horizontally through each frame. Because the large photo of Yogi appears in the Score before the other large photos, it is the first to download. Understanding how this works will help you to order your Shockwave movie to fit the needs of your project. Place the elements you want to appear first (such as the thumbnails in the Mars Rocks! sample) higher up in the Score and place elements that can be deferred until later, lower in the Score.
Creating a Status Bar Using streamStatus
One of the surest ways to keep a user on the hook through the download process is to provide them with up-to-date feedback on how long the download will take. Nothing does that better than a good-old thermometer-style progress bar.
In this technique, I'll show you how to create a loading-status bar by
pre-fetching the first frame of a movie which contains the status bar
graphics. The Lingo, streamStatus is used to monitor the download
of the movie and create the necessary information to update the status
bar.
See this technique in action:
First, let's look at how the first frame is set up.
The red bar is a graphic 150 pixels wide x 10 pixels high,
as seen here. This graphic is intentionally kept very basic to keep the
file size as small as possible in order to insure a quick download of
the first frame. Next, in a movie script, I've placed a
prepareMovie script. In this script, which is activated before
the movie starts playing, I set the width of the red bar (sprite 22) to zero
(see script below). What we'll be doing here is, using the information
reported by streamStatus, calculate the percentage of data that
has been downloaded so far. Using that percentage, set the width of the
red bar graphic to the percentage of its full width (150 pixels). This
will be done within the streamStatus handler.
In addition to setting the width of the red bar to zero, the
prepareMovie handler does two more important things. First, it
issues the tellStreamStatus(TRUE) command. This command turns on
(enables) the streamStatus reporting. Without this command,
nothing would be reported using streamStatus. And secondly, the
text of the field called "Percentage" is emptied. This field is a text
field that appears on Stage that will contain the numerical percentage
as the movie streams.
Let's take a look at the streamStatus handler:
Before we discuss the handler, let's talk a bit about how
streamStatus works. Like other event handlers (such as
startMovie or exitFrame) that are triggered by
events that take place in the movie, streamStatus runs continuously as the
file is streamed. But unlike other event handlers, it also gathers some
very useful information about the file being streamed.
As you can see from the above example, streamStatus reports the
URL of the data being streamed, the state of the streaming data, the
number of bytes streamed so far, the total number of bytes in the file
to be streamed, and an error check. We'll only be using a few pieces of
this information, specifically: state, bytesSoFar and
bytesTotal.
In the first line of the streamStatus handler, we check the
state of the streaming file. The state parameter
reports back a variety of conditions: Connecting, Started,
InProgress, Complete, and Error. In
this case, I want to simply check to see if the streaming is
complete. If it is, I send the movie to frame 2 which contains
the four thumbnails. If the state parameter does not equal
complete, the status bar and percentage field are updated in the
else portion of the if...then statement.
This is done by first setting a variable called percentNow to
equal the bytesSoFar divided by the bytesTotal. For
example, if the total byte size of a movie is 100,000 bytes and 20,000
bytes have been downloaded so far, the value contained in
percentNow would be 0.2 (or 20 percent). Note: the numbers
contained in bytesSoFar and bytesTotal are just
strings of text to Lingo, it doesn't know we want to use them as numerals in a
mathematical expression. Using the float command converts the
strings into floating-point numbers, so they can be mathematically
divided.
Next, we set another variable called spritePercent to equal the
number contained in percentNow (0.2 in our example) multiplied by
150, which is the full width of the red bar (the width it will be at
100% completion). The integer command is used here to convert the
resulting calculation to a whole integer, rather than a floating point
number. In our perfect little example above (where the percentage equals
0.2) the spritePercent variable would equal a nice round 30,
unfortunately in the real world things would not be so clean. If the
total file size of the movie was, say, 102,546 bytes, and the bytes so
far were 20,354, using these numbers as an example, the resulting number
in percentNow would be .1984865, multiply that by 150 and
spritePercent equals 29.772975. Using the integer
command converts that number to a nice round 30.
Next, the script sets the width of the red bar (sprite 22) to equal the
number in spritePercent (in our example 30 pixels). After that,
the script multiplies percentNow by 100 (essentially moving the
decimal point over two spaces), makes a whole integer out of the number
and sticks it, and a percent sign (%), into the field called
"percentage." In the example above (where percentNow equals
.1984865) the result in the percentage field would be "20%." Her again,
the integer command rounds out the number.
Lastly, once all these calculations are done and the changes made, the
Stage is redrawn using the updateStage command.
Loading Cast Members on an as Needed Basis
The last technique I want to discuss concerns the idea of downloading media on demand (only as needed). Using this technique, you can set up a situation where you load a portion of the movie to start with and download other portions only as requested by the user. Take a look at this sample, to see what I mean:
In this movie, only the thumbnail interface was downloaded, and the large images downloaded and displayed only when requested by clicking on the thumbnails. This results in a much smaller file size, than in the previous six examples (30 Kbytes vs 265 Kbytes).
This technique is accomplished with two Lingo commands:
preLoadNetThing and netDone. Let's take a look at how
these commands work together in downloading the large images.
When any of the thumbnails in this movie are clicked on, it calls an attached sprite script. For example, here is the script for the Yogi thumbnail:
The first thing this script does is set a variable called
myFileName to the location of the large file on the Internet.
This is done so the URL can be used with the preLoadNetThing
command in the next line of the script, and in the enterFrame
script discussed next. (Note that the three variables in this script are
all global variables and therefore must be declared before they are
used. See source code for usage.) In this next line, a variable called
myNetID is set to a unique ID for this download. Each download
called by preLoadNetThing is automatically assigned a unique ID
number by Director (i.e., 1, 2, 3, 4, etc.). This line of the script,
then, serves two purposes: First, to put this unique ID number into
myNetID; and second, to start the download of the file.
The last line of this script sets another variable called
clickFlag to one (1). If you examine the source code for this
movie, you'll see that at the start of the movie, clickFlag is set to
equal zero (0). This variable is simply used as a flag for the script in
the enterFrame handler which I'll explain next.
The EnterFrame Handler
In the Score Script channel of the frame that contains the thumbnail
images is the following enterFrame script. This script is
executed each time the playback of the movie passes through the frame
(roughly 30 times per second depending on the speed of the user's
machine).
The first line of this script checks to see if the clickFlag
variable equals one (1). If so, it executes the remaining commands; if not,
nothing happens. The reason for this flag is that we want the commands
to be executed only if the user has clicked on one of the thumbnails.
Setting the flag to one when the thumbnail is clicked on, and back to zero
when the script is done, ensures that the commands will only be executed
when appropriate.
The next line checks to see if the download of the file is complete.
This is done with the netDone command. The netDone
command returns TRUE if the download identified by the unique ID number
contained in myNetID is complete.
If the download is complete, the filename of the Cast member called
"placeholder" is replaced with the file name of the URL contained in the
variable myFileName (set earlier in the mouseUp
handler). The place holder graphic is just a simple, blank graphic positioned on
the Stage and turned invisible. This place holder gives the movie a
positioning in which to place the incoming graphic. Once the new
downloaded graphic is in place, the channel which contains the place
holder (sprite 10) is turned visible, making it appear on the Stage.
Lastly, the clickFlag variable is set back to zero.
Using These Techniques in Your Projects
By now you should have a decent understanding of many of the strategies for streaming movies and graphics using Shockwave. Of course, the solution you use will depend solely on the nature of your movies. In general, these are some of the basic techniques that you can use to build upon to solve the unique needs of your projects. Please download and examine the source code for these examples and feel free to use any of the scripts in your projects. If you come up with any clever uses of these techniques, be sure to let me know about them.
Copyright © 2012 Robert Schmitt. All rights reserved.