# Custom AS3 RTMP Video Player Help (Streaming is fine, the scrubber isn't)

**URL:** <https://forum.kirupa.com/t/custom-as3-rtmp-video-player-help-streaming-is-fine-the-scrubber-isnt/325871>\
**Category:** flash\
**Created:** [November 9, 2011, 1:09pm UTC](https://forum.kirupa.com/t/custom-as3-rtmp-video-player-help-streaming-is-fine-the-scrubber-isnt/325871 "2011-11-09T13:09:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![DannyGraphics](https://avatars.discourse-cdn.com/v4/letter/d/f6c823/32.png) [@DannyGraphics](https://forum.kirupa.com/u/DannyGraphics)\
**Post date:** [November 9, 2011, 1:09pm UTC](https://forum.kirupa.com/t/custom-as3-rtmp-video-player-help-streaming-is-fine-the-scrubber-isnt/325871/1 "2011-11-09T13:09:13Z")

</div>

To those that help me with this tutorial, will get credit to whatever on one of my website tutorials here: [http://www.funtut.com/building-an-rtmp-as3-video-player/](http://www.funtut.com/building-an-rtmp-as3-video-player/)  
[URL=“[http://www.funtut.com/building-an-rtmp-as3-video-player/](http://www.funtut.com/building-an-rtmp-as3-video-player/)”]  
The streaming is all fine, I got it all worked out, but when I scrub, the duration scrambles. When I stop scrubbing, the scrubber literally sets to where the duration was read. Does that make sense? Other words, the duration isn’t accurate. How do I fix this problem? Is there anything that I’m doing wrong? My code is below or you can visit the link that I’ve shared. Please help!

```auto

// Import AS3 class files
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.NetStatusEvent;
import flash.events.MouseEvent;
import flash.display.SimpleButton;
import flash.events.TimerEvent;

// ##########################
// ############# CONSTANTS
// ##########################

// time to buffer for the video in sec.
const BUFFER_TIME:Number = 8;
// start volume when initializing player
const DEFAULT_VOLUME:Number = 0.6;
// update delay in milliseconds.
const DISPLAY_TIMER_UPDATE_DELAY:int = 10;
// smoothing for video. may slow down old computers
const SMOOTHING:Boolean = true;
 
// ##########################
// ############# VARIABLES
// ##########################

// flag for knowing if flv has been loaded
var bolLoaded:Boolean = false;
// flag for volume scrubbing
var bolVolumeScrub:Boolean = false;
// flag for progress scrubbing
var bolProgressScrub:Boolean = false;
// holds the last used volume, but never 0
var intLastVolume:Number = DEFAULT_VOLUME;
// net connection object for net stream
var ncConnection:NetConnection;
// net stream object
var nsStream:NetStream;
// object holds all meta data
var liveVideo:Video;

var objInfo:Object;
//rtmp of server hosting the flv
var FLVServer:String = "rtmp://www.chameleon.com/vids";
//flv file

var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters;

//var strSource:String = paramObj['video_id'] + ".flv";
var strSource:String = "6.flv";
// timer for updating player (progress, volume...)
var tmrDisplay:Timer;
 
// ##########################
// ############# FUNCTIONS
// ##########################
 
// sets up the player
function initVideoPlayer():void {
    // hide buttons
    controlPanel.mcVideoControls.btnUnmute.visible = false;
    controlPanel.mcVideoControls.btnPause.visible = false;
    controlPanel.mcVideoControls.normalS.visible = false;
    
    // set the progress/preload fill width to 1
    controlPanel.mcVideoControls.mcProgressFill.mcFillRed.width = 1;
    controlPanel.mcVideoControls.mcProgressFill.mcFillGrey.width = 1;
    
    // add global event listener when mouse is released
    stage.addEventListener( MouseEvent.MOUSE_UP, mouseReleased);
    stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreen);
    
// ##########################
// ###### PB HIDEN TIMER
// ##########################
 
    stage.addEventListener(MouseEvent.MOUSE_MOVE, cPanel);
    
    function cPanel(event:MouseEvent):void {
        
        controlPanel.gotoAndPlay(1);
        
        controlPanel.mcVideoControls.mcProgressScrubber.btnProgressScrubber.visible = true;
        
        Mouse.show();
    
    }
    // add event listeners to all buttons
    controlPanel.mcVideoControls.btnPause.addEventListener(MouseEvent.CLICK, pauseClicked);
    controlPanel.mcVideoControls.btnPlay.addEventListener(MouseEvent.CLICK, playClicked);
    controlPanel.mcVideoControls.btnMute.addEventListener(MouseEvent.CLICK, muteClicked);
    controlPanel.mcVideoControls.btnUnmute.addEventListener(MouseEvent.CLICK, unmuteClicked);
    controlPanel.mcVideoControls.btnProgressBar.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);
    controlPanel.mcVideoControls.btnVolumeBar.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
    controlPanel.mcVideoControls.mcProgressScrubber.btnProgressScrubber.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);
    big_play.addEventListener(MouseEvent.CLICK, BIGPLAY);
    controlPanel.mcVideoControls.fullS.addEventListener(MouseEvent.CLICK, FullScreen);
    controlPanel.mcVideoControls.normalS.addEventListener(MouseEvent.CLICK, NormalScreen);
		
	// create timer for updating all visual parts of player and add
	// event listener
	tmrDisplay = new Timer(DISPLAY_TIMER_UPDATE_DELAY);
	tmrDisplay.addEventListener(TimerEvent.TIMER, updateDisplay);
	
	// create a new net connection, add event listener and connect
	// to null because we don't have a media server
	ncConnection = new NetConnection();
	ncConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
	ncConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
	ncConnection.connect(FLVServer);
	
	nsStream = new NetStream(ncConnection);
	nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
	nsStream.client = this;
	nsStream.bufferTime = BUFFER_TIME;
	
	// set the smoothing value from the constant
	vidDisplay.attachNetStream(nsStream);
	vidDisplay.smoothing = SMOOTHING;
    controlPanel.mcVideoControls.mcProgressScrubber.durationBubble.visible = false;
 
    // set default volume
    controlPanel.mcVideoControls.mcVolumeScrubber.x = (52 * DEFAULT_VOLUME) + 341;
    controlPanel.mcVideoControls.mcVolumeFill.mcFillRed.width = controlPanel.mcVideoControls.mcVolumeScrubber.x - 394 + 52;
	
}
 
function onFullscreen(e:FullScreenEvent):void {
    // check if we're entering or leaving fullscreen mode
    if (e.fullScreen) {
        // switch fullscreen buttons
        controlPanel.mcVideoControls.fullS.visible = false;
        controlPanel.mcVideoControls.normalS.visible = true;
 
        // bottom center align controls
        controlPanel.x = (Capabilities.screenResolutionX - 440) / 2;
        controlPanel.y = (Capabilities.screenResolutionY - 33);
 
        // size up video display
        vidDisplay.height = (Capabilities.screenResolutionY - 33);
        vidDisplay.width = vidDisplay.height * 4 / 3;
        vidDisplay.x = (Capabilities.screenResolutionX - vidDisplay.width) / 2;
    } else {
        // switch fullscreen buttons
        controlPanel.mcVideoControls.fullS.visible = true;
        controlPanel.mcVideoControls.normalS.visible = false;     
 
        // reset controls position
        controlPanel.x = 0;
        controlPanel.y = 330;
 
        // reset video display
        vidDisplay.y = 0;
        vidDisplay.x = 0;
        vidDisplay.width = 440;
        vidDisplay.height = 330;
    }
}
 
function FullScreen(e:MouseEvent):void {
    
    stage.displayState = "fullScreen";
    
    controlPanel.mcVideoControls.normalS.visible = true;
    
}
 
function NormalScreen(e:MouseEvent):void {
    
    stage.displayState = "normal";
    
    controlPanel.mcVideoControls.fullS.visible = false;
    
}
 
function BIGPLAY(e:MouseEvent):void {
    
    if( bolLoaded) {
 
        nsStream.resume();
		
		bufferClip.visible = true;
    
    }
    
    // show video display
    vidDisplay.visible = true;
    
    // switch play/pause visibility
    controlPanel.mcVideoControls.btnPause.visible = true;
    controlPanel.mcVideoControls.btnPlay.visible = false;
    big_play.visible = false;
    
}
 bufferClip.visible = false;
 
function playClicked(e:MouseEvent):void {
    // check's, if the flv has already begun
    // to download. if so, resume playback, else
    // load the file
    if( bolLoaded) {
 
        nsStream.resume();
		
		bufferClip.visible = true;
    
    }
    
    // show video display
    vidDisplay.visible = true;
    
    // switch play/pause visibility
    controlPanel.mcVideoControls.btnPause.visible = true;
    controlPanel.mcVideoControls.btnPlay.visible = false;
    big_play.visible = false;
}
 
function pauseClicked(e:MouseEvent):void {
    // pause video
    nsStream.pause();
    
    // switch play/pause visibility
    controlPanel.mcVideoControls.btnPause.visible = false;
    controlPanel.mcVideoControls.btnPlay.visible = true;
    big_play.visible = true;
}
 
function muteClicked(e:MouseEvent):void {
    // set volume to 0
    setVolume(0);
    
    // update scrubber and fill position/width
    controlPanel.mcVideoControls.mcVolumeScrubber.x = 341;
    controlPanel.mcVideoControls.mcVolumeFill.mcFillRed.width = 1;
}
 
function unmuteClicked(e:MouseEvent):void {
    // set volume to last used value
    setVolume(intLastVolume);
 
    // update scrubber and fill position/width
    controlPanel.mcVideoControls.mcVolumeScrubber.x = (53 * intLastVolume) + 341;
    controlPanel.mcVideoControls.mcVolumeFill.mcFillRed.width = controlPanel.mcVideoControls.mcVolumeScrubber.x - 394 + 53;
}

function volumeScrubberClicked(e:MouseEvent):void {
    // set volume scrub flag to true
    bolVolumeScrub = true;
    
    // start drag
    controlPanel.mcVideoControls.mcVolumeScrubber.startDrag(true, new Rectangle(341, 19, 53, 0));
}

function progressScrubberClicked(e:MouseEvent):void {
	
    // set progress scrub flag to true
    bolProgressScrub = true;
    
    controlPanel.mcVideoControls.mcProgressScrubber.durationBubble.visible = true;
    
	controlPanel.mcVideoControls.mcProgressScrubber.x = controlPanel.mcVideoControls.mouseX - controlPanel.mcVideoControls.mcProgressScrubber.width/2;
	
    // start drag
    controlPanel.mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, -9, 630, 0));
	
}
 
function mouseReleased(e:MouseEvent):void {
    // set progress/volume scrub to false
    bolVolumeScrub = false;
    bolProgressScrub = false;
    
    controlPanel.mcVideoControls.mcProgressScrubber.durationBubble.visible = false;
    
    // stop all dragging actions
    controlPanel.mcVideoControls.mcProgressScrubber.stopDrag();
    controlPanel.mcVideoControls.mcVolumeScrubber.stopDrag();
    
    // update progress/volume fill
    
    controlPanel.mcVideoControls.mcProgressFill.mcFillRed.width = controlPanel.mcVideoControls.mcProgressScrubber.x + 5;
    
    controlPanel.mcVideoControls.mcVolumeFill.mcFillRed.width = controlPanel.mcVideoControls.mcVolumeScrubber.x - 394 + 53;
    
    // save the volume if it's greater than zero
    if((controlPanel.mcVideoControls.mcVolumeScrubber.x - 341) / 53 > 0)
        intLastVolume = (controlPanel.mcVideoControls.mcVolumeScrubber.x - 341) / 53;
}

function updateDisplay(ev:TimerEvent):void {
		
	if(bolProgressScrub)
	{
		nsStream.seek( Math.floor( (controlPanel.mcVideoControls.mcProgressScrubber.x * streamLength_num) / 630 ) );
		
	} else { controlPanel.mcVideoControls.mcProgressScrubber.x = nsStream.time / streamLength_num * 630; }
		
    // set time and duration label Math.round((ns.time / streamLength) * 10000) / 100;
    controlPanel.mcVideoControls.lblTimeDuration.htmlText = "" + formatTime(nsStream.time) + " / " + formatTime(streamLength_num);
    
    controlPanel.mcVideoControls.mcProgressScrubber.durationBubble.lblTimeDuration.htmlText = "" + formatTime(nsStream.time) + " / " + formatTime(streamLength_num);
    
	controlPanel.mcVideoControls.mcProgressFill.mcFillRed.width = controlPanel.mcVideoControls.mcProgressScrubber.x + 5;
	
}

var streamLength_num:Number;

function onMetaData(info:Object):void {

objInfo = info;

streamLength_num = info.duration;

for (var propName:String in objInfo) {
	trace(propName + " = " + objInfo[propName]);
}

// now we can start the timer because
// we have all the necessary data
if(!tmrDisplay.running)
tmrDisplay.start();
 
}

function netStatusHandler(event:NetStatusEvent):void {
	
	if(event.info.code == "NetStream.Buffer.Full"){
		bufferClip.visible = false;
	}
	
	if(event.info.code == "NetStream.Buffer.Empty"){
		bufferClip.visible = true;
	}
	
	trace( event.info.code );
	
	switch (event.info.code) {

		case "NetConnection.Connect.Success":
		   
		   connectStream();
			
			break;
			
		// trace a messeage when the stream is not found
		case "NetStream.Play.StreamNotFound":
			trace("Stream not found: " + strSource);
			break;
		
		// when the video reaches its end, we stop the player
		case "NetStream.Play.Stop":
			stopVideoPlayer();
			trace('stoped');
		break;
	}
		
		
}
 
function securityErrorHandler(event:SecurityErrorEvent):void {
    
    trace("securityErrorHandler: " + event);
 
}

function connectStream():void {
    
    nsStream = new NetStream(ncConnection);
    
    nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
	
	nsStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
    
    nsStream.client = this;
	
	nsStream.bufferTime = BUFFER_TIME;
    
    vidDisplay.attachNetStream(nsStream);
	
	vidDisplay.smoothing = SMOOTHING;
    
	
	/* EXTRA */
	
    nsStream.seek(0.01);
	
	bolLoaded = true;
    
    nsStream.play(strSource);
    
    nsStream.pause();
	
	bolProgressScrub = false;
	
}

function asyncErrorHandler(event:AsyncErrorEvent):void {
// ignore AsyncErrorEvent events.
} 
 
function stopVideoPlayer():void {
    // pause netstream, set time position to zero
    nsStream.pause();
    nsStream.seek(0);
    
    // in order to clear the display, we need to
    // set the visibility to false since the clear
    // function has a bug
    vidDisplay.visible = false;
    
    // switch play/pause button visibility
    controlPanel.mcVideoControls.btnPause.visible = false;
    controlPanel.mcVideoControls.btnPlay.visible = true;
}
 
function setVolume(intVolume:Number = 0):void {
    // create soundtransform object with the volume from
    // the parameter
    var sndTransform = new SoundTransform(intVolume);
    // assign object to netstream sound transform object
    nsStream.soundTransform = sndTransform;
    
    // hides/shows mute and unmute button according to the
    // volume
    if(intVolume > 0) {
        controlPanel.mcVideoControls.btnMute.visible = true;
        controlPanel.mcVideoControls.btnUnmute.visible = false;
    } else {
        controlPanel.mcVideoControls.btnMute.visible = false;
        controlPanel.mcVideoControls.btnUnmute.visible = true;
    }
}
 
function formatTime(t:int):String {
 var s:int = Math.round(t);
 var m:int = 0;
 if (s > 0) {
  while (s > 59) {
   m++;
   s -= 60;
  }
  return String((m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s);
 } else {
  return "00:00";
 }
}
 
 
// ##########################
// ############# INIT PLAYER
// ##########################
initVideoPlayer();

```

Would you like me to share piece by piece to make it easier to correct?
