In this walkthrough you will:

Figure 4. Completed video player with replay and view-live features
Note: This walkthrough is a continuation from Walkthrough 1: Enabling DVR on a live stream. You can either use the same files used in that walkthrough or open a fresh starting set from the {start files}/hands-on/DVR-Consuming/start/ directory.
_onPlay() method. You can use the files from
the first walkthrough, or open the start files in the /DVR-Consuming/start/ directory._initConsumerDisplay() method._initConsumerDisplay() method. Inside that method, find the comment that begins:
//Play and specify...
Under this comment, call the play() method on the _ns NetStream object, passing it the property vidID as the first parameter, zero (0)
for the second parameter, and negative one (-1) as the third and
final parameter:
// Play and specify 0 for start, -1 for dur _ns.play( vidID, 0, -1 );
Call the attachNetStream() method on the consumerVideo Video
object and pass it the _ns NetStream object:
// Play and specify 0 for start, -1 for dur
Make sure the completed method looks like the following:
private function _initConsumerDisplay():void
{
_ns = new NetStream(nc);
_ns.client = new ConsumerClient( this );
_ns.addEventListener( NetStatusEvent.NET_STATUS,
_onNetStatus
);
_ns.addEventListener( AsyncErrorEvent.ASYNC_ERROR,
_onAsyncError );
//Start tracking the time
timer.addEventListener( TimerEvent.TIMER, _onTimer, false, 0, true );
_timer.start();
// Play and specify 0 for start, -1 for dur
_ns.play( vidID, 0, -1 );
consumerVideo.attachNetStream( _ns );
}
Locate the _onReplay() method. Inside this method, add a
call to the replay() method and pass it the value property of the replayTime_ns object:
replay( replayTime_ns.value );
The completed _onReplay() method should look like the
following:
private function _onReplay( p_evt:MouseEvent ):void
{
replay( replayTime_ns.value );
}
Locate the replay() method. Under the comment in the
method, call the seek() method on the _ns NetStream object
and pass it the result of _ns.time minus the p_time argument. The
completed method should look like the following:
public function replay( p_time:Number ):void
{
//Set seek time to current position minus the jump back time
_ns.seek( _ns.time - p_time );
}
Locate the onMetaData() method in the ConsumerClient
internal class. Under the comment that begins:
//Set the cur duration...
set the recordedDuration property of the _owner object equal to the duration property of the p_info object:
//Set the cur duration from metadata when received _owner.recordedDuration = p_info.duration;
recordedDuration. They
have been commented out./* before the getter
and */ after the setter's last curly brace.Under the comment that begins:
//Create a local variable...
create a local Number variable called timeSinceLastDuration and
set it equal to the result of a call to the getTimer() method minus _lastRecordedTime:
//Create the local var for timeSinceLastDuration var timeSinceLastDuration:Number = getTimer() - _lastRecordedTime;
To
finish off the recordedDuration getter method, return the result of _lastRecordedDuration plus the value of timeSinceLastDuration divided by one thousand (1000):
return _lastRecordedDuration + ( timeSinceLastDuration / 1000;
The completed getter method should look like the following:
public function get recordedDuration():Number
{
//Create the local var for timeSinceLastDuration
var timeSinceLastDuration:Number = getTimer() -
_lastRecordedTime;
//Return the estimated duration adjusting for miliseconds
return _lastRecordedDuration + ( timeSinceLastDuration / 1000 ) ;
}
In the
implicit setter method for recordedDuration, under the comment that begins:
// Track the value...
set the value of _lastRecordedDuration equal to the argument value:
// Track the value and store a initial time for comparision later _lastRecordedDuration = p_value;
Set the
value of _lastRecordedTime equal to the result of a call to the getTimer() method:
// Track the value and store a initial time for comparision later _lastRecordedDuration = p_value; _lastRecordedTime = getTimer();
The completed setter method for recordedDuration should
look similar to the following:
public function set recordedDuration( p_value:Number ):void
{
// Track the value and store a initial time for comparision
later
_lastRecordedDuration = p_value;
_lastRecordedTime = getTimer();
}
Locate
the _onRestart() method. In this method, call the NetStream's seek method to send the
stream back to 0 seconds:
private function _onRestart( p_evt:MouseEvent ):void
{ _ns.seek( 0 ); } _onCatchup() method. Inside the method add a call to the catchup() method. Locate
the catchup() method. Under the explanation that starts:
/* Optimized ...
call the seek() method on the _ns NetStream object and pass it the recordedDuration property:
public function catchup():void
{
//Simple way
//_ns.seek( 100000 );
/* Optimized way - though with this example assumes the
video recording hasn't stopped or paused during the whole
playback or video will restart if seeked past end existing time */
_ns.seek( recordedDuration );
}You have now created an application that can both broadcast and consume DVR-enabled video. You have even added controls for navigating the video with DVR functionality.
In the next walkthrough, you will test the functionality of your DVR player and see how you can replay moments from the live stream, as well as go to the beginning and navigate to the live broadcasting point of the stream.