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:
Listen for the
StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY
event to find out when theStage.stageVideos
vector has changed. See Using the StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY event.If the
StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY
event reports that stage video is available, use theStage.stageVideos
Vector object within the event handler to access a StageVideo object.Attach a NetStream object using
StageVideo.attachNetStream()
or attach a Camera object usingStageVideo.attachCamera()
.Play the video using
NetStream.play()
.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.Listen for the
VideoEvent.RENDER_STATE
event on the Video object. This event provides the same statuses asStageVideoEvent.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.