Using the StageVideo APIs

Stage video is a mechanism within the runtime that enhances video playback and device performance. The runtime creates and maintains this mechanism; as a developer, your role is to configure your application to take advantage of it.

To use stage video, you implement a framework of event handlers that detect when stage video is and isn’t available. When you receive notification that stage video is available, you retrieve a StageVideo object from the Stage.stageVideos property. The runtime populates this Vector object with one or more StageVideo objects. You can then use one of the provided StageVideo objects, rather than a Video object, to display streaming video.

On Flash Player, when you receive notification that stage video is no longer available, switch your video stream back to a Video object.

Note: You cannot create StageVideo objects.

Stage.stageVideos property

The Stage.stageVideos property is a Vector object that gives you access to StageVideo instances. This vector can contain up to four StageVideo objects, depending on hardware and system resources. Mobile devices can be limited to one, or none.

When stage video is not available, this vector contains no objects. To avoid run time errors, be sure that you access members of this vector only when the most recent StageVideoAvailability event indicates that stage video is available.

StageVideo events

The StageVideo API framework provides the following events:

StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY
Sent when the Stage.stageVideos property changes. The StageVideoAvailabilityEvent.availability property indicates either AVAILABLE or UNAVAILABLE. Use this event to determine whether the stageVideos property contains any StageVideo objects, rather than directly checking the length of the Stage.stageVideos vector.

StageVideoEvent.RENDER_STATE
Sent when a NetStream or Camera object has been attached to a StageVideo object and is playing. Indicates the type of decoding currently in use: hardware, software, or unavailable (nothing is displayed). The event target contains videoWidth and videoHeight properties that are safe to use for resizing the video viewport.
Important: Coordinates obtained from the StageVideo target object use Stage coordinates, since they are not part of the standard display list.

VideoEvent.RENDER_STATE
Sent when a Video object is being used. Indicates whether software or hardware accelerated decoding is in use. If this event indicates hardware accelerated decoding, switch to a StageVideo object if possible. The Video event target contains videoWidth and videoHeight properties that are safe to use for resizing the video viewport.

Workflow for implementing the StageVideo feature

Follow these top-level steps to implement the StageVideo feature:

  1. Listen for the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event to find out when the Stage.stageVideos vector has changed. See Using the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event.

  2. If the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event reports that stage video is available, use the Stage.stageVideos Vector object within the event handler to access a StageVideo object.

  3. Attach a NetStream object using StageVideo.attachNetStream() or attach a Camera object using StageVideo.attachCamera().

  4. Play the video using NetStream.play().

  5. Listen for the StageVideoEvent.RENDER_STATE event on the StageVideo object to determine the status of playing the video. Receipt of this event also indicates that the width and height properties of the video have been initialized or changed. See Using the StageVideoEvent.RENDER_STATE and VideoEvent.RENDER_STATE events.

  6. Listen for the VideoEvent.RENDER_STATE event on the Video object. This event provides the same statuses as StageVideoEvent.RENDER_STATE, so you can also use it to determine whether GPU acceleration is available. Receipt of this event also indicates that the width and height properties of the video have been initialized or changed. See Using the StageVideoEvent.RENDER_STATE and VideoEvent.RENDER_STATE events.

Initializing StageVideo event listeners

Set up your StageVideoAvailabilityEvent and VideoEvent listeners during application initialization. For example, you can initialize these listeners in the flash.events.Event.ADDED_TO_STAGE event handler. This event guarantees that your application is visible on the stage:

public class SimpleStageVideo extends Sprite 
    private var nc:NetConnection; 
    private var ns:NetStream; 
 
    public function SimpleStageVideo() 
    { 
        // Constructor for SimpleStageVideo class 
        // Make sure the app is visible and stage available 
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 
    } 
     
    private function onAddedToStage(event:Event):void 
    { 
        //... 
        // Connections 
        nc = new NetConnection(); 
        nc.connect(null); 
        ns = new NetStream(nc); 
        ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus); 
        ns.client = this; 
 
        // Screen 
        video = new Video(); 
        video.smoothing = true; 
 
        // Video Events 
        // the StageVideoEvent.STAGE_VIDEO_STATE informs you whether 
        // StageVideo is available 
        stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, 
            onStageVideoState); 
        // in case of fallback to Video, listen to the VideoEvent.RENDER_STATE 
        // event to handle resize properly and know about the acceleration mode running 
        video.addEventListener(VideoEvent.RENDER_STATE, videoStateChange); 
        //... 
    }

Using the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event

In the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY handler, decide whether to use a Video or StageVideo object based on the availability of StageVideo. If the StageVideoAvailabilityEvent.availability property is set to StageVideoAvailability.AVAILABLE, use StageVideo. In this case, you can rely on the Stage.stageVideos vector to contain one or more StageVideo objects. Obtain a StageVideo object from the Stage.stageVideos property and attach the NetStream object to it. Because StageVideo objects always appear in the background, remove any existing Video object (always in the foreground). You also use this event handler to add a listener for the StageVideoEvent.RENDER_STATE event.

