AIR, HTML and SWF

I saw a couple of posts and questions on twitter where it seems people are confused
so here some details on stuff related to AIR, HTML and SWF

Disclaimer:
Don’t feel offended if I simplify too much and you already know all those stuff like the back of your hand, I’m just trying to keep thing “simplest” (even “dumb”) to defuse confusion, if people “feels like it” more advanced stuff can be discussed later in comments :slight_smile:


Runtimes

You have two official runtimes from Adobe

  • the Flash Player plugin
    that can run only inside a browser
  • Adobe AIR
    that can can run by itself without the help of a browser
    note: AIR stands for “Adobe Integrated Runtime”

and a third unofficial one

  • the Redtamarin shells
    eg. redshell, redshell_d, redshell_dd, etc.

They all share one thing in common:
the ActionScript Virtual Machine 2 or AVM2

The Flash Player and Adobe AIR share more stuff like

  • the Flash API (native code)
  • vector rendering engine
  • stage3D rendering engine
  • image, sound, video, etc. renderer/codec/etc.

The SWF Format

Without going into too much details you should see a SWF as a container, like a zip file,
but instead of containing “files”, it contains “tags”.

From the SWF File Format Specification

Each SWF tags has a header signature which allow to know which type of tag to expect.

So, when a runtime read and interpret a SWF file here what happen

  • read header
  • get the type T, the start and end of the tag
  • parse from start to end to obtain an object of type T
  • do something with the object of type T
  • rinse and repeat

All the runtimes: Flash Player, Adobe AIR and Redtamarin shells
can do that to a certain extend, eg. the number of tags the runtime understand.

Redtamarin for example is very limited as it understand only a couple of SWF tags,
and so it will just ignore the other tags it does not know how to parse or interpret.

For the Flash Player and Adobe AIR you can also have cases where they will not
know how to parse or interpret some specific SWF tags, for example if a SWF tag
SomethingObject2 was introduced for Flash Player 10, then the Flash Player 9 will
not understand it, that’s why we have versioning for the SWF and for the runtime reading the SWF.

So, yeah a SWF file is pretty much like a ZIP file, but instead of files
it uses a binary format to pack tightly different types of objects
the same way you could compress a bunch of different files:
a .txt file, a .mp3 file, a .png, etc. into one .zip file.

And a SWF file is versioned so the runtime know if it can open it in the first place,
and if it can understand the files contained inside it.


Who Can Read SWF Files?

Everyone … well, at least all the runtimes based on the AVM2.

But “read a SWF file” can be viewed in different manners.

In the Browser

The same way on your operating system you can associate a “file viewer”
with a particular type extension, when the browser encounter the .swf
file extension it will try to “open it” with the Flash Player plugin.

It does work the same as with a .png file for example.

When the browser encounter a .png it internally associate it with
a “PNG reader” that allow to display it on the screen.

The browser knows how to interpret by itself many file extensions:
.txt, .htm, .html, .png, .gif, etc.

But for other extensions it doesn’t know, then the browser need
the help of plugins to know how to interpret and display specific file.

The Flash Player plugin is like a PNG viewer, same principle,
but the SWF format is something more complicated to “display” that’s all.

If the Flash Player plugin is not installed, or if it is blocked to run by the browser,
then a SWF fille will not “play” at all.

In the Flash Player plugin

By default, you embed a SWF file into an HTML page, and that’s what the Flash Player read first.

But the Flash Player can load more SWF files into itself, it is not limited to read only 1 SWF,
see How to load external SWF files for Adobe Flash Player and Loading an external SWF file.

It’s very basic, you probably done that tons of times, but here a simple example.

var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("ExternalSWF.swf");
myLoader.load(url);
addChild(myLoader);

And there are many many many use cases

  • load a SWF that load another SWF that load yet another SWF
  • load a SWF hosted on a different domain
  • load a SWF to extend the content of the current SWF
  • load a SWF that replace completely the current SWF
  • etc.

Now you could say “that’s how it works when the Flash Player is used with the browser”
but then I want to mention: you can do the same with the Flash Plugin and without the browser.

Here introducing the Standalone Flash Player :slight_smile:

You will find those in the Adobe Flash Player Support Center under Debug Downloads

For the different platforms: Windows, Macintosh and Linux you will see

Download the Flash Player projector content debugger
.../updaters/26/flashplayer_26_sa_debug.exe

Download the Flash Player projector
.../updaters/26/flashplayer_26_sa.exe

Yeah the name have slightly changed, nowadays it is called the Flash Player projector.
But if you look at the naming of the files sa stands for “stand alone”.

I think it is important to mention it because it’s like a “portable” Flash Player
that does not need a browser, it exists since the very beginning of Flash, and
it is quite different from Adobe AIR.

What happen if you want to open a .zip file and you don’t have a ZIP software to unzip it?
Nothing much, you do need a way to read the file, so you need the ZIP software.

Because of that people came up with a solution that allow them to embed with the .zip file
the tiny bit of code that is required to unzip the file and created “Self-extracted zip file” that
are basically executable files, eg. .exe.

