This is a message.

Writing Flash plugins

Characteristics of a Flash plugin

  • they are written with ActionScript 3.0

  • they interact with Flowplayer ActionScript API

  • they are loaded into the player upon configuration or at runtime using loadPlugin() method. This method is availabe to both JavaScript and ActionScript coders.

  • they are usually visible in the Flowplayer canvas, and they may be also hidden and berform their function in the background

  • all animation, configuration and styling capabilities are automatically set for the plugin without any coding

  • they may implement org.flowplayer.model.Plugin interface to get access to Flowplayer internals. This is not required however and you can load any SWF object inside Flowplayer as long as it’s coded with AS3.

  • plugin’s methods can be marked as external and that method will become part of JavaScript Plugin object meaning that you can use your method like this: $f().getPlugin("myPlugin").myMethod();

Example plugin: Hello world

We start by showing you an example plugin and how it's configured. Later in this document we will show you how it's done. Click on this player to see it in action.

// install player normally
$f("player", "http://releases.flowplayer.org/swf/flowplayer-3.2.18.swf", {
// our "hello" plugin is configured here
plugins: {
hello: {
url: '/media/swf/hello-world.swf',
 
// display properties become automatically available for users
bottom:50,
backgroundColor: '#666666',
borderRadius: 10,
border:'1px solid #333333'
}
}
});

JavaScript

This plugin can be animated and styled normally using Plugin object's animate and css methods. Here is an example.

// get handle to our plugin with JavaScript
var hello = $f().getPlugin("hello");
 
// animate our plugin
hello.animate(
{top:50, height:40, width:300},
3000,
function() {
// after animation finishes change its background color
hello.css("backgroundColor", "#778899");
}
);

JavaScript

The player above must be loaded first by clicking on it. You can see the immediate results after clicking "Run". You can play around with Firebug console if you have one and try any animations and style changes with animate and css calls.

Plugin types

There are four kinds of Flash plugins in Flowplayer:

  1. display plugins that implement org.flowplayer.model.Plugin interface. These plugins have direct access to Flowplayer API and they are usually drawn on player's canvas but that is not a requirement since the can also stay hidden. This document focuses on these plugins.

  2. streaming providers are used to load content to Flowplayer. For example video content from a Content Delivery Network, CDN. If you want to know how to make providers you should read this document.

  3. font plugins that can be loaded into the player to provide your favorite font for each component inside Flowplayer.

  4. any Flash component that that implements flash.display.DisplayObject or its subclasses. So if you have a suitable Flash component just configure it normally inside Flowplayer and you should be done. You can even animate those components using JavaScript!

Here is an example where we load random Flash component into Flowplayer and animate it using JavaScript.

// install player normally
$f("player2", "http://releases.flowplayer.org/swf/flowplayer-3.2.18.swf", {
// place a "clock" plugin that is just a Flash component found
// from the web
plugins: {
clock: {
url: '/media/swf/clock.swf',
 
// all display properties work for any Flash component
width:230,
height:230,
top:20,
right:20,
 
// styling properties do not work
border:'1px solid #ffffff'
}
}
});

JavaScript

After you have loaded the player by clicking on it you can run the following animation.

$f().getPlugin("clock").animate({width:100,height:100}, 3000)

JavaScript

Flowplayer Plugin interface

org.flowplayer.model.Plugin interface opens up a door for Flowplayer plugin development. If your plugin implements this interface you'll get access to Flowplayer API and other crucial things at the right time. Here is its signature.

public interface Plugin {
/ This is invoked when the plugin is loaded. PluginModel gives
* you access to display properties and other configuration. You
* will also use it to dispatch events to outside world.
/
public function onConfig(model:PluginModel):void {
}
 
/ This is invoked when all plugins have been loaded and the
* player initialization is complete. Flowplayer API is supplied
* as the argument.
/
public function onLoad(player:Flowplayer):void {
}
 
/ This should return the default configuration to be used for
* this plugin. Where it is placed and what are its dimensions
* if they are not explicitly specified by the user.
/
public function getDefaultConfig():Object {
}
}

ActionScript 3

So the crucial classes for Plugin development are org.flowplayer.model.PluginModel and org.flowplayer.view.Flowplayer. The default config will just return an object of different properties. For example controlbar plugin has the following defaultConfig implementation:

public function get defaultConfig():Object {
return {
bottom: 0,
left: 0,
height: 28,
width: "100%",
zIndex: 2
};
}

ActionScript 3

If this method returns null value, the plugin will be placed on the panel centered and with 50% width and height values.

Working with Flowplayer

The primary tool for working with the player is org.flowplayer.view.Flowplayer object that you'll recieve on onLoad event. This object makes it possible to do lots of powerfull stuff including

  • starting/stopping/pausing/resuming playback

  • registering event listeners

  • invoking methods on other plugins

  • loading other plugins

  • animating plugins and other display objects

  • working with playlist clips

Here we talk about the most usefull things you can do with the API.

Events

