Unexpected “Gotcha” with Relative Paths in ActionScript
About a month ago, I mentioned a quirky fact of life when dealing with relative paths in ActionScript. In a nutshell, a SWF’s point of view changes depending on how it’s embedded. A SWF considers relative paths from its own folder when played in a Projector. That makes perfect sense. On the other hand, a SWF embedded in an HTML document, as played by the Flash Player plug-in, sees things differently. To a SWF in an HTML document, relative paths begin from the folder of the HTML document.
For example, if a root HTML document embeds a SWF in a flashcontent subfolder, and if that SWF loads a JPG from the same folder as itself, the ActionScript must nevertheless include a reference to the flashcontent subfolder — because that’s where that JPG is located from the HTML’s point of view. This can quickly confuse matters when you test the SWF from inside Flash, because the Flash IDE plays SWFs inside a special Projector (see (Perhaps) Unexpected Point of View: SWF Defers to HTML for some workarounds).
That’s a “gotcha” enough already, but I just discovered an exception to the rule.
An HTML-embedded SWF considers relative paths from the folder of its HTML file unless … unless you’re loading an FLV (Flash video) file. For some reason, FLV references — even in HTML-embedded SWFs — start from the SWF’s own point of view. This is true of the FLVPlayback Component and also a plain vanilla Video object.
August 26th, 2006 at 7:52 am
I’ve recently hit the same problem when an external SWF is dynamically loaded into a projector. The ‘main’ swf/projector folder is taken as the starting point for relative paths and the fact that the loaded swf was in a sub folder is ignored. So, once loaded into projector, the external swf could no longer find its resources.
I am new to Action Script and this totally threw me for almost a day while traced _urls and tested and retested. Being new, I thought I was doing something wrong.
August 26th, 2006 at 9:21 am
Steve,
Hey, the important thing is that you solved it!
I was getting so frustrated, I had to step back and follow the same advice I often give people on the Adobe forums: set the current project aside, start a brand new FLA, and isolate the problem from whatever else is going on. Try to reproduce it in the new, “quieter” environment. That’s what did it for me.
October 15th, 2006 at 4:30 pm
Here’s an easy way to make all relative paths absolute:
_global.p = _url.split(’/').slice(0,-1).join(’/')+’/';
So when you have: “images/file.jpg”, you would instead use p+”images/file.jpg”
This way, you can type all the paths as if they are relative to your swf, but it will be in the end, absolute.
March 13th, 2007 at 7:24 pm
Hi guys,
I had a problem that my FLVs were not loading from my web server using a relative path, but I tried your advice and referenced it as though it was in the same place as my HTML that’s loading the swf. It now works, thanks for your help!
- Jackson
September 14th, 2007 at 6:55 am
I tried to put NSurveyor’s code (_global.p = _url.split(’/’).slice(0,-1).join(’/’)+’/’;) on my main.fla but theres an error:
**Error** Scene=Scene 1, layer=Scripts, frame=1:Line 3: Operator ‘=’ must be followed by an operand
_global.p = _url.split(’/’).slice(0,-1).join(’/’)+’/’
Total ActionScript Errors: 1 Reported Errors: 1
Anyone knows how to fix that? Because i have a gallery.swf that loads into main.swf. The problem is that main.swf don’t know were the gallery.ml and gallery.txt are.
I hoped that these code could fix that…
September 14th, 2007 at 10:40 am
Pedro,
That code’s quotation marks got modified into curly quotes by the blogging software. Make sure, when using NSurveyor’s code, or anything like it, to use straight quotes (
"instead of“or”— same for single quotes).September 28th, 2007 at 11:33 am
I’m having a similar problem. I have other external files that need to be loaded in my swf:
#include “/includes/siPreloader.as”
#include “/includes/zoomPreloader.as”
#include “/includes/preloader.as”
#include “/includes/_hScroll.as”
#include “/includes/_vScroll.as”
#include “/includes/photo_gallery.as”
The above like shows the flash initially loading but it appears it’s not loading in the .as files.
Also this piece is using xml files to load in jpgs , htm files and captions for the photos. Here’s an example of one of the gallery.xml files:
Any suggestions??
THANKS!
September 28th, 2007 at 11:35 am
xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?
results imgFolder=”images/gallery_01/” htmFolder=”htm/gallery_01/”
item image=”ak_portage_meadow.jpg” thumbnail=”ak_portage_meadow.jpg” zoom=”ak_portage_meadow.jpg” htmURL=”FPO_01.htm”
item image=”ak_portage_glacier.jpg” thumbnail=”ak_portage_glacier.jpg” zoom=”ak_portage_glacier.jpg” htmURL=”FPO_02.htm”
October 1st, 2007 at 11:23 am
Gregg,
#includeis a compiler directive, which means it only comes into play at compile time, when a SWF is generated from its FLA source file. In other words,#includeis read by the FLA, not the SWF, so it doesn’t fall pray to any of the gotchas mentioned in this article or the earlier one. By the time your ActionScript is compiled into bytecode, the SWF is no longer aware of the#includedirective, because that’s what#includedoes: it tells the FLA to copy/paste the code it finds in external text files into the FLA itself, making that code indistinguishable from anything typed into the FLA by hand.Your included .as files need to be located in relation to the FLA source file. The JPGs listed in your XML need to be located in relation to the HTML document that loads your SWF.
October 25th, 2007 at 10:11 am
Glad I found this topic on your blog. I have one quick question about actionscript and relative paths… this may be a silly one, but I’m stuck.
I am trying to load an xml file into the swf via actionscript and the swf file is located in a folder AHEAD of the folder where the images.xml file is. So, I have been trying, for example, this relative path:
../images/images.xml
I am assuming that I cannot backup out of the swf folder to get to the images folder using “../” because its not working… or does it and I am doing this wrong? any help would be appreciated.
October 25th, 2007 at 10:23 am
Brian,
It sounds to me like your site has a swf folder and an images folder. I’m guessing your HTML files are in the root, and they references images like this:
images/someImage.jpg
… and SWFs like this:
swf/someSwf.swf
If that’s right, then from your SWF’s point of view, the XML document is here:
../images/images.xml
But that’s not how Flash works. The SWF takes its point of view from the HTML document that contains it. If I’ve correctly described the arrangement of your files, that would mean you’d drop the “../” in this case. The only exception to “the SWF’s point of view is actually the HTML’s point of view” is when the SWF is loading FLV files.
October 25th, 2007 at 10:39 am
Hi David,
Wow, thanks for the quick response.
actually, here is the file structure:
the index.html file, which calls the .swf file is located here:
/en/index.html
the swf file is located here:
/CommonScripts/myflash.swf
the images.xml and images folder are located here:
/CommonScripts/
right now the actionscript in the swf is “images.xml” and I understand that since the swf loads from the index.html, the “images.xml” means it looks in the
/en/
folder since that is relative to the html file.
what the heck do I put in there to reference the images.xml from the CommonScripts folder.
October 27th, 2007 at 9:28 pm
Brian,
Either use “../CommonScripts/images.xml” or simply “/CommonScripts/images.xml”, as the slash alone (preceding any path) should send the point of view to the root.
In the first case, the SWF effectively says, “Okay, I am where my HTML page is, so that means I’m in the ‘en’ folder. Let me back up one folder — now I’m in the root — and look for a folder named ‘CommonScripts,’ then a file named ‘images.xml.’”
In the second case, the SWF says, “Let me go straight to the root and look for a folder named ‘CommonScripts,’ then a file named ‘images.xml.’”
November 10th, 2007 at 10:57 am
Hi David,
I encounter an ugly phenomenon with Mozilla and relative paths.
The files are located in separate paths for html and flash related files:
webroot/html/showvideo.html
webroot/flash/player.swf
webroot/flash/skin.swf
webroot/flash/video.flv
So I embed
* player.swf relative to the .html
* skin.swf relative to the .html
* video.flv relative to the player.swf
This works fine as long as showvideo.html is opened locally in Mozilla.
When I open it via a host (webserver or localhost) it’s going weird:
Opening the file the first time (after clearing the cache) everything is ok.
But when opening again or pressing ‘Refresh’ or opening showanothervidedo.html to see anothervideo.flv there is no video and no skin displayed.
Even worse: Trying to see another video (video2.flv) with another player (player2.swf) and another skin (skin2.swf) from another html (showvideo2.html) on the same host fails.
To be true: I can see the skin for about a second, then it disappears into empty space.
To be completely true: sometimes the first picture of the video is shown.
The player.swf IS loaded (displaying some text).
Any idea what’s going wrong there?
Maybe I have to set some -parameters I’ve never heard of?
But why does it work once an then nevermore? Sometimes even clearing the cache doesn’t help.
Something wrong with the Flash-Plugin?
Because in InternetExplorer everything is fine. Only Firefox and Iceweasels do that!
It’s really the relativity - when all files are in the same directory there is no problem..,
I’m completely at a loss.
Mechthild
November 30th, 2007 at 8:26 pm
Hi David:
Great topic. We’re suffering a similar problem as those who have written here. We have a projector file running on a local machine. It calls an outside swf running on our CDN. That swf calls an .flv residing in the same folder as that swf on the CDN. The flv won’t load/play. There are no HTML containers anywhere along the path. We’ve tried absolute paths and relative paths. No luck.
The projector is the parent file, right? Then how do we reference the projector file locale from the outside swf that’s calling the .flv?
We are distributing a P2P product that will be a projector. It will call swfs that will call flvs. Thoughts?
–Dana
December 5th, 2007 at 3:50 am
My solution to the "Mozilla-doesn’t-play" phenomenon was to cancel using the FLVPlayback componet.
Decided to use NetStream with my own controls.
The vid_player from Datic was a good starting-point.
Found it at tutorials.de:
http://www.tutorials.de/forum/flash-faq/180861-sammel-thread-und-flash-faq-2.html
This is the ZIP-File with fla and swf:
http://www.tutorials.de/forum/attachments/flash-faq/16585d1117140120-vid_player.zip
Now everything works fine. And I like my own design…
Mechthild
December 7th, 2007 at 9:13 am
To Mechthild …
By your original description, it certainly sounds to me as if you had done everything right. In any case, I’m glad to hear you resolved the issue! Ultimately, I think you’ll be happier with this closer control over the video. And like you said, the visual design is now yours.
Thanks for sharing those links, too!
To Dana …
The Projector is indeed the parent, or the base of your file references. Obviously, you can’t use the Debugger panel when you’re testing a Projector (which is too bad!), but you can still arrange for something akin to
trace()statements in your Projectors. In a case like this, you could put a dynamic text field somewhere on the Stage for testing purposes. Give it an instance name, saydebugger. In your keyframe code, add the following line:… which invokes
MovieClip._urlon the main timeline (assuming that’s where your code is) and sends the return value to the text field. That will show you where the SWF believes itself to be, and if your experience is like mine, you’ll see a file reference directly to the EXE.That aside, if you’re distributing this as a professional product, you may want to consider a 3rd party Projector enhancer like ZINC or Jugglor. Not only with those allow you to customize the appearance of the executable, they’ll also give you system level functionality you can’t get with a native Projector alone.
December 7th, 2007 at 3:52 pm
David:
Thanks SO MUCH for your insight into this problem. We’ll also check out ZINC and Jugglor, for additional functionality of the Projector.
Best Regards,
Dana