Skip to main content
August 16, 2011
Answered

Scrub Bar Problems

  • August 16, 2011
  • 1 reply
  • 2308 views

My scrub bar isn't so percise. When I scrub, the duration is off track. What am I doing wrong? Please help.


PS, it's stream NOT progressive.

// ##########################
// ############# 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 objInfo:Object;

var dur:Number;

var totalBytes:Number;

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

// Create a new NetConnection instance
var conn:NetConnection = new NetConnection();

// Connect with a null value for progressive FLV files
conn.connect(null);

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

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.btnStop.addEventListener(MouseEvent.CLICK, stopClicked);
    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);

    // set the smoothing value from the constant
    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();
   
    }
   
    // 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 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();
   
    }
   
    // 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 stopClicked(e:MouseEvent):void {
    // calls stop function
    stopVideoPlayer();
    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;
   
    // start drag
    controlPanel.mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, -6, 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;
}

var duration:Number;

function updateDisplay(ev:TimerEvent):void {
    // checks, if user is scrubbing. if so, seek in the video
    // if not, just update the position of the scrubber according
    // to the current time
    if(bolProgressScrub)
   
        nsStream.seek( Math.round( controlPanel.mcVideoControls.mcProgressScrubber.x * objInfo.duration / 630 ) )
   
    else
    controlPanel.mcVideoControls.mcProgressScrubber.x = nsStream.time * 630 / objInfo.duration;
   
    // set time and duration label
    controlPanel.mcVideoControls.lblTimeDuration.htmlText        = "<font color='#FFFFFF'>" + formatTime(nsStream.time) + "</font> / " + formatTime(objInfo.duration);
   
    controlPanel.mcVideoControls.mcProgressScrubber.durationBubble.lblTimeDuration.htmlText        = "<font color='#FFFFFF'>" + formatTime(nsStream.time) + "</font>";
   
    // update the width from the progress bar. the grey one displays
    // the loading progress
    controlPanel.mcVideoControls.mcProgressFill.mcFillRed.width        =     controlPanel.mcVideoControls.mcProgressScrubber.x + 5;
    controlPanel.mcVideoControls.mcProgressFill.mcFillGrey.width    =    nsStream.bytesLoaded * 630 / nsStream.bytesTotal;
   
    // update volume and the red fill width when user is scrubbing
    if(bolVolumeScrub) {
        setVolume((controlPanel.mcVideoControls.mcVolumeScrubber.x - 341) / 53);
        controlPanel.mcVideoControls.mcVolumeFill.mcFillRed.width = controlPanel.mcVideoControls.mcVolumeScrubber.x - 394 + 53;
    }
   
}

function onMetaData(info:Object):void {
   
objInfo = info;

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

}

function netStatusHandler(event:NetStatusEvent):void {
    // handles net status events
   
    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.bufferTime = BUFFER_TIME;
   
    // nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
   
    nsStream.client =  this;
   
    bolLoaded = true;
   
    vidDisplay.attachNetStream(nsStream);       
   
    nsStream.seek(5);
   
    nsStream.play(strSource);
   
    nsStream.pause();
   
    // attach net stream to video object on the stage
    vidDisplay.attachNetStream(nsStream);
   
    vidDisplay.visible = true;
   
}

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 remainder:Number;
           
    var hours:Number = t / ( 60 * 60 );
   
    remainder = hours - (Math.floor ( hours ));
   
    hours = Math.floor ( hours );
   
    var minutes = remainder * 60;
   
    remainder = minutes - (Math.floor ( minutes ));
   
    minutes = Math.floor ( minutes );
   
    var seconds = remainder * 60;
   
    remainder = seconds - (Math.floor ( seconds ));
   
    seconds = Math.floor ( seconds );
   
    var hString:String = hours < 10 ? "0" + hours : "" + hours;   
    var mString:String = minutes < 10 ? "0" + minutes : "" + minutes;
    var sString:String = seconds < 10 ? "0" + seconds : "" + seconds;
               
    if ( t < 0 || isNaN(t)) return "00:00";           
               
    if ( hours > 0 )
    {           
        return hString + ":" + mString + ":" + sString;
    }else
    {
        return mString + ":" + sString;
    }
           
}