Your plugin can listen and react to different events. This is your primary tool for interacting with the player. To hook up with events related clips you can register an event listener to the Playlist. By registering your listener to the Playlist you are actually listening to all clips in the playlist. If the playlist changes (clips are replaced) your event listeners stay intact and will receive events happening to the new clips.

// start listening to playback start for each clip
player.playlist.onStart(onClipStart);
 
// here is the invoked function
private function onClipStart(event:ClipEvent):void {
var clip:Clip = event.target as Clip;
trace(clip + " was just started");
}

ActionScript 3

If you are interested in all events related to the first clip you can register a listener just for it:

player.playlist.getClip(0).onAll(onFirstClipEvents);
 
private function onFirstClipEvents(event:ClipEvent):void {
var clip:Clip = event.target as Clip;
trace("event received for clip " + clip);
 
// do my stuff while the first clip is paused
if (event.eventType == ClipEventType.PAUSE) {
 
}
}

ActionScript 3

Animations

You can animate plugins and other plugins using the animation engine that you can fetch from the Flowplayer object. You can use this engine to animate any Flash component that is displayable. This is how you can "tween" a button to a new position and at the same time change its opacity and width:

player.animationEngine.animate(
button,
{ x: 500, y: 200, opacity: 0.5, width: 200 }
);

ActionScript 3

The animate() method can take relative values if you are animating plugins. The relative values are always calculated from the plugin's current position and percentages are relative to the player's dimensions. The following code will animate the Content plugin to move +10% horizontally and 50 pixels vertically:

var content:Plugin = player.getPlugin("content");
player.animationEngine.animate(content, { x: "+10%", y: "+50" });

ActionScript 3

External public methods

Your plugin can expose methods to JavaScript. These exposed methods are then added to the Plugin object's public API. Methods are exposed simply by adding a special "External" annotation to the method you want to make available for external invokations:

[External]
public function showAlert(message:String):void {
_myTextField.text = message;
}

ActionScript 3

CSS styling support

The Flowplayer API has a method called css() that is used to affect the looks of certain plugins. Currently the controls and content plugins and the special "canvas" plugin support styling of their background area via the css() method. For these plugins it's possible to change the following properties using css():

  • backgroundColor

  • backgroundGradient

  • backgroundImage

  • backgroundRepeat

See this skinning demo in this page to see how changing these properties affect the looks of the control bar.

If your plugin implements the Styleable interface it becomes styleable via the css() method. This interface defines the css(styleProps:Object) method that takes in an object containing CSS style properties. You can implement this method as you like and support CSS properties as you see fit. To easily support the background properties listed above just inherit your plugin from the StyleableSprite class that is part of the Flowplayer library. This is how the controls and the content plugins get their styling support. Next we'll take a look at a simple "hello world" plugin that supports CSS styling.

Layout management

The player takes care of placing the plugin into the display list and the plugin should not do that by itself using addChild(this). All plugins are shown on the player's Panel and the Panel takes care of their placement and resizing. For example, when the player goes to fullscreen the player resizes the affected plugins by setting their width and height properties. If you need to rearrange your plugin's child objects when resizing happens (you usually need to) you should override the width and height property accessors that are inherited from DisplayObject. For example:

override public function set width(newWidth:Number):void {
// use newWidth here to arrange my child objects
}
 
override public function set height(newHeight:Number):void {
// use newHeight here to arrange my child objects
}

ActionScript 3

The Flowplayer library contains a convenient superclass that that provides some support for handing the size changes. It's called AbstractSprite. When using it you need to override its onResize() method that gets called when the plugin's size is changed:

override public function onResize():void {
// set _childButton width according to my new width, the standard
// width & height properties have been set already
_myChildButton.width = width - 20;
_myChildButton.x = 10;
}

ActionScript 3

Code example: Hello world

Here is the complete source code of our "hello world" plugin at the beginning of this page.

package org.flowplayer {
import flash.display.Sprite;
import flash.text.TextField;
 
import org.flowplayer.model.Plugin;
import org.flowplayer.util.Arrange;
import org.flowplayer.model.PluginModel;
import org.flowplayer.view.Flowplayer;
 
public class SimpleHelloWorld extends Sprite implements Plugin
{
private var _text:TextField;
 
public function SimpleHelloWorld() {
_text = new TextField();
_text.text = "Hello World!";
_text.height = 20;
addChild(_text);
}
 
public override function set width(newWidth:Number):void {
super.width = newWidth;
arrangeChildren();
}
 
public override function set height(newHeight:Number):void {
super.width = newHeight;
arrangeChildren();
}
 
private function arrangeChildren():void {
Arrange.center(_text, width, height);
}
 
// implementation of the Plugin interface follows:
public function getDefaultConfig():Object {
return {
top: "70%", left: '50%', width: '40%', height: 50,
opacity: 0.9
};
}
 
public function onConfig(configProps:PluginModel):void {
}
 
public function onLoad(player:Flowplayer):void {
// onLoad event must be dispatched once our plugin is
// completely initialized, if initialization fails we need
// to call _model.dispatchError(PluginError.INIT_FAILED)
_model.dispatchOnLoad();
}
}
}