If the StageVideoAvailabilityEvent.availability property is set to StageVideoAvailability.UNAVAILABLE, do not use StageVideo or access the Stage.stageVideos vector. In this case, attach the NetStream object to a Video object. Finally, add the StageVideo or Video object to the stage and call NetStream.play().

The following code shows how to handle the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event:

private var sv:StageVideo; 
private var video:Video; 
 
private function onStageVideoState(event:StageVideoAvailabilityEvent):void 
{     
    // Detect if StageVideo is available and decide what to do in toggleStageVideo 
    toggleStageVideo(event.availability == StageVideoAvailability.AVAILABLE); 
} 
 
private function toggleStageVideo(on:Boolean):void 
{     
    // To choose StageVideo attach the NetStream to StageVideo 
    if (on) 
    { 
        stageVideoInUse = true; 
        if ( sv == null ) 
        { 
            sv = stage.stageVideos[0]; 
            sv.addEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange); 
                sv.attachNetStream(ns); 
        } 
 
        if (classicVideoInUse) 
        { 
            // If you use StageVideo, remove from the display list the 
            // Video object to avoid covering the StageVideo object 
            // (which is always in the background) 
            stage.removeChild ( video ); 
            classicVideoInUse = false; 
        } 
    } else 
    { 
        // Otherwise attach it to a Video object 
        if (stageVideoInUse) 
            stageVideoInUse = false; 
        classicVideoInUse = true; 
        video.attachNetStream(ns); 
        stage.addChildAt(video, 0); 
    } 
     
    if ( !played ) 
    { 
        played = true; 
        ns.play(FILE_NAME); 
    } 
} 
Important: The first time an application accesses the vector element at Stage.stageVideos[0], the default rect is set to 0,0,0,0, and pan and zoom properties use default values. Always reset these values to your preferred settings. You can use the videoWidth and videoHeight properties of the StageVideoEvent.RENDER_STATE or VideoEvent.RENDER_STATE event target for calculating the video viewport dimensions.

Download the full source code for this sample application at Getting Started with Stage Video.

Using the StageVideoEvent.RENDER_STATE and VideoEvent.RENDER_STATE events

StageVideo and Video objects send events that inform applications when the display environment changes. These events are StageVideoEvent.RENDER_STATE and VideoEvent.RENDER_STATE.

A StageVideo or Video object dispatches a render state event when a NetStream object is attached and begins playing. It also sends this event when the display environment changes; for example, when the video viewport is resized. Use these notifications to reset your viewport to the current videoHeight and videoWidth values of the event target object.

Reported render states include:

  • RENDER_STATUS_UNAVAILABLE

  • RENDER_STATUS_SOFTWARE

  • RENDER_STATUS_ACCELERATED

Render states indicate when hardware accelerated decoding is in use, regardless of which class is currently playing video. Check the StageVideoEvent.status property to learn whether the necessary decoding is available. If this property is set to “unavailable”, the StageVideo object cannot play the video. This status requires that you immediately reattach the NetStream object to a Video object. Other statuses inform your application of the current rendering conditions.

The following table describes the implications of all render status values for StageVideoEvent and VideoEvent objects in Flash Player:

 

VideoStatus.ACCELERATED

VideoStatus.SOFTWARE

VideoStatus.UNAVAILABLE

StageVideoEvent

Decoding and presentation both occur in hardware. (Best performance.)

Presentation in hardware, decoding in software. (Acceptable performance.)

No GPU resources are available to handle video, and nothing is displayed. Fall back to a Video object.

VideoEvent

Presentation in software, decoding in hardware. (Acceptable performance on a modern desktop system only. Degraded full-screen performance.)

Presentation in software, decoding in software. (Worst case performance-wise. Degraded full-screen performance.)

(N/A)

Color spaces

Stage video uses underlying hardware capabilities to support color spaces. SWF content can provide metadata indicating its preferred color space. However, the device graphics hardware determines whether that color space can be used. One device can support several color spaces, while another supports none. If the hardware does not support the requested color space, Flash Player attempts to find the closest match among the supported color spaces.

To query which color spaces the hardware supports, use the StageVideo.colorSpaces property. This property returns the list of supported color spaces in a String vector:

var colorSpace:Vector.<String> = stageVideo.colorSpaces();

To learn which color space the currently playing video is using, check the StageVideoEvent.colorSpace property. Check this property in your event handler for the StageVideoEvent.RENDER_STATE event:

var currColorSpace:String; 
 
//StageVideoEvent.RENDER_STATE event handler 
private function stageVideoRenderState(event:Object):void 
{ 
    //... 
    currColorSpace = (event as StageVideoEvent).colorSpace; 
    //... 
}

If Flash Player cannot find a substitute for an unsupported color space, stage video uses the default color space BT.601. For example, video streams with H.264 encoding typically use the BT.709 color space. If the device hardware does not support BT.709, the colorSpace property returns "BT601". A StageVideoEvent.colorSpace value of "unknown" indicates that the hardware does not provide a means of querying the color space.

If your application deems the current color space unacceptable, you can choose to switch from a StageVideo object to a Video object. The Video class supports all color spaces through software compositing.