Little Sign
Joe Sparks <>

Director MX Tutorial 1: Dynamic Use of External Media
by Joe Sparks

Part 1

* This extremely useful technique gives your project run-time access to a wide variety of media types

Director can dynamically import and use external files at run-time. It can pull the file from the user's hard drive or any accessible volume, and from any accessible web address. It can grab a wide variety of video, audio, graphic, and Flash files, and even other Director movies, then bring them inside your running project to be used, just like any other asset in your cast library. This core ability is what makes a project like "Postcard Maker" possible.

The basic lingo command behind this functionality is:

member(whichCastMember).fileName = "fileName"

The filename is a cast member property, which can be tested and set to either a path name (absolute or relative) or a URL. Here's a few ways you might see it in a script

-- relative pathname to the file:
member(1, 1).fileName = "@:audio/startsound.mp3"
-- URL to the file:
member("StartUpImage).fileName = ""
-- File is in same directory as Director movie:
the fileName of member "SpotAnimation" = "LogoAnimation2.swf"

The core is quite simple, however, there are many surrounding techniques and issues to the efficient usage of this command, and it can become complicated. The aim of this tutorial is to sort out the basic issues for you.

Let's start with the simplest kind of usage, a random image displayer. The movie below, called "LuckyNumbers," contains one linked bitmap member, and a script that will change the filename of the default linked member to a random image from a list of 10 jpeg files.

Click on my name above, and send me
a little note! Let me know what you think!

Source Director Files Here

Step by step creation of "LuckyNumbers" example.
1. Created 11 images: 1 default image and 10 images to represent the numbers zero through nine.
2. Created a project folder, with one sub folder to contain the images

3. Started a new Director MX movie and saved it into the project folder as "LuckyNumbers.dir"
4. Imported the default image "startup.jpg" as a linked cast member.

5. renamed imported member to: "DynamicMember"
6. Dragged the default image to the score, and extended the resulting sprite out to frame 40.
7. I wrote this movie script:

( Download RTF formatting script here: ScriptExample1.rtf )

global gImageList, gImageHistoryList
global gDynamicMember, gImagePath, gDefaultImagePath
on startMovie
-- creating the list of images
gImageList = []
-- a way of populating the list with image file names
repeat with x = 0 to 9
add gImageList, x & ".jpg"
end repeat
-- duplicating the list to force a different image than
-- the previouly displayed image, in case of rewind

gImageHistoryList = duplicate(gImageList)

-- defining the member to change:
gDynamicMember = member("DynamicMember",1)

-- defining path to images:
gImagePath = "@/images/"

-- saving start up image:
gDefaultImagePath = member(gDynamicMember).filename

on PickRandomImage
-- if we have dispensed all of the images, reset the list to original
if gImageHistoryList.count = 0 then
gImageHistoryList = duplicate(gImageList)
end if
-- counting everything in image list:
tTotal = gImageHistoryList.count
-- getting random number based on total in list:
tRandomNumber = random(tTotal)
-- pulling out the image file name:
tImageFIleName = gImageHistoryList[tRandomNumber]

--constructing path to image:
tPathname = gImagePath & tImageFIleName

-- setting the filename of the default cast member
member(gDynamicMember).filename = tPathname


-- gets called by rewind button:
on StartOver
go 1

on resetStartupImage
member(gDynamicMember).filename = gDefaultImagePath

8. Added markers, a "go marker(0)" loop back, and a rewind button

(Note: The demo above is playing in shockwave, even though it was not build for running over the internet. To really be Internet-worthy, we would need to preload the images before reseting the filename.)

What is this technique good for? Dynamically linked media is perfect and extremely practical for any type of media library situation, where you need random access to one or all of a large batch of pre-existing media files. Projects along these lines include, a sound-sample library browser, a video kiosk, a photo or clip art library, or any project where you have a bulk of media that needs to be tapped into incrementally. Another type of need is with a project that asks its users to specify which of their own media will be imported and used.

The Postcard Maker project has both types of needs. Users need to be able to browse and use a pre-existing library of external clip art files and also, to pick and use their own graphic files.
Before we delve into "dynamic linking," let's define "run-time" versus "author-time" (or "in authoring"). Run-time refers your finished project running "live" as it will be used by your audience, outside of the Director Authoring application itself, through a finished projector or from within Shockwave. Author-time refers to the time in which you are editing and developing your project from inside of Director, before the project is complete.

Next, let's talk about "dynamic" versus "fixed." At author-time, you can import a file as "linked." The file will show up in your cast library, and can be used like any other fully imported cast member, yet Director does not import the file into the movie, it only stores the "link" (the path to the file), and the data remains external to your project. If you never change this link, then we could refer to this linked cast member as "fixed," in other words, the path to the external file does not change while the movie is playing. "Dynamic" refers to the changeability of any file link, the ability to switch to another file on the fly.

* External media handling: Flash Vs. Director

How does Director MX differ from Flash MX in regard to dynamic use of external media? Flash MX is the first version of Flash to allow some run-time linking to external media, but it still has a long way to go before it can match Director's broad support for multimedia file types. While Flash can import and use a wide variety of media in authoring, the Flash MX Player can only make use of external MP3 files and non-progressive JPEG files at this time (and also, swf files, of course). Director, on the other hand, can make run-time use of all flavors of jpeg, gif, pict, bmp, png, psd, mp3, aif, wav, mov, avi, real media, swf, dir, dxr, dcr, and other formats.

* Too many Internal cast members can quickly cause problems

By default, when you import assets (graphics, sounds, etc.) into your director project, Director will embed the assets into the cast library (the main exception being Digital Video files, which are always kept external). When you save the Director project as .dir file, a single file will be written that contains all of your imported items.

Imagine how impractical it would be to import all of your assets into Director, if you were working with a very large library of photos, for example. Imagine 600 megabytes of digital photos inside a single .dir file. If you only changed a tiny piece of text, you would have to write 600 megs to the hard disk to simply do a "save as" on your movie. Tracking & archiving versions of your project over time would be a nightmare! The entire development process would slow to a crawl. It is best to leave a dense quantities of media separate from your director project.

Spotting a linked member in your Director MXCast Library:

You might try to bring your multitude of media files into the cast library as linked cast members (by choosing "Link to External File" in the import dialog). The bulky media data stays separate from Director, yet you would have convenient access to all the files in the cast library. There are problems with this approach. Depending on the number of members this entails, the performance drag within Director (of generating, maintaining, and displaying all of those thumbnails in the cast) could be cumbersome during authoring. You would need some very good reasons to warrant the "pollution" of your cast library your cast with excessive numbers of members, even if they are linked to external files.

Part 2

* Methods for creating creating new cast members "on the fly."

A better plan (for handling a large bumber of external members) would be to create new cast members and link in the external media on demand, as it is needed. This technique will work for a big known media library, and just as well for the situation where the user is going to introduce new, unknown files into the mix.

Below, is an example of this technique, running in Shockwave. Please give it a try. This Director movie has only 1 bitmap member in the cast- plus a few scripts and UI elements. One field in the movie holds a list of external files, each file sitting in a folder in the same directory as the dcr (shockwave movie file). To import a file from the list, simply click on its name. You can keep clicking until you have imported all of the files in the list:

Download Source HERE

There are several key things going on inside this movie, Please download the source files, and open it inside Director MX, and look through the highly commented code. If you are new to lingo, it may look complicated, but actually it is just densely commented, and many aspects are highly defined, with items grouped into list containers, much in the way I would do in an much more advanced project.

Key features to examine in the lingo:

1. Using an external text file as a media menu

An external text file is used to get the list of media available to the movie. On startup, the movie downloads a text file called "medialist.txt" The file's text looks like this:

Blue_JPEG.jpg, #bitmap
Hello_JPEG.jpg, #bitmap
HI_PNG_32.png, #bitmap
I_am_GIF.gif, #bitmap
Pink_JPEG.jpg, #bitmap
I_Am_Flash.swf, #flash
sf_sky.jpg, #bitmap
SF_Sunset.jpg, #bitmap
joes_rddbook.jpg, #bitmap
bird.jpg, #bitmap
BDalpe.jpg, #bitmap
ScaryBarrie.jpg, #bitmap

The first line is the pathname to the media. The rest of the lines are names of files, followed by the TYPE of cast member that should be created to contain the media file.

I chose this simple method of listing the media in a simple text file, but the data could come from anywhere. It could be inside director as text, or you could make a database call to a server. A text file is a simple thing, and you can easily change it, re-upload it, and the shockwave movie will adapt to the new text file. This is very convenient was to update and maintain existing director projects!

Try this: After you download the source, and run the the demo inside director, open the text file "medialist.txt" inside of the project folder. Add this line on a new line, anywhere AFTER the first line:

JoeFococcia.jpg, #bitmap

Save the text file, rewind and run the movie again. This new item (an extra file I added to the media folder), will now be available to the director movie. You could add your own files to the folder and text file, and see how they work. (It was designed to hold 128 x 128 sized items).

2. Carefully preloading the external media file before attaching it to a cast member

To make this safe for shockwave and over-the-internet downloading, I used the net lingo command "preloadnetthing" with waiting scripts that check the status of the download. I wait until the requested file is completely downloaded before assigning its file name to a cast member. A great thing while testing & developing- Director's net lingo works fine offline (locally) too, so the same movie will work off a hard drive, in a projector situation, as well as over the net. Here is the two step process...

Step 1:

gNetID = preloadNetThing(directorypath/something.jpg)

That lingo command initiates the download of the external media item. The status of the download is stored and updated in the global variable gNetID (you could name that variable anything, but make sure you delcare: global gMyVariableName some where neear the top of your script).

Step 2:

Next we have to periodically check on the status, so step 2 is to regularly check for the the status of the download, and when done, use the file. I call the script below from a frame script. If the member is not ready, the script loops back to a frame. (This is a commented handler straight from the demo source) :

-- this gets called from a frame script, to check
-- progress of the file download.

on waitForExternalItemToDL
-- not doing error checking
-- tError = netError(gNetID)
-- put tError

-- MAIN PART: checking to set if file is ready to be used:
if netDone(gNetID) then
-- The download is done, so now we are free create a new
-- member (calling custom handler):

-- calling sprite display handler:
PrintASprite gCurrentExternalMediaL
-- jumping away from waiting part of score, to area where user
-- can pick a new file (only allowing one download at a time):

go "PickFiles"
-- looping back to a marker in the score (which I prefer to do,
-- iinstead of looping on a single frame)

go "DownloadingItem"
end if

3. Using the New() command to create new cast members

Let's look at the Lingo Dictionary listing for the New Cast member command:

new(type, castLib whichCast)
new(type, member whichCastMember of castLib whichCast)
variableName = new(parentScript arg1, arg2, ...)
new(script parentScriptName, value1, value2, ...)
timeout("name").new(timoutPeriod, #timeoutHandler, {, targetObject})
new(xtra "xtraName")

As you can see, the New() command can be used in a variety of ways to create new cast members (and many other things) from lingo, on the fly. Here is how I use it in this demo:

tMember = new(tType, castLib gImportCastLib)

"tMember" is a variable that will hold the resulting location of the member (member number and castlib name). This gets returned by Director, after the new member is created.

"tType" is a variable I set earlier, which contains the cast member type to create (in symbol form). In this case it will be either #bitmap or #flash. This type is something I defined in the "medialist" text file. You could ascertain the type of member in many others ways, from parsing the file name for the extension, or by asking the user to define, and so on. It is very important to create the right kind of cast member to contain your external media file! If you try to set a #bitmap type to a .swf file, it will not work. The type has to match up with the supported external file, and in the case of a .swf file, the type would be #flash.

"gImportCastLib" is a variable that holds the name the name of the castlib I want to add my new members to, in this case, it is the second castlib. When you have dynamic members being continually being created and destroyed, it really simplfies things if you have a blank, free cast library reserved for this activity. This can ease fears that you might accidentally tread on existing members in your main movie.

4. Assigning the filename to the newly created member

The last step of dynamically creaing linked members is setting the filename property of the new cast member. In this demo, it look like this:

tMember.filename = gCurrentExternalMediaL.fullpath

That doesn't make much sense, because that values are obscured by my variable names. Let me write it out with example values instead of variables:

member( 1, 2).filename = "@/media/photo.jpg"

There's that simple command, from the beginning of this tutorial. Only now, however, is it safe to use it. We've know where the file is, we've used that information to download it, we checked on the progress of the download, and now that it is ready, we can finally set the filename safely.

Please check out the source files for this demo, and read through the code. The above process can be used to dynamically access many other kinds of media. I hope you find this information useful on your future projects in Director MX!

Here is a few highly recommend links to related information about this topic:

Use preloadNetThing before importing external media

What does preloadNetThing look like in action?

Lingo limits safe mode

Using the searchPath in Director

Best Wishes, Joe Sparks