// ##########################
// ############# INIT PLAYER
// ##########################
initVideoPlayer();

    This topic has been closed for replies.
    Correct answer calmchessplayer

    ok when you read this code it might seem like its for Audio thats because it used to be for audio only but I modified it but didn't change variable names and stuff it will work for your code if you just study the math you are on the right track. Oh yeah there is some comented code for MP3  enjoy.

    private function ChangeHandler(event:Event=null):void {
      
       if(main00.play_btn.y ==2800 && main00.pause_btn.y==2800){
          main00.play_btn.y =15;
       }
      
       if(main00.progBar.scrubber.x==0 && main00.progBar.progBar==100){
        main00.progBar.progBar.reset();
       }
      
       if (oneTime0==0) {
        //main00.progBar.progBar.reset();
        oneTime0=1;
       }
       //amountLoaded = audioR0.time/duration;
             //main00.progBar.progBar.width = amountLoaded*218;
            if(stopScrub==0){
         main00.progBar.scrubber.x = audioR0.time/duration*main00.progBar.progBar.width;
         }
     
      
       //main00.progBar.scrubber.x = percent;
       //seconds//getmetadata
       main00.progBar.progBar.setProgress(audioR0.time,duration);
      
      percent = int(main00.progBar.progBar.percentComplete);
       if(percent ==100){
        main00.progBar.progBar.reset();
        main00.progBar.scrubber.x=main00.progBar.progBar.x;
       }

      }
      /*
      private function Mp3Tim(e:TimerEvent){
          if(oneTime1 ==0){
         
       //dur total number of segments
       var dur=Math.ceil(soundFactory.length/1000);//number of segments
       trace("duration = "+dur);
          inc = 1;
       oneTime1=1;
       }
      
       inc = (inc++)+1.114;
       trace(inc);
       dur=Math.ceil(soundFactory.length/1000);//number of segments
       progBar.progBar.setProgress(inc,dur);
       //the end of MP3 is delayed by 5 seconds to allow for slight changes multiple mp3 length .
       if(inc >= dur+5){
       Mp3Fin();
       }
      }
      */
     
     
     
      function CompleteHandler(e:Event):void {
       //oneTime0=0;
      
      
       progBar.progBar.setProgress(100,100);

      }


    here you need this too

    private function thumbMove(e:MouseEvent):void {
       main00.progBar.scrubber.x = mouseX - yOffset;
       if (main00.progBar.scrubber.x <= yMin) {
        main00.progBar.scrubber.x = yMin;
       }
       if (main00.progBar.scrubber.x >= yMax) {
        main00.progBar.scrubber.x = yMax;
       }
       dispatchEvent(new ScrollBarEvent(main00.progBar.scrubber.x / yMax));
       e.updateAfterEvent();
      }

    1 reply

    calmchessplayer
    Inspiring
    August 16, 2011

    I didn't take the time to read your code I will ask instead are you using metadata to find the length of the .flv ?you must change the metadata to precisely reflect the .flv  for MP3 I use the program MP3Tag. Not sure what you streamings and if I remember correctly there is a tool for change flv metadata in the FMS tools directory.

    August 16, 2011

    Yes I am. You can see that by looking at the function named "onMetaData." So does this have to do with my meta data?

    calmchessplayer
    Inspiring
    August 16, 2011

    great that question is out  of the way  now we come to the hard part. making a scrub bar is not trivial but you are on the correct path either you will have to spend many hours debugging it and figuring it out  The first time I built one without help took me 1 month of probably 12 hour days to build it. However I didn't use tutorials or anything for help. maybe you shoud find a tutorial or hire somebody to build it for you. I have one but I don't think adobe appericiate me doing business  here.