ActionScript 3

Another Hello world example

This example includes a centered TextField with the "Hello World!" text in it. This time it implements org.flowplayer.view.Styleable interface thus providing support for styling properties that user's can give in the configuration. The Flowplayer library has one implementation for it called StyleableSprite. You can use it to implement any Sprite including a Sprite that is used as a plugin. Here is the previous example enhanced to support styling:

package org.flowplayer {
import flash.text.TextField;
 
import org.flowplayer.model.Plugin;
import org.flowplayer.model.PluginModel;
import org.flowplayer.util.Arrange;
import org.flowplayer.view.Flowplayer;
import org.flowplayer.view.StyleableSprite;
 
public class HelloWorld extends StyleableSprite implements Plugin
{
private var _text:TextField;
private var _model:PluginModel;
 
public function HelloWorld() {
_text = new TextField();
_text.text = "Hello World!";
_text.height = 20;
addChild(_text);
}
 
/
* Arranges the child display objects. Called by superclass
* when the size of this sprite changes.
*/
override protected function onResize():void {
super.onResize();
Arrange.center(_text, width, height);
}
 
/

* Gets the default configuration for this plugin.
*/
public function getDefaultConfig():Object {
return {
top: "70%", left: '50%', width: '40%', height: 50,
opacity: 0.9,
 
// this time we have a support for styling properties
borderRadius: 20,
backgroundGradient: 'medium'
};
}
 
public function onConfig(model:PluginModel):void {
// setting rootStyle causes the superclass to draw our
// background rootStyle properties can be defined in our
// config object, so we'll use that as the rootStyle
// object
rootStyle = model.config;
 
// store a reference to the model, it's used below
_model = model;
}
 
public function onLoad(player:Flowplayer):void {
// onLoad event must be dispatched once our plugin is
// completely initialized, if initialization fails we need
// to call _model.dispatchError(PluginError.INIT_FAILED)
_model.dispatchOnLoad();
}
}
}

ActionScript 3

Note the borderRadius and backgroundGradient properties returned in the defaultConfig accessor method. These settings makes our plugin to have a glossy gradient color and nice round corners. Its default opacity (alpha) is 0.9 making it slightly transparent. The plugin can be manipulated and animated using the css() and animate() methods just like the default Flowplayer plugins.

To enhance this class you can add it with support for the Flowplayer's css() and animate() methods. You may support any property to these methods from both JavaScript and Flash and you can do whatever you want to do with your custom methods.

Example external method

To make it possible to change the text shown in our plugin we can add one method to this class:

[External]
public function set text(newText:String):void {
_text.text = newText;
}

ActionScript 3

Now you can change the text using the following JavaScript call:

$f().getPlugin("hello").setText("hello again!");

JavaScript

Developer resources

Source code repositories

Flowplayer is in Github.

We encourage you to checkout the sources and study them. This will make it easier for you to get started with coding your own plugins. If you are willing to share your plugin in our Github repository, please contact us. We are happy to host it there and can also feature it in this site.

Flowplayer library

To compile your plugin you need to include the flowplayer.swc library into the compiler classpath. Our own plugins use Ant for building and this library is included there in the classpath. This library and previous "hello world" example plugins are included in our plugin development kit (devkit) that you can download here.

Apache Ant is pre-integrated into the following Flash IDEs, and we recommend using one of these for plugin development: IntelliJ IDEA, FDT, Flex Builder.

FileSizeDownload

flowplayer.devkit-3.2.18.zip

None

Please right-click and choose "save link as ..." (or similar)

The devkit is built from the core sources. If you want to build your plugin against the latest SVN trunk version, please checkout the core from SVN (see above) and build it.

Devkit's version history is available here.

Developing with the Flash authoring tool

The example in the devkit also contains a FLA file for Flash developers that use the Adobe's Flash authoring tool. You need to make sure that you have flowplayer.swc in the FLA's classpath so that the plugin compiles. You can change the classpath in the publish settings. After publishing you can test the plugin by running it in Flowplayer.

You cannot run it in the Flash authoring tool because it does not have the classes of the Flowplayer library (the ones in flowplayer.swc) available at runtime. To make them available to during runtime in the Flash tool, you need to add flowplayer.swc to the component library by copying in into [flash install dir]/Configuration/Components/Flowplayer. Create the Flowplayer directory under Components before copying. After that the Flowplayer classes are available in the components list (select Window/Components) - you might need to select "Reload" in the component list menu to make them appear. Once you have the Flowplayer components showing, copy them over to the plugin's Library and you are done. NOTE: If you do this the classes in the Library, plus other dependent classes, will be compiled into the plugin SWF. That makes it big! It's also completely unnecessary to have them in the plugin SWF because the player has them included and there is no need to have them in both places. For this reason make sure you remove the classes from the library before publishing the plugin for deployment.

Note that the [External] annotation is not supported by the Flash authoring tool.

You can also use our content, controls, rtmp, and pseudostreaming plugins as examples to guide you when you implement your first plugin.

More information

Forum post: How to compile a flash-based plugin