ActionScript - movie playback with pause and rewind controls

From NoskeWiki
Jump to: navigation, search

About

NOTE: This page is a daughter page of: ActionScript


Due to the structure of ActionScript 3.0 there are a number of ways to implement playback controls, but below is a simple solution to play, pause, rewind and fast-forward the main timeline.


Pause and Play Controls

Let's start with just the pause and play controls.

INSTRUCTIONS: To get this code working will need to create two buttons named "btn_play" and "btn_pause". To save time you can use the menubar in Flash and click Windows > Common Libraries > Buttons and under "playback flat" drag a play and pause button onto your scene, then make sure you use the Properties panel to change their "instance name name" to "btn_play" and "btn_pause". In the very first frame of the TimeLine right click and select "Actions" to add the following code to frame 1:

btn_play.addEventListener        (MouseEvent.CLICK, Play_Clicked);
btn_pause.addEventListener       (MouseEvent.CLICK, Pause_Clicked);
 
function Play_Clicked(e:MouseEvent):void     { PlayMainVideo();  }
function Pause_Clicked (e:MouseEvent):void   { PauseMainVideo(); }
 
function PlayMainVideo():void
{
  btn_play.visible = false;        // Hide play button.
  btn_pause.visible = true;        // Show pause button.
  this.play();
}
 
function PauseMainVideo():void
{
  btn_play.visible = true;         // Show play button.
  btn_pause.visible = false;       // Hide pause button.
  this.stop();
}
 
Play_Clicked();     // Will hide the play button when your movie starts.

NOTE: If desired the content of "PlayMainVideo()" can be moved to the "Play_Clicked()" function (and the same for rewind) to reduce code. My reason for creating separate (non-event) functions is that it allows me to call the bottom two functions from anywhere - for instance I might want to call "PauseMainVideo()" on the very last frame of my scene so the movie won't loop and the play button will appear. In the following example you'll notice rewind and fast-forward both use these functions too.


Adding Intelligent Rewind and Fast-FowardControls

Rewind and fast-forward can behave in different ways. If you want to rewind to the start in one click or click multiple times to progressively rewind it is easy:

btn_rewind.addEventListenerMouseEvent.CLICK, Rewind_Clicked);
 
function Rewind_Clicked(e:MouseEvent):void
{
  this.gotoAndStop( this.currentFrame - 10 );    // NOTE: Set this to 1 to go to the first frame....
                                                 // or this.totalFrames to jump to the last frame
}

This code will rewind when you click, but clicking multiple times to progressively rewind is very annoying. Instead you will probably want to rewind or fast-foward while the button is held down. In ActionScript 3 this is surprisingly involved, because there is no "mouse over while down" event. Instead you'll need a combination of "MOUSE_DOWN", "MOUSE_UP" and "ENTER_FRAME" events, plus a variable to remember if the mouse is down. There is also a way to achieve this with "MOUSE_OVER" and "MOUSE_OUT", but the way I've used is easier. In the code below you'll notice I use "rewindDown" and "fastforwardDown" to record the number of frames the button is depressed so that there can be a short delay before the button starts repeatedly increasing or decreasing the current frame. By slightly modifying the code you could easily make these control button "accelerate" the longer it's held down or might decide to have it repeat this action immediately without any repeat delay.

INSTRUCTIONS: Continue from the "Pause and Play Controls" example and make sure you add two extra buttons in the main scene and name them "btn_rewind" and "btn_fastfoward". Paste the code below to replace the action script in frame 1. This code builds on the same functions from the previous example, but also includes comments.


//######################################################################
//## GLOBAL VARIABLES:
 
var rewindDown:int      = 0;    // Number of frames rewind button has been down.
var fastforwardDown:int = 0;    // Number of frames fastforward button has been down.
var BUTTON_DELAY:int    = 10;   // Number of frames before a button repeats an action.
 
//######################################################################
//## ADD EVENT LISTENERS:
 
btn_play.addEventListener        (MouseEvent.CLICK, Play_Clicked);
btn_pause.addEventListener       (MouseEvent.CLICK, Pause_Clicked);
 
