http://livedocs.adobe.com/flex/3/html/help.html?content=Working_with_Video_32.html
Video
With ActionScript 3
Author: Meir Ohayon
ohmeir@gmail.com
Based on official documuntation of Adobe Meir Ohayon : ohmeir@gmail.com
1
Alternatives
VideoDisplay Control
Creating FLV in FLASH CS3 Professional and selecting
the option of skin for your video including common
playback controls.
Working with videos : Classes
Video Class – Display Object
o The actual video content box on the Stage is an instance of
the Video class.
NetStream Class – Represent stream of video data .
NetConnection Class – Represent connection handling to
stream source.
Important concepts and terms
Cue point – A marker placed on specific moment
(bookmarking).
Encoding – Converting to another video data format.
Frame
Keyframe – A video frame which contains the full
information for the frame. Other frames that follow a
keyframe only contain information about how they differ
from the keyframe.
Metadata Meir Ohayon : ohmeir@gmail.com
2
Progressive Download
Loading in sequence
o You can't jump ahead to a part of the video that hasn't
loaded.
True Streaming (Aka Streaming)
Loading chanks from the video file by demand.
o Needs implemantation of special protocol to split video data
into fragments on the server → RTMP
o Needs server that can handle remote procrdure calls for
getting demands (RPC)
o Needs persistant connection to server (getting demands +
handling RTMP)
Flash Media Server enables all that. Meir Ohayon : ohmeir@gmail.com
3
Setting connection
Connecting to local:
var nc:NetConnection = new NetConnection();
nc.connect(null);
Connecting to Flash Media Server:
var nc:NetConnection = new NetConnection();
nc.connect("rtmp://localhost/HelloWorld");
Setting stream and playing it
var ns:NetStream = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
asyncErrorHandler);
ns.play("video.flv");
function asyncErrorHandler(event:AsyncErrorEvent):void {
// ignore error
{
Handling display
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid); Meir Ohayon : ohmeir@gmail.com
4
NetStream methods
pause( )
o If the video is already paused does nothing.
resume( )
o Resumes paused video.
o If the video is already playing does nothing.
seek( )
o Seeks the keyframe closest to the specified location (an
offset, in seconds, from the begining of the stream).
togglePause( )
o Pauses\Resumes playback of stream.
Notes on NetStream methods
There is no stop( ) method.
o In order to stop a stream you must pause playback and seek
to the begining of the stream.
The play( ) method doesn't resume playback, it is used for
loading video files.Meir Ohayon : ohmeir@gmail.com
5
NetStream methods: Example
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
asynErrHandler);
ns.play("video.flv");
function asynErrHandler(e:AsyncErrorEvent):void {
// ignore error
{
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
pauseBtn.addEventListener(MouseEvent.CLICK,
pauseHandler);
playBtn.addEventListener(MouseEvent.CLICK, playHandler);
stopBtn.addEventListener(MouseEvent.CLICK, stopHandler);
togglePauseBtn.addEventListener(MouseEvent.CLICK,
togPauseHandler);
function pauseHandler(event:MouseEvent):void {
ns.pause();
{
function playHandler(event:MouseEvent):void {
ns.resume();
{
function stopHandler(event:MouseEvent):void {
// Pause the stream and move the playhead back to // the
beginning of the stream.
ns.pause();
ns.seek(0);
{
function togPauseHandler(event:MouseEvent):void {
ns.togglePause();
{Meir Ohayon : ohmeir@gmail.com
6
This way you can implement a
playlist that loads the next
video once the current video
has finished playing.
Detecting the end of a video stream
ns.addEventListener(NetStatusEvent.NET_STATUS,
statusHandler);
function statusHandler(event:NetStatusEvent):void
}
trace(event.info.code);
{
Output:
NetStream.Play.Start
NetStream.Buffer.Empty
NetStream.Buffer.Full
NetStream.Buffer.Empty
NetStream.Buffer.Full
NetStream.Buffer.Empty
NetStream.Buffer.Full
NetStream.Buffer.Flush
NetStream.Play.Stop
NetStream.Buffer.Empty
NetStream.Buffer.Flush
Reminder
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
asyncErrorHandler);
ns.play("video.flv");
function asyncErrorHandler(event:AsyncErrorEvent):void {
trace(event.text);
{
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid); Meir Ohayon : ohmeir@gmail.com
7
Problem with the reminder when having metadata or
cue point(s)
Error #2095: flash.net.NetStream was unable to invoke callback
onMetaData.
Error #2095: flash.net.NetStream was unable to invoke callback
onCuePoint.
Error #2095: flash.net.NetStream was unable to invoke callback
onCuePoint.
Error #2095: flash.net.NetStream was unable to invoke callback
onCuePoint.
The error occurs because the NetStream object was unable to
find an onMetaData or onCuePoint callback method.
Solution 1: Set the NetStream object's client
property to an Object
var nc:NetConnection = new NetConnection();
nc.connect(null);
var customClient:Object = new Object();
var ns:NetStream = new NetStream(nc);
ns.client = customClient;
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
If you wanted to listen for either the onMetaData or onCuePoint
callback methods, you would need to define methods to handle those
callback methods, as shown in the following snippet:
var customClient:Object = new Object();
customClient.onMetaData = metaDataHandler;
function metaDataHandler(infoObject:Object):void
}
trace("metadata");
{Meir Ohayon : ohmeir@gmail.com
8
Solution 2: Create a custom class and define
methods to handle the callback methods
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.client = new CustomClient();
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
The CustomClient class is as follows:
package
}
public class CustomClient
}
public function onMetaData(infoObject:Object):void
}
trace("metadata");
{
{
{
Solution 3: Extend the NetStream class and add
methods to handle the callback methods
var ns:CustomNetStream = new CustomNetStream();
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
The following code listing defines the CustomNetStream class that
extends the NetStream class, handles the creation of the necessary
NetConnection object, and handles the onMetaData and onCuePoint
callback handler methods: Meir Ohayon : ohmeir@gmail.com
9
package
}
import flash.net.NetConnection;
import flash.net.NetStream;
public class CustomNetStream extends NetStream
}
private var nc:NetConnection;
public function CustomNetStream()
}
nc = new NetConnection();
nc.connect(null);
super(nc);
{
public function onMetaData(infoObject:Object):void
}
trace("metadata");
{
public function onCuePoint(infoObject:Object):void
}
trace("cue point");
{
{
{
If you want to rename the onMetaData() and onCuePoint() methods
in the CustomNetStream class, you could use the following code:
package
}
import flash.net.NetConnection;
import flash.net.NetStream;
public class CustomNetStream extends NetStream
}
private var nc:NetConnection;
public var onMetaData:Function;
public var onCuePoint:Function;
public function CustomNetStream()
}
onMetaData = metaDataHandler;
onCuePoint = cuePointHandler;
nc = new NetConnection();
nc.connect(null);
super(nc);
{ Meir Ohayon : ohmeir@gmail.com
10
private function metaDataHandler(infoObject:Object):void
}
trace("metadata");
{
private function cuePointHandler(infoObject:Object):void
}
trace("cue point");
{
{
{
Solution 4: Extend the NetStream class and make it
dynamic
var ns:DynamicCustomNetStream = new DynamicCustomNetStream();
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
The DynamicCustomNetStream class is as follows:
package
}
import flash.net.NetConnection;
import flash.net.NetStream;
public dynamic class DynamicCustomNetStream extends NetStream
}
private var nc:NetConnection;
public function DynamicCustomNetStream()
}
nc = new NetConnection();
nc.connect(null);
super(nc);
{
{
{
Even with no handlers for the onMetaData and onCuePoint callback
handlers, no errors are thrown since the DynamicCustomNetStream class Meir Ohayon : ohmeir@gmail.com
11
is dynamic. If you want to define methods for the onMetaData and
onCuePoint callback handlers, you could use the following code:
var ns:DynamicCustomNetStream = new DynamicCustomNetStream();
ns.onMetaData = metaDataHandler;
ns.onCuePoint = cuePointHandler;
ns.play("http://www.helpexamples.com/flash/video/cuepoints.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
function metaDataHandler(infoObject:Object):void
}
trace("metadata");
{
function cuePointHandler(infoObject:Object):void
}
trace("cue point");
{
Solution 5: Set the NetStream object's client
property to this
By setting the client property to this, Flash Player looks in the
current scope for onMetaData() and onCuePoint() methods. You
can see this in the following example:
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.client = this;
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid); Meir Ohayon : ohmeir@gmail.com
12
If the onMetaData or onCuePoint callback handlers are called and
no methods exist to handle the callback, no errors are generated. To
handle these callback handlers, create an onMetaData() and
onCuePoint() method in your code, as seen in the following snippet:
function onMetaData(infoObject:Object):void
}
trace("metadata");
{
function onCuePoint(infoObject:Object):void
}
trace("cue point");
{
Setting the buffer time
ns.bufferTime(8);
The default time is 10 (mesured in seconds). Meir Ohayon : ohmeir@gmail.com
13
Using video metadata
The previous code generates code similar to the following, assuming your
FLV file contains cue points and audio:
width: 320
audiodelay: 0.038
canSeekToEnd: true
height: 213
cuePoints: ,,
audiodatarate: 96
duration: 16.334
videodatarate: 400
framerate: 15
videocodecid: 4
audiocodecid: 2
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.client = this;
ns.play("video.flv");
var vid:Video = new Video();
vid.attachNetStream(ns);
addChild(vid);
function onMetaData(infoObject:Object):void
}
var key:String;
for (key in infoObject)
}
trace(key + ": " + infoObject[key]);
{
{Meir Ohayon : ohmeir@gmail.com
14
Video metadata: videocodecid
videocodecid Codec name
2 Sorenson H.263
3 Screen video (SWF 7 and later only)
4 VP6 (SWF 8 and later only)
5 VP6 video with alpha channel (SWF 8 and later only)
Video metadata: audiocodecid
audiocodecid Codec Name
0 uncompressed
1 ADPCM
2 mp3
5 Nellymoser 8kHz mono
6 Nellymoser
Video: Complete Example
Download and extract from
www.adobe.com/go/as3examples
In the folder Samples/VideoJukebox
add those files to new flex project:
o videoJukebox.mxml
o playlist.xml