The Flash Player projector works on the same principle, you can either execute
the “Flash Player projector” / “Standalone Flash Player” and open a SWF file to play it,
or you can also select the option “Create a projector…”.

Creating a projector will merge the Flash Player projector and a SWF file and produce an executable
which is basically a “Self-extracting and playing SWF file”.

If you want to know the gritty details check the Redtamarin wiki documentation about Projector.

In Adobe AIR

That’s here where things get a bit more complicated and where people are mainly confused,
but let clarify everything out.

You have basically 6 different way to read/play a SWF file in Adobe AIR

  • the main file of Adobe AIR is a SWF file
    you have a foobar-app.xml that points to a foobar.swf file
    and AIR (the runtime) play it
  • an Adobe AIR app can load external SWF files
    the same way you would do with the Flash Player by using the Loader class
  • you can export a SWC library of a SWF
    that you reference when you compile your main app
  • you can embed a SWF file into an Adobe AIR app
    the same way you would embed a .png image or a .mp3 sound
    there are 3 ways to do it
    • embed as a binary
      [Embed(source="file.swf", mimeType="application/octet-stream"]
    • embed as a SWF and select a specific symbol
      [Embed(source="file.swf", symbol="SymbolName")]
    • embed as a SWF and select a specific symbol (alternative way)
      [Embed(source="file.swft#SymbolName")]
  • you can use the HTMLLoader class
    to either load a local SWF file or a remote SWF file (hosted on a domain)
  • the main file of Adobe AIR is an HTML file
    you have a foobar-app.xml that points to a foobar.html file
    that can load an external SWF file

Let’s see all the different cases one by one

The main file of Adobe AIR is a SWF file

This is the “default” of publishing an Adobe AIR app,
you write some AS3 code, it get compiled to a SWF
and that also produce an -app.xml that allow to configure the AIR app.

At the end, you either produce an .air file (like a SWF file it is a container, like a zip file)
which need the Adobe AIR runtime to be installed on the system to be able to install/run the app,
or
you produce a “captive runtime” as an MyApp directory (for Windows), an MyApp.app for macOS
that contains in itself the Adobe AIR runtime and also the main SWF file and other assets.

See Packaging a captive runtime bundle for desktop computers

with a list of pros and cons

Benefits

  • Produces a self-contained application
  • No Internet access required for installation
  • Application is isolated from runtime updates
  • Enterprises can certify the specific application and runtime combination
  • Supports the traditional software deployment model
  • No separate runtime redistribution required
  • Can use the NativeProcess API
  • Can use native extensions
  • Can use the File.openWithDefaultApplication() function without restriction
  • Can run from a USB or optical disk without installation

Drawbacks

  • Critical security fixes are not automatically available to users when Adobe publishes a security patch
  • Cannot use the .air file format
  • You must create your own installer, if needed
  • AIR update API and framework are not supported
  • The AIR in-browser API for installing and launching an AIR application from a web page is not supported
  • On Windows, file registration must be handled by your installer
  • Larger application disk footprint

You do not need to have the Flash Player plugin installed on the system for this to work.

The AIR publishing options are more complex than that but let’s keep it simple for now.

Adobe AIR app can load external SWF files

Exactly like the Flash Player plugin you can use the Loader class
to load dynamically an external SWF file.

var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("ExternalSWF.swf");
myLoader.load(url);
addChild(myLoader);

But do read Loading an external SWF file in the documentation
to know the little differences of behaviour when you load older or newer SWF versions.

You do not need to have the Flash Player plugin installed on the system for this to work.

Export a SWC library of a SWF

OK, this may not be seen as a legit case but I can guarantee you it is.

You are working in Flash Pro / Flash CS 6 / Flash CC / Animate CC
and you build complex graphic stuff and then you export them as a SWF files
(with or without code, it does not matter).

Then later on you load these SWF into your app.

But here another way, in your Flash Library
you can assign a class to a symbol

the example above would be the same as

import flash.display.MovieClip;

package test
{
    public class FooBar extends MovieClip
    {
        public function FooBar()
        {
        }
    }
}

For example, if you want to display a blue rectangle

  • some people will write AS3 code and use the display API
  • other people will actually draw it inside Flash

For simple stuff you can get away by drawing everything with code,
but for more advanced bloody creative artistic stuff you will want to draw them by hand,
or import stuff from Illustrator / Photoshop, do animations, etc.

But whatever you prefer or need, it does not matter,
both things can be exported to the same AS3 class test.FooBar

and either you right click on the symbol directly to export a SWC

or if you have a big library with a lot of assets, you can export the whole FLA file as a SWC

From that point, you add the SWC files into your Adobe AIR app project
and you reference them “as if” they were AS3 code libraries.

Because all those assets are AS3 classes, you can instantiate them new FooBar(),
inherit from them public class AnimationPlayer extends FooBar, etc.

But the real interesting thing is that they will automatically get exported into your main SWF
if your code reference them.

It’s different than loading an external SWF but it got plenty of interesting use cases

  • you want to compile from the command-line, designers provide you the updated “design SWC” files
  • a SWC can contains thousands of assets and symbols, but the final SWF will only embed the one actually used
  • it avoid to load an external SWF into a Loader than is then added as a MovieClip,
    you can directly use the symbol
  • you can work with a placeholder, so you do your programming,
    while the designers keep updating the design, allow to work in parallel,
    when they are happy with the design they export the SWC and you update it in your code
    etc.

Personally I consider that another way to load a SWF file into AIR :stuck_out_tongue:

You do not need to have the Flash Player plugin installed on the system for this to work.

Embed a SWF file into an Adobe AIR app

The same way you can use the metadata [embed] to embed fonts, images, sound, etc.
you can also embed SWF files.

Here a basic example:

embed the SWF as binary

import flash.utils.ByteArray;

package test
{
    [Embed(source="file.swf", mimeType="application/octet-stream"]
    public class MyFile extends ByteArray
    {
        public function MyFile()
        {
        }
    }
}

then load the SWF from the binary data

import flash.utils.ByteArray;
import test.MyFile;

var bytes:ByteArray = new MyFile();
var myLoader:Loader = new Loader();
myLoader.loadBytes( bytes );
addChild(myLoader);

It is very similar to loading a SWF from an external file.

Off course, here the advantage is that the SWF file, even if kept separated from
the main app source code, is internally available.

It is just binary data (ByteArray) and you can do plenty of things with that

  • quickly embed a lot of SWF files into 1 main AIR app
    instead of referencing external SWF
  • split the file in different parts and re-assemble them later
  • encrypt the file, decrypt it in memory then load the SWF file
  • etc.

Or maybe you just don’t want people to see you are loading external assets.

You do not need to have the Flash Player plugin installed on the system for this to work.

Use the HTMLLoader class

Adobe AIR since AIR 1.0 embed its own browser engine: Safari WebKit.

See About the HTML environment

Adobe® AIR® uses WebKit (www.webkit.org), also used by the Safari web browser, to parse, layout, and render HTML and JavaScript content. Using the AIR APIs in HTML content is optional. You can program in the content of an HTMLLoader object or HTML window entirely with HTML and JavaScript. Most existing HTML pages and applications should run with few changes (assuming they use HTML, CSS, DOM, and JavaScript features compatible with WebKit).

and more documentation to read

From AIR 1.0 to AIR 21.0 the Adobe AIR runtime embedded its own Flash Player plugin,
wether the user had installed or not the Flash Player on its system you could play SWF files
from an HTMLLoader no matter what.

Advantage is you didn’t really have to check if the Flash Player was installed or not.

The problem with that is that the Flash Player version could only be updated
if you updated the Adobe AIR version.

From AIR 22.0 to now, see the Adobe AIR 22 release notes

System level Flash Player support for AIR desktop applications
Starting in AIR 22, applications that play swf content via the HTML control (WebKit)
will now load the system level NPAPI Flash Player provided by Adobe.
If this plugin is not available on the system, the end user will be prompted to download
and install the plugin from Adobe.

The Flash Player plugin is not anymore embedded into the Adobe AIR runtime,
if you try to load a SWF with HTMLLoader it will only work if the Flash Player plugin (NPAPI)
is installed on the user system.

Advantage is that Adobe AIR can use the Flash Player from the system and so this one
can be updated to its latest version, eg. AIR 22 loading a SWF made for Flash Player 26.

The problem is now you do have to detect the Flash Player plugin like you would do
on an HTML page for the browser (hosted on a domain), and if not installed prompt the user to install it.

You do need to have the Flash Player plugin installed on the system for this to work,
unless you are publishing to AIR 21 or less.

The main file of Adobe AIR is an HTML file

Yep, you can build AIR app purely based on HTML, it’s all in the documentation
see Creating your first HTML-based AIR application with the AIR SDK

and here for a bunch of examples
Adobe AIR sample applications for HTML/JavaScript developers

Now my take on this is even if your main app is HelloWorld.html instead of HelloWorld.swf
you can still load an external SWF into it.

The bottom of the page in the doc is pretty explicit

In AIR, HTML and JavaScript code generally behaves the same as it would in a typical web browser. (In fact, AIR uses the same WebKit rendering engine used by the Safari web browser.) However, there are some important differences that you must understand when you develop HTML applications in AIR. For more information on these differences, and other important topics, see Programming HTML and JavaScript.

Yep, Adobe AIR is also a full fledged browser and will load any SWF files without blocking the Flash Player plugin :smile:

You do need to have the Flash Player plugin installed on the system for this to work,
unless you are publishing to AIR 21 or less.


In summary, 2/3rd cases allow you to embed/load/use a SWF file without the need of the Flash Player plugin, and 1/3rd cases only need the Flash Player plugin installed on the system if AIR is less than version 22.

Also as a bonus (yay you read it till the end) for Adobe AIR 2.6 on Linux
which was stuck for many years with the Flash Player plugin version 10.3,
you can update the libflashplayer.so to use the latest version 26 available again for Linux :wink:.

6 Likes

Good job on this! good reading :wink:

1 Like

A post was split to a new topic: How to load a remote swf files from a server?