{"id":51,"date":"2010-03-26T13:19:40","date_gmt":"2010-03-26T11:19:40","guid":{"rendered":"http:\/\/blog.teleranek.org\/?p=51"},"modified":"2025-06-29T12:29:29","modified_gmt":"2025-06-29T10:29:29","slug":"flash-movie-swf-launcher-in-air","status":"publish","type":"post","link":"https:\/\/blog.teleranek.org\/?p=51","title":{"rendered":"Flash movie ( swf ) launcher in AIR"},"content":{"rendered":"<p>I wanted to make some kind of loader, which loads swf file, and accompanying asset files ( like for example dynamically loaded images or xml configuration files ) from one zip archive. Then we could have only 2 files &#8211; loader file and an archive with an application to load, instead of bunch of folders and files.<br \/>\nI wanted to make it cross-platform, so I&#8217;ve tried to do it in Adobe AIR ( standard flash player won&#8217;t allow us to create any files or folders ).<br \/>\nIt would also serve as a Flex to AIR converter, becasue you add your Flex application&#8217;s files to data.zip archive, launch our AIR loader, and you have your Flex application running in AIR, without need to change xml files and so on.<\/p>\n<p>We have AIR&#8217;s <a href=\"http:\/\/www.adobe.com\/livedocs\/flash\/9.0\/ActionScriptLangRefV3\/flash\/filesystem\/File.html\" target=\"_blank\" rel=\"noopener noreferrer\">File<\/a> class, which allows us to create folder and files.<br \/>\nSo the basic idea is:<\/p>\n<ul>\n<li>unpack data.zip into some temporary directory ( <a href=\"http:\/\/www.adobe.com\/livedocs\/flash\/9.0\/ActionScriptLangRefV3\/flash\/filesystem\/File.html#applicationStorageDirectory\" target=\"_blank\" rel=\"noopener noreferrer\">File.applicationStorageDirectory<\/a> is recommended by Adobe lang reference&#8230; )<\/li>\n<li>run some .swf file found in unpacked files.<\/li>\n<\/ul>\n<p>Yes&#8230; No. That&#8217;s not possible. You cannot run files from appStorageDir. Stupid sandbox violation errors will appear. SandBox in standalone applications&#8230; gr8 idea.<br \/>\nYou will think of a hack: Let&#8217;s load this swf into <a href=\"http:\/\/www.adobe.com\/livedocs\/flash\/9.0\/ActionScriptLangRefV3\/flash\/utils\/ByteArray.html\" target=\"_blank\" rel=\"noopener noreferrer\">ByteArray<\/a>, and then execute this ByteArray using Loader class!!!<br \/>\nfor example:<br \/>\n<code>var ldr:Loader = new Loader();<br \/>\nvar fstream:FileStream = new FileStream();<br \/>\nfstream.open( YOUR_SWF_TO_LOAD , FileMode.READ );<br \/>\nldr.load( fstream.readBytes() );<\/code><br \/>\n&#8230; Ok, it will run, but it won&#8217;t see any other files you&#8217;ve unpacked. Suppose we have <strong>config.xml<\/strong> in applicationStorageDirectory. It won&#8217;t see this config.xml, it will only see files in applicationDirectory &#8211; directory where our loader resides.<br \/>\nOk: so let&#8217;s abandon this useless applicationStorageDirectory, and unpack everything to applicationDirectory. You think they will let you? Ha! You ingenuous little developer. They of course knows better what&#8217;s good for you. You can&#8217;t write to <a href=\"http:\/\/www.adobe.com\/livedocs\/flash\/9.0\/ActionScriptLangRefV3\/flash\/filesystem\/File.html#applicationDirectory\" target=\"_blank\" rel=\"noopener noreferrer\">applicationDirectory<\/a>. They say &#8220;it&#8217;s a bad practice&#8221;, and they also say &#8220;better use applicationStorageDirectory&#8221; They also say <a href=\"http:\/\/livedocs.adobe.com\/flex\/3\/langref\/flash\/filesystem\/File.html#applicationDirectory\" target=\"_blank\" rel=\"noopener noreferrer\">&#8220;make sandbox bridges to run active content from applicationStorageDirectory&#8221;<\/a>. Sandbox bridges? This just some trivial feature in HTMLLoader class. SWF which runs in HTMLLoader is rendered by built-in flash AIR browser, and it runs 10x slower than it could in pure standalone flash player.<br \/>\nOk, so we are still stuck with the problem &#8211; how to run this swf in AIR &#8211; and another problem &#8211; we can&#8217;t write to applicationDirectory. But wait&#8230; we can write to any other directory&#8230; So we can write to applicationDirectory too.<br \/>\nThis is so stupid &#8230; Look, this causes security exception:<br \/>\n<code>var new_directory:File = File.applicationDirectory.resolvePath( \"some_new_directory\" ); \/\/ create path to \"some_new_directory\" in our loader's directory<br \/>\nnew_directory.createDirectory(); \/\/ &lt;---- ERROR<\/code><br \/>\nAnd this doesn&#8217;t:<br \/>\n<code>var new_directory:File = new File( File.applicationDirectory.resolvePath( \"some_new_directory\" ).nativePath );<br \/>\nnew_directory.createDirectory();<\/code><br \/>\nWe basically create new File object, with path equal to File.applicationDirectory\/some_new_directory, but flash doesn&#8217;t know it&#8217;s our apps dir, so it doesn&#8217;t throw an exception. The rest is obvious &#8211; we execute .swf using File.applicationDirectory, because all files we need are actually in our application&#8217;s directory. And this is the simplest possible detour for these unnecessary sandbox &#8220;feature&#8221;.<\/p>\n<p>And finally I&#8217;ve made this AIR swf loader, but&#8230; It appears, that files you load into AIR application has fewer fps, than they could have, when run stand-alone.<br \/>\n<a href=\"http:\/\/blog.teleranek.org\/wp-content\/uploads\/2010\/03\/telelauncher.zip\">These are<\/a> the mxml sources, along with some additional dependencies, in case you&#8217;d ever want to load some swf&#8217;s dynamically from AIR.<br \/>\nIt depends on &#8220;newzip&#8221;, nochump&#8217;s zip loading library, which I&#8217;ve modified slightly, to support asynchrounous loading ( then if you&#8217;ll have 30MB zip, your flash won&#8217;t hang due to timeout exception ). Just build .air package along with your data.zip archive ( the .swf files to launch ) and you&#8217;re ready to go. Sample data.zip included.<\/p>\n<p><a href=\"http:\/\/blog.teleranek.org\/wp-content\/uploads\/2010\/03\/telelauncher.zip\">sources<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to make some kind of loader, which loads swf file, and accompanying asset files ( like for example dynamically loaded images or xml configuration files ) from one zip archive. Then we could have only 2 files &#8211; loader file and an archive with an application to load, instead of bunch of folders [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[55,56,18,57],"class_list":["post-51","post","type-post","status-publish","format-standard","hentry","category-flash-experiments","tag-air","tag-applicationstoragedirectory","tag-as3","tag-sandbox-violation"],"_links":{"self":[{"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/posts\/51","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=51"}],"version-history":[{"count":7,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/posts\/51\/revisions"}],"predecessor-version":[{"id":355,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=\/wp\/v2\/posts\/51\/revisions\/355"}],"wp:attachment":[{"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=51"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=51"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.teleranek.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=51"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}