btn_rewind.addEventListener       (MouseEvent.MOUSE_DOWN, Rewind_Down);
btn_rewind.addEventListener       (MouseEvent.MOUSE_UP,   Rewind_Up);
btn_rewind.addEventListener       (Event.ENTER_FRAME,     Rewind_EnterFrame);
btn_rewind.addEventListener       (MouseEvent.MOUSE_OUT,  Rewind_Up);      // Prevents button from getting "stuck" on.
 
btn_fastforward.addEventListener  (MouseEvent.MOUSE_DOWN, FastForward_Down);
btn_fastforward.addEventListener  (MouseEvent.MOUSE_UP,   FastForward_Up);
btn_fastforward.addEventListener  (Event.ENTER_FRAME,     FastForward_EnterFrame);
btn_fastforward.addEventListener  (MouseEvent.MOUSE_OUT,  FastForward_Up);  // Prevents button from getting "stuck" on.
 
//######################################################################
//## EVENT/CALLBACK FUNCTIONS:
 
function Play_Clicked(e:MouseEvent):void     { PlayMainVideo();  }
function Pause_Clicked (e:MouseEvent):void   { PauseMainVideo(); }
 
function Rewind_Down(e:MouseEvent):void      { rewindDown = 1; }
function Rewind_Up(e:MouseEvent):void        { rewindDown = 0; }
function Rewind_EnterFrame(e:Event):void
{
  if(rewindDown == 0)                  // If button not down:
    return;                            // do nothing. 
  if(rewindDown == 1)                  // If button just pressed: 
    ChangeFrame(-10, true, false);     // jump back 10 frames.
  if(rewindDown > BUTTON_DELAY)        // If button held long enough: 
    ChangeFrame(-5, true, false);      // keep rewinding 5 frames at a time.
  rewindDown++;
}
 
function FastForward_Down(e:MouseEvent):void { fastforwardDown = 1; }
function FastForward_Up(e:MouseEvent):void   { fastforwardDown = 0; }
function FastForward_EnterFrame(e:Event):void
{
  if(fastforwardDown == 0)             // If button not down: 
    return;                            // do nothing.
  if(fastforwardDown == 1)             // If button just pressed: 
    ChangeFrame(10, true, false);      // jump back 10 frames.
  if(fastforwardDown > BUTTON_DELAY)   // If button held long enough: 
    ChangeFrame(5, true, false);       // keep rewinding 5. frames at a time
  fastforwardDown++;
}
 
//######################################################################
//## VIDEO CONTROL FUNCTIONS:
 
//----------------------------------------
//-- Changes the current frame by the specified number of frames (changeAmount). If (goToAndPlay) is false it will pause the movie
//-- and will adjust the visibility of "btn_pause" and "btn_play" based
//-- on the value of (pauseMovie).
//-- > changeAmount  - positive or negative number of frames to change.
//-- > pauseMovie    - if true, will pause the movie else will keep playing.
//-- > loop          - if true, movie will loop to beginning if it passes the end.
 
function ChangeFrame( changeAmount:int, pauseMovie:Boolean, loop:Boolean ):void
{
  var newFrame = this.currentFrame + changeAmount;
 
  if (newFrame < 1)
    newFrame = 1;
  if (newFrame > this.totalFrames )
    newFrame = loop ? 1 : this.totalFrames;
 
  this.gotoAndStop( newFrame );
 
  if(pauseMovie)
    PauseMainVideo();
  else
    PlayMainVideo();
}
 
//----------------------------------------
//-- Sets the main movie to play and changes the visibility of
//-- "btn_pause" and "btn_play" accordingly.
 
function PlayMainVideo():void
{
  btn_play.visible = false;
  btn_pause.visible = true;
  this.play();
}
 
//----------------------------------------
//-- Pauses the main movie and changes the visibility of 
//-- "btn_pause" and "btn_play" accordingly.
 
function PauseMainVideo():void
{
  btn_play.visible = true;
  btn_pause.visible = false;
  this.stop();
}


Hope this solution helps you! Notice in the code above I include the lines "btn_rewind.addEventListener(MouseEvent.MOUSE_OUT, Rewind_Up);" and "btn_fastforward.addEventListener (MouseEvent.MOUSE_OUT, FastForward_Up);". These lines are not essential, but without them each button can get "stuck" on if you depress the mouse on a button, but release the mouse outside of that button.

Links