VideoControlBar Class

 

Have you ever implemented an FLV video in your Flash project? The simple embedding of a video is quite easy, although it already requires the combination of several objects (a NetConnection, a NetStream, and a Video object). However, if you want to take total control over the video, it needs a lot of additional code. For instance, the possibility to stop, pause, play, to skip to another time position or to adjust the sound volume.
Don't panic: Here I present my VideoControlBar class that handles all these features: Similar to what you may know from YouTube videos, you can use that class in order to load and control an FLV video in your Flash project—with only three code lines!
The class provides, as a graphical interface, a control bar that scrolls into the screen when you move your mouse cursor over the display. This control bar contains buttons to stop, pause, and play the video, a time line that shows the current frame position and that can also be used to skip to another position, as well as an interactive element to adjust the relative sound volume of your video. In its entire beauty, the control bar looks as follows:

 

 

 

How to use the VideoControlBar class in your Flash project

In order to use my VideoControlBar class, you first have to copy the entire code block at the end of this page and copy it into a file named “VideoControlBar.as” and save that file in the same folder as your Flash project. Then you have to import it into your Flash project, as shown in the code block below. Next, you have to create an instance of this VideoControlBar object and finally you must add this object to the display list (addChild(instance name);).

 


import VideoControlBar;

var myVid:VideoControlBar = new VideoControlBar("DemoVideo.flv",480,360);

addChild(myVid);

 

When creating the VideoControlBar instance by calling the constructor, you will have to pass the path of the FLV video as the first argument to the object. There are more settings that can be modified this way, i.e., by passing further arguments to the constructor method of that class. The complete structure of the constructor is the following:

VideoControlBar(path:String, vidWidth:uint = 480, vidHeight:uint = 320, controlColor:uint = 0x00C070, fadeDelay:uint = 3000, startSoundVolume:Number = 0.5)

path:String – This first argument must be passed to the constructor method, as a string that contains the path to the FLV video.

vidWidth:uint – The second argument represents the width of the video, which typically corresponds to the width of the stage. This should be adjusted in case the width of the video differs from the default value 480.

vidHeight:uint - The third argument represents the height of the video, which typically corresponds to the height of the stage. This value should be adjusted in case the height of the video differs from the default value 320.
    
controlColor:uint – The fourth argument can be used to set another color for the control elements of the control bar, i.e., the color for the button symbols, the time line and the sound volume display. The default value is 0x00C070 (a greenish color).

fadeDelay:uint – The fifth argument determines the temporal delay before the control bar scrolls back to its initial position. The default value is 3000 msec. Note that the smoothness of the scrolling can be adjusted by the global FPS setting of your Flash application. In the demonstration above I used an FPS rate of 24.

startSoundVolume:Number – Finally, as the sixth and last argument, the starting value for the sound volume of your video can be modified, as a relative value between 0 and 1. The default value is 0.5 (50% of the original sound volume of the video).

 

The code of the VideoControlBar class

The following entire code block must be copied and pasted to a file named “VideoControlBar.as”:

 


package {
	
/*
 * @author Gunnar Wendt 2012
 * @version 1.0
 * 
 * www.worldwidewendt.com
 *
 */
	
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.filters.BevelFilter;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.AsyncErrorEvent;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.utils.Timer;
import flash.media.Video;
import flash.media.SoundTransform;	
	
public class VideoControlBar extends Sprite
{	
	
	private var onMyWayUp:Boolean = false;
	private var onMyWayDown:Boolean = false;
	private var standingStill:Boolean = false;
	private var totalVideoLength:Number;
	private var currentSoundVolume:Number;
	private var actionColor:uint;
	private var backColor:uint = 0x555555;
	private var buttonPause:Boolean = false;
	private var totalWidth:uint;
	private var timeBarWidth:uint;
	private var timeBarStart:uint = 70;
	private var textWidth:uint = 80;	
	
	private var backTimer:Timer;
	private var ns:NetStream;
	private var vid:Video = new Video();
	private var nsst:SoundTransform = new SoundTransform();
		
	private var back:Sprite = new Sprite();
	private var pauseBack:Sprite = new Sprite();
	private var playBack:Sprite = new Sprite();
	private var pauseButton:SimpleButton;
	
	private var timeProgress:Sprite = new Sprite();
	private var timeBarBack:Sprite = new Sprite();
	private var timeLineButton:SimpleButton;
	
	private var timeLineTxt:TextField = new TextField();
	private var textFormat:TextFormat = new TextFormat();
		
	private var soundBack:Sprite = new Sprite();
	private var soundArrow:Sprite = new Sprite();
	private var soundArrowBack:Shape = new Shape();
	private var soundVolumeButton:SimpleButton;
	
	
	public function VideoControlBar(path:String, vidWidth:uint = 480, vidHeight:uint = 320, controlColor:uint = 0x00C070, fadeDelay:uint = 3000, startSoundVolume:Number = 0.5)
	{
		var nc:NetConnection = new NetConnection();
		nc.connect(null);
		ns = new NetStream(nc);
		
		if(startSoundVolume < 0)
			startSoundVolume = 0;
		if(startSoundVolume > 1)
			startSoundVolume = 1;
			
		currentSoundVolume = startSoundVolume;
		nsst.volume = currentSoundVolume;
		ns.soundTransform = nsst;
		
		var vidInfo:Object = new Object();
		nc.connect(null);
		ns.client = vidInfo;
		ns.client.onMetaData = onMyMetaData;
		vid.attachNetStream(ns);
		vid.height = vidHeight;
		vid.width = vidWidth;
		addChild(vid);

		totalWidth = vid.width;
		timeBarWidth = totalWidth - 200;
		
		ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
		ns.play(path);
		

		
		actionColor = controlColor;
		backTimer = new Timer(fadeDelay,1);
		drawControlBar(vid);
		
		///LISTENER
		this.addEventListener(MouseEvent.MOUSE_MOVE,fadeInBack);
		back.addEventListener(MouseEvent.MOUSE_OVER,stayBack);
		back.addEventListener(MouseEvent.MOUSE_OUT,getBack);

	}
	
	public function onMyMetaData(infoObject:Object):void
	{
		totalVideoLength = infoObject.duration;
	}

	private function asyncErrorHandler(event:AsyncErrorEvent):void
	{
		// Ignore errors
	}

	private function drawControlBar(vid:Video):void
	{
		///PANEL BACKGROUND

		back.graphics.beginFill(0x252525);
		back.graphics.drawRect(0,0,totalWidth,40);
		back.graphics.endFill();
		back.y = vid.height;
		back.alpha = 0.7;
		this.addChild(back);
		
		///////////////////////
		/////  Buttons	///////
		///////////////////////
		var bevel:BevelFilter = new BevelFilter(0.5);
		var glow:GlowFilter = new GlowFilter(actionColor);

		var normalButton:Array = [bevel];
		var glowingButton:Array = [bevel,glow];
		///TogglePause
		playBack.graphics.beginFill(backColor);
		playBack.graphics.drawRoundRect(0,0,22,22,10);
		playBack.graphics.endFill();
		playBack.filters = [bevel];

		pauseBack.graphics.beginFill(backColor);
		pauseBack.graphics.drawRoundRect(0,0,22,22,10);
		pauseBack.graphics.endFill();
		pauseBack.filters = [bevel];
		
		
		var playSymbol:Shape = new Shape();
		playSymbol.graphics.beginFill(actionColor);
		playSymbol.graphics.moveTo(0,5);
		playSymbol.graphics.lineTo(0,-5);
		playSymbol.graphics.lineTo(10,0);
		playSymbol.graphics.endFill();
		playSymbol.x = 6;
		playSymbol.y = 11;
		
		playBack.addChild(playSymbol);

		var pauseSymbol:Shape = new Shape();
		pauseSymbol.graphics.beginFill(actionColor);
		pauseSymbol.graphics.drawRect(0,0,4,10);
		pauseSymbol.graphics.drawRect(6,0,4,10);
		pauseSymbol.graphics.endFill();
		pauseSymbol.x = 6;
		pauseSymbol.y = 6;
		
		pauseBack.addChild(pauseSymbol);

		pauseButton = new SimpleButton(pauseBack,pauseBack,pauseBack,pauseBack);
		
		pauseButton.x = 8;
		pauseButton.y = 10;
		back.addChild(pauseButton);
		
		pauseButton.addEventListener(MouseEvent.CLICK,togglePause);
		
		///STOP
		
		var stopBack:Sprite = new Sprite();
		stopBack.graphics.beginFill(backColor);
		stopBack.graphics.drawRoundRect(0,0,22,22,10);
		stopBack.graphics.endFill();
		stopBack.filters = [bevel];
		
		var stopSymbol:Shape = new Shape();
		stopSymbol.graphics.beginFill(actionColor);
		stopSymbol.graphics.drawRect(0,0,10,10);
		stopSymbol.graphics.endFill();
		stopSymbol.x = 6;
		stopSymbol.y = 6;
		
		stopBack.addChild(stopSymbol);

		var stopButton:SimpleButton = new SimpleButton(stopBack,stopBack,stopBack,stopBack);
		stopButton.x = 35;
		stopButton.y = 10;
		back.addChild(stopButton);
		
		stopButton.addEventListener(MouseEvent.CLICK,stopVideo);

		
		////TEXTFIELD
		
		timeLineTxt.x = timeBarStart + timeBarWidth + 5;
		timeLineTxt.y = 12;
		timeLineTxt.height = 30;
		timeLineTxt.width = textWidth;
		timeLineTxt.wordWrap = true;
		
		textFormat.color = 0xAAAAAA;
		textFormat.font = "Arial";
		textFormat.size = 11;
		
		
		back.addChild(timeLineTxt);
		
		timeLineTxt.addEventListener(Event.ENTER_FRAME,updateText);
		
		///TIMEBAR
		
		timeBarBack.graphics.beginFill(0x444444);
		timeBarBack.graphics.drawRect(0,0,timeBarWidth,10);
		timeBarBack.graphics.endFill();
		
		///TIMEPROGRESS
		timeProgress.graphics.beginFill(actionColor);
		timeProgress.graphics.drawRect(0,0,1,10);
		timeProgress.graphics.endFill();
		timeBarBack.addChild(timeProgress);
		
		timeLineButton = new SimpleButton(timeBarBack,timeBarBack,timeBarBack,timeBarBack);
		timeLineButton.x = timeBarStart;
		timeLineButton.y = 16;
		back.addChild(timeLineButton);
		
		timeLineButton.addEventListener(MouseEvent.CLICK,setNewPlayHead);
		
		///SOUND VOLUME
		soundBack.graphics.beginFill(0x000000,0);
		soundBack.graphics.drawRect(0,0,40,20);
		soundBack.graphics.endFill();
		
		var soundSymbol:Shape = new Shape();
		soundSymbol.graphics.beginFill(backColor);
		soundSymbol.graphics.moveTo(2,3);
		soundSymbol.graphics.lineTo(4,3);
		soundSymbol.graphics.lineTo(9,0);
		soundSymbol.graphics.lineTo(9,11);
		soundSymbol.graphics.lineTo(4,8);
		soundSymbol.graphics.lineTo(2,8);
		soundSymbol.graphics.endFill();
		soundSymbol.filters = [bevel];
		soundBack.addChild(soundSymbol);
		
		soundArrowBack.graphics.beginFill(0x444444);
		soundArrowBack.graphics.moveTo(0,20);
		soundArrowBack.graphics.lineTo(40,20);
		soundArrowBack.graphics.lineTo(40,0);
		soundArrowBack.graphics.endFill();
		soundBack.addChild(soundArrowBack);
		
		soundVolumeButton = new SimpleButton(soundBack,soundBack,soundBack,soundBack);
	
		soundVolumeButton.x = timeBarStart + timeBarWidth + textWidth;
		soundVolumeButton.y = 10;
		back.addChild(soundVolumeButton);
		soundVolumeButton.addEventListener(MouseEvent.MOUSE_DOWN, showXPosition);
                soundBack.addChild(soundArrow);
		updateSoundGraph(currentSoundVolume);
	}

	private function getBack(event:MouseEvent):void
	{
		standingStill = false;
		backTimer.start();
	}

	private function stayBack(event:MouseEvent):void
	{
		back.y = vid.height -40;
		standingStill = true;
	}

	private function fadeInBack(event:MouseEvent):void
	{
		back.addEventListener(Event.ENTER_FRAME,fadeMeIn);
		onMyWayDown = false;
		onMyWayUp = true;
	}
	
	private function fadeMeOut(event:Event):void
	{
		if(onMyWayDown && !standingStill)
		{
			if(back.y <= vid.height && onMyWayUp == false)
			{
				back.y += 5;
				onMyWayDown = true;
			}
			else
			{
				onMyWayDown = false;
				back.removeEventListener(Event.ENTER_FRAME,fadeMeOut);
			}
		}
	}

	private function fadeMeIn(event:Event):void
	{
		if(onMyWayUp)
		{
			if(back.y >= (vid.height -35) && onMyWayDown == false)
			{
				back.y -= 5;
			}
	
			else
			{
				onMyWayUp = false;
				backTimer.start();
				backTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerComplete);
				back.removeEventListener(Event.ENTER_FRAME,fadeMeIn);
			}
		}

	}
	
	private function onTimerComplete(event:TimerEvent):void
	{
		back.addEventListener(Event.ENTER_FRAME,fadeMeOut);
		backTimer.stop();
		onMyWayDown = true;

	}
	
	private function togglePause(event:MouseEvent):void
	{
		ns.togglePause();
		buttonPause = !buttonPause;
		
		if(buttonPause)
		{
			pauseButton.upState = playBack;
			pauseButton.overState = playBack;
			pauseButton.downState = playBack;
			pauseButton.hitTestState = playBack;
			
		}
		else
		{
			pauseButton.upState = pauseBack;
			pauseButton.overState = pauseBack;
			pauseButton.downState = pauseBack;
			pauseButton.hitTestState = pauseBack;
		}
	}
	
	private function stopVideo(event:MouseEvent):void
	{
		ns.pause();
		ns.seek(0);
		buttonPause = true;
		pauseButton.upState = playBack;
		pauseButton.overState = playBack;
		pauseButton.downState = playBack;
		pauseButton.hitTestState = playBack;
	}
	
	private function updateText(event:Event):void
	{
	
		timeLineTxt.text = timeTransform(ns.time)+" / "+timeTransform(totalVideoLength);
		timeLineTxt.setTextFormat(textFormat);
	
		///TimeProgressBar
		var maxVal:uint = timeBarWidth;
		var step:uint = uint(timeBarWidth*(ns.time/totalVideoLength));
		timeProgress.width = step;
	}
	
	private function timeTransform(time:Number):String
	{
		var min:uint = Math.floor(int(Math.floor(time)/60));
		var sec:uint = int(Math.floor(time)%60);
		var secString:String;
		var minString:String;
		
		if(sec < 10)
			secString = "0"+String(sec);
		else
			secString = String(sec);
		
		minString = String(min);
			
		var res:String = minString+":"+secString;
		return res;
			
	}

	private function setNewPlayHead(event:MouseEvent):void
	{
		var xPos:uint = event.currentTarget.mouseX;
		var newPlayPos:Number = (xPos/timeBarWidth)*totalVideoLength;
		ns.seek(newPlayPos);
	
	}
	
	private function showXPosition(event:MouseEvent):void
	{
		currentSoundVolume = event.target.mouseX/40;
		nsst.volume = currentSoundVolume;
		ns.soundTransform = nsst;
		updateSoundGraph(currentSoundVolume);
	}
	
	private function updateSoundGraph(vol:Number):void
	{
		soundArrow.graphics.clear();
	
		soundArrow.graphics.beginFill(actionColor);
		soundArrow.graphics.moveTo(0,20);
		soundArrow.graphics.lineTo(vol*40,20);
		soundArrow.graphics.lineTo(vol*40,20-vol*20);
		soundArrow.graphics.endFill();
		
	}


	
} //END CLASS	
} //END PACKAGE

 

 

© 2012 G. Wendt



Write a comment
Name: Note: Your email address will not be displayed on this site nor otherwise published!
Email:
Comment:
Anti-Spam:
Color & Font
Color tool

You have difficulties finding a balanced color combination and appropriate font formats for your website?


Use the tool Color & Font on this website in order to interactively create the color and font properties of your own site. The results of your settings can be easily included as CSS listing in your web project.

Archive
MTWTFSS
123456
78910111213
14151617181920
21222324252627
282930