(Perhaps) Unexpected Point of View: SWF Defers to HTML
Ever aiming for a small SWF footprint, I often load external assets at runtime. This includes FLVs, MP3s, XML, sometimes CSS, and frequently images (which even includes PNG — woo hoo! — since the release of Flash Player 8). As often as not, I use a relative path to specify the location of an asset. This means the resolution of that path depends on its position in relation to the SWF itself. For example, with something like mc.loadMovie("external.jpg");, it only makes sense that the SWF with this ActionScript must reside in the same folder as the JPG it loads. Why? Because no absolute path to the JPG is provided — how would the SWF possibly know where else to look, other than its own folder?
If the SWF was in one folder and the JPG in another, you’d have to provide a path to that location. For example, if the SWF was inside a folder named swf and the JPG was inside a subfolder of the first — say, swf/images — you would have to specify mc.loadMovie("images/external.jpg");. The SWF would interpret that as, “Okay, start from where I am; now, look for a folder named ‘images,’ then look for external.jpg.” If the images folder was side-by-side with the swf folder, the relative path would instead be mc.loadMovie("../images/external.jpg");; that is, “Ah, back up one folder [that’s what the .. means], then look for a folder named ‘images,” then look for external.jpg.” All of this should be pretty straightforward, and it always works when the HTML document is also in the same folder as the SWF. But there’s the rub: what happens if it isn’t?
This may be counter intuitive, but a SWF’s point of view is not its own when embedded in an HTML document. When embedded, the SWF’s point of view is that of the HTML document itself.
Let’s look at an illustration. Suppose you have an HTML document in the root of your site. This document embeds a SWF contained in a subfolder of the root. (I like to do this, for example, to separate my HTML files from my SWFs; I do the same with images.) If the SWF references a JPG from the point of view of itself (such as the same folder as itself, without a path reference, as above), the JPG will not load when the SWF is tested from the HTML document.
To restate: HTML is in the root; SWF and JPG are in the same subfolder, which is a subfolder of the root. SWF references JPG without a path, or with a relative path that relies on the SWF as its point of reference. JPG will load when you run the SWF on its own, but will not load when you run the SWF from the HTML.
Why? Because the ActionScript says mc.loadMovie("external.jpg");, and remember, the point of view is now that of the HTML document, so the SWF will look “through the eyes” of the HTML document in order to locate that JPG.
You could bypass this trouble altogether by using an absolute path, such as …
mc.loadMovie("http://www.domain.com/images/external.jpg");
… but that means you’d have to upload your JPG to the server in order to test your ActionScript. You could alternatively get fancy and let the SWF determine whether or not it’s playing in a browser. The System.capabilities object comes in handy here …
if (System.capabilities.isDebugger) {
this.loadMovie("external.jpg");
} else {
this.loadMovie("images/external.jpg");
}
… but that may be overkill in this context.
You could, of course, just be aware of the issue and make your own best judgment.
For you, that may mean keeping all three files in the same place, putting the JPG in both locations, or … heck, it’s up to you.
Update!
Note: As recounted in Unexpected ”Gotcha“ with Relative Paths in ActionScript, I discovered the above holds true except for Flash video files (FLV).
October 23rd, 2006 at 12:03 pm
this article saved me a ton of time. Just wanted to say thanks.
October 29th, 2006 at 5:58 am
thanks for writing this, wish I’d found it sooner (I wasted about 3 hours on this). You’re right about the file path not being obvious. (though it is once you know)
December 13th, 2006 at 11:05 am
As you specify here the swf refers to files from the html’s (or main swf’s) point of view.
I am very new to this and have got a problem. I have root folder where my main swf is located. I would like to know how I make another swf in a sub-folder refer to another swf in the same sub-folder without always having to type the entire path?
In that way I can make a template that I can copy to other subfolders without having to retype the path 1.000 times.
I hope this makes sence.
- Simon
December 14th, 2006 at 3:02 am
Simon,
If I understand what you’re saying, you’re hoping for a way to tell the main SWF what sub folder another SWF is in — but you want to do that without specifying that sub folder’s name. I can’t think of any way to do that. Clearly, you’re going to have to mention the folder’s name at least once. Once you’ve done that, you can continue to use that same path, of course. You could store the path in a variable. In fact, you could even specify the value of that variable from outside that SWF. Maybe that’s what you’re after? Check out this article, which may get you started.
March 14th, 2007 at 1:13 am
hi david.
was trolling adobe’s flash forums and saw the link to this article. i’m having a problem with my skin not showing up as well. wondering if you have any advice.
my flash is simple: www.gaming11.com. it plays a video and then buttons appear at the end, one of which leads to the registration page of my website. when i publish the .fla with “publish settings->local playback security” set to “access local files only”, the skin shows up just fine (ie. when i play load the Flash generated sliver of html that contains the .swf). however, when i click on the button at the end, i get a dialog that says the .swf is trying to access the internet and that i have to change my settings first and restart.)
now if I publish the same .fla but with “publish settings->local playback security” set to “access network only”, then the button at the end works fine but my skin doesn’t show up. now i’m sure that the skin’s .swf is in the same folder as the actual .swf itself.
any help would be much appreciated. thanks!
March 14th, 2007 at 2:19 am
David,
We figured it out. it now works in our dev environment. no need to reply but thanks for this very helpful article int he first place.
June 9th, 2007 at 12:38 am
Hi David,
I gotta typical problem here. I have several multimedia applications made in flash. Each application inturn calls hundreds of smaller swfs which reside in their same folder as the applications and they work well within the application. Now I wanted a single menu that calls each application’s starting swf. Upto this it is fine the menu calls the first swf. The rest of the swfs are not called. And I am in no mood to re-publish each set of those hundred swfs with additional path prefix.
Is there a method or a workaround like setAppPath(”//New Application”) before calling a loadMovie()
menu.swf
//App Folder1
1.swf
2.swf
3.swf
…
//App Folder2
1.swf
2.swf
3.swf
…
June 18th, 2007 at 9:29 pm
To alex leung …
Glad you figured it out!
To Santanu …
Sorry for the delayed reply! I’m still settling in after a dynamite trip to Las Vegas for TODCon. Unfortunately, there isn’t a
setAppPath()function in Flash (if memory serves me, Lingo offers something like this for Director). But maybe I don’t get what you’re asking. Were all these files originally in one place, and now they’re in another? It shouldn’t really matter, either way, as long as the menu knows where each file is. If it helps, you can certainly declare a string variable — say,appPath— and precede your various SWFs with that variable. You can set it to an empty string ("") for SWFs that are in the same folder as the SWF that loads them, and populate it with partial paths to SWFs in other locations.September 13th, 2007 at 3:38 am
Champ! I cant believe I had to trawl the web forever!
Problems all sorted cause of your simple explanation.
Thanks
January 7th, 2008 at 5:14 pm
What I usually do to solve this problem is give the swf the html’s relative path via FlashVars. Inside the swf there is a default path that would be used if there is no Flashvars’s path (meaning you’re using the projetor in the developer enviroment).
This way I always use relative paths (except for uploading/downloading files, which strictly requires http(s); hence you need the full path).
Cheers,
Gorka
http://www.AquiGorka.com/blog
January 13th, 2008 at 1:13 pm
To Shaun …
Hoo hah! Glad to hear that.
To Gorka …
That’s a great idea! Thanks for sharing that.
February 3rd, 2008 at 7:00 pm
My dear friend
Thank for god idea and sharing this work.
February 3rd, 2008 at 8:30 pm
kral,
Sure thing.
November 13th, 2008 at 8:00 am
I can’t think of any way to do that. Clearly, you’re going to have to mention the folder’s name at least once. Once you’ve done that, you can continue to use that same path, of course. You could store the path in a variable. In fact, you could even specify the value of that variable from outside that SWF. Maybe that’s what you’re after?