hates the internet

Post thumbnail is Paper tape by sfllaw

Zen and the Art of Cueing.

Capturing cue points on the client end is very easy. This is done by creating an onCuePoint property on whatever object you're using for NetStream.client and pointing it to a function. This will get called with the object the NetStream encounters in the stream:

function handleCue( theCue:Object ) {
    trace( "Encountered " + theCue.name + " at " + theCue.time );
}

var myCallback:Object = new Object();
myCallback.onCuePoint = handleCue;

var myStream:netStream = new NetStream( myConnection );
myStream.client = myCallback;

myStream.play( "file_with_cues.flv" );

Data About the Data

As you know, when you start .play()ing a NetStream, usually before the first frame of video plays an onMetaData event is sent. The data object passed to this event contains a cuePoints property which contains all the cuepoints you can expect in this file. The main use for this is pulling out navigation cues to make a table of contents:

function onMetaData( poData:Object )  {
    for( lsNum:String in poData.cuePoints ) {
        var loCue:Object = poData.cuePoints[lsNum];
        if( loCue.type == "navigation" ) {
            trace( "Cue " + lsNum + ": Chapter " + loCue.name + 
                " at " + loCue.time + " seconds" );
        } // if
    } // for<
} // function

How Red5 Handles Cues

Red5 treats cues as an extension of a file's meta data. The very lowest level in the Red5 cue hierarchy is the org.red5.io.flv.meta.MetaCue. This is the object that will get passed to your NetStream's onCuePoint handler. Outside of the required options, MetaCues can be treated like HashTables:

import org.red5.io.flv.meta.MetaCue;
MetaCue cue = new MetaCue();
cue.setTime( 40 ); // Time in seconds
cue.setType( "event" ); // cue type, "event" or "navigation"
cue.setName( "MyEvent" ); // name for this event
cue.put( "that", "this" );

When this cue point is hit, your custom fields can be accessed as properties:

trace( "At cue point " + poCue.time + ", that is " + poCue.that );

Cues the the file level

Cues are set at the file level by passing an array of MetaCue objects to org.red5.io.flv.met.MetaData's setMetaCue method:

MetaCue[] loCues = new MetaCue[10];
MetaCue loTemp = null;
int liX = 0;
for( liX = 0; liX < 10; liX ++ ) {
    loTemp = new MetaCue();
    loTemp.setTime( liX * 10 );
    loTemp.setName( "Auto Cue " + liX );
    loTemp.setType( "event" );
    loTemp.put( "count", liX );
    loCues[liX] = loTemp;
}

Storing your Cues

So, now you have the various fields in your MetaData set properly, you've added your array of MetaCues, all that remains is to write the metadata to the org.red5.io.flv.impl.FLV:

File loFile = new File( "my_test_flv.flv" );
FLV loFLV = new FLV( loFile );
loFLV.setMetaData( loMD );

And that's that. The cues are automatically inserted into the file's MetaData header as well as into the File's stream itself. This overwrites the existing file and can take quite a while to complete on larger files.

That's All Folks

That's really all there is to it, an array, a little bit of disk thrasing and these three imports:

org.red5.io.flv.impl.FLV
org.red5.io.flv.meta.MetaCue
org.red5.io.flv.meta.MetaData

Post new comment

The content of this field is kept private and will not be shown publicly.