How to use the Feathers VideoPlayer component

The VideoPlayer class provides video playback capabilities using a flash.net.NetStream object. Video files may be loaded from a URL and displayed as a Starling texture. Media player controls may be added as children to display information such as the current time or to control playback by seeking or pausing the audio. VideoPlayer is a subclass of LayoutGroup, so its children may be positioned and sized using layouts.

Screenshot of a Feathers VideoPlayer component
A VideoPlayer component with controls skinned with MetalWorksMobileTheme

The Basics

First, let's create a VideoPlayer component, set its dimensions, and add it to the display list:

var player:VideoPlayer = new VideoPlayer();
player.setSize( 320, 300 );
this.addChild( player );

To play a video file, pass the URL to the videoSource property:

player.videoSource = "http://example.com/video.m4v";

To display the video, we need to add an ImageLoader as a child of the VideoPlayer:

var loader:ImageLoader = new ImageLoader();
player.addChild( loader );

Notice that we have not set the source property of the ImageLoader yet. A video texture requires a moment to initialize on the GPU before it may be rendered by Starling. The VideoPlayer will dispatch Event.READY once we can pass the texture to the ImageLoader:

function videoPlayer_readyHandler( event:Event ):void
{
    loader.source = player.texture;
}
player.addEventListener( Event.READY, videoPlayer_readyHandler );

The video texture may be accessed throught the texture property. Until Event.READY is dispatched, the texture property of the VideoPlayer will be null.

Additionally, you should listen for Event.CLEAR:

function videoPlayer_clearHandler( event:Event ):void
{
    loader.source = null;
}
player.addEventListener( Event.CLEAR, videoPlayer_clearHandler );

This event is dispatched when the video texture has been disposed, and it must no longer be rendered.

Controls

Let's give the VideoPlayer some controls. First, let's create a LayoutGroup to use as a toolbar for our controls:

var controls:LayoutGroup = new LayoutGroup();
controls.styleNameList.add( LayoutGroup.ALTERNATE_STYLE_NAME_TOOLBAR );
player.addChild(controls);

With the toolbar in place, let's add a PlayPauseToggleButton and a SeekSlider. It's as simple as adding them as children of the tool bar:

var button:PlayPauseToggleButton = new PlayPauseToggleButton();
controls.addChild( button );

var slider:SeekSlider = new SeekSlider();
controls.addChild( slider );

There's no need to add event listeners for these controls. You simply need to add them as children of the VideoPlayer (or a container that has been added as a child of the VideoPlayer), and everything will be set up automatically.

In the next section, we'll position everything with some layouts.

Layout

First, let's create a layout for the toolbar with our controls. We'll pass a HorizontalLayout to the layout property:

var layout:HorizontalLayout = new HorizontalLayout();
layout.gap = 10;
controls.layout = layout;

Here, we've set the gap property, but HorizontalLayout provides many more useful features, including padding and alignment. See How to use HorizontalLayout with Feathers containers for complete details.

If we want our SeekSlider to stretch to fill as much space as possible within the VideoPlayer, we can pass in HorizontalLayoutData:

var sliderLayoutData:HorizontalLayoutData = new HorizontalLayoutData();
sliderLayoutData.percentWidth = 100;
slider.layoutData = sliderLayoutData;

Now, because we set the percentWidth property, when the width of the toolbar changes, the width of the SeekSlider will change too.

Next, we want to position the toolbar and the ImageLoader. Let's use a VerticalLayout for that.

player.layout = new VerticalLayout();

We want the ImageLoader to fill as much space as possible.

var loaderLayoutData:VerticalLayoutData = new VerticalLayoutData();
loaderLayoutData.percentWidth = 100;
loaderLayoutData.percentHeight = 100;
loader.layoutData = loaderLayoutData;

Then, we want the toolbar to fill the entire width of the VideoPlayer:

var controlsLayoutData:VerticalLayoutData = new VerticalLayoutData();
controlsLayoutData.percentWidth = 100;
controls.layoutData = controlsLayoutData;

Controlling playback programmatically

By default, the VideoPlayer will automatically start playing its videoSource. We can use the autoPlay property to change this behavior:

player.autoPlay = false;

If autoPlay is set to false, we can call play() to begin playback manually:

player.play();

To pause, we can call pause() to pause playback at the current position:

player.pause();

The togglePlayPause() method may be called to toggle between the play and pause states:

player.togglePlayPause();

To stop playback and return the video to the beginning, we may call stop():

player.stop();

The seek() function may be called to change the current time:

player.seek( 5.0 );

The time is measured in seconds.

To change the volume, we can pass a flash.media.SoundTransform object to the soundTransform property:

player.soundTransform = new SoundTransform( 0.5 );

The toggleFullScreen() function will toggle between normal and full screen modes:

player.toggleFullScreen();

When the VideoPlayer is displayed in full screen mode, it will be added as a modal pop-up above all Starling content.

Loading Videos

Previously, we loaded a video using a simple URL. Let's look at all of the ways that video may be loaded by the VideoPlayer component.

Loading from URLs

First, we'll review how to load a video from a URL:

player.videoSource = "http://example.com/video.mp4";

Loading from the file system

In Adobe AIR, we can also load a video from the file system:

var videoFile:File = File.applicationDirectory.resolvePath("video.mp4");
player.videoSource = videoFile.url;

Be sure to pass the url property of a flash.filesystem.File object to videoSource. Attempting to use the nativePath property will not work.

Streaming video

Finally, we can stream a video from a server, such as Adobe Media Server or the open source Red5 Media Server. First, we want to use the netConnectionFactory property of the video player to set up the connection to the server:

player.netConnectionFactory = function():NetConnection
{
    var nc:NetConnection = new NetConnection();
    nc.connect("rtmp://localhost/vod");
    return nc;
};

Next, we'll pass the name of the stream to the videoSource property:

player.videoSource = "mp4:streams/myvideo";

To play another video stream from the same server, set the videoSource property again.

Skinning a VideoPlayer

As mentioned above, VideoPlayer is a subclass of LayoutGroup. For more detailed information about the skinning options available to VideoPlayer, see How to use the Feathers LayoutGroup component.