RSS

Expanding the Flash Actionscript 3.0 Videoplayer

Thu, Aug 14, 2008

Audio & Video, Flash, Interfaces, Tutorials, XML

Expanding the Flash Actionscript 3.0 Videoplayer

Alright, here’s the second part of the video player tutorial. We will be adding the following new features:
- Playlist support
- Fullscreen support
- Save volume
- Clickable progress/volume bar

You can preview the final result of this tutorial here.

Requirements

Adobe Flash CS3

Try / Buy

Source Files

Download

We also wanted to create a box displaying a message when the video is still buffering. But there has been an issue with the NetStreamEvent. It doesn’t fire the NetStream.Buffer.Empty event when the player’s actually buffering. People from the community say that this problem is somehow related with the encoding software of the flash video files. Since we didn’t find a proper solution, we left this feature out. If someone has an idea how this problem can still be properly solved, feel free to leave us a comment.

Playlist support

Ok, let’s begin with the major new feature. Adding the playlist support is quite simple and nearly implemented the same way as in the slideshow tutorial. So we have our XML file which looks like this:

<playlist>
	<vid src="video/hancock.flv" desc="Hancock (2008) - Movie Trailer"/>
	<vid src="video/redbelt.flv" desc="Redbelt (2008) - Movie Trailer"/>
	<vid src="video/the_dark_knight.flv" desc="The Dark Knight (2008) - Movie Trailer"/>
</playlist>

As you can see, each video has two attributes. One describes the source to the file and the other one is a short description or the title of the movie.
Now it’s time to go on with coding. We changed the line which defines the source of the flash video file to the following:

var strSource:String = root.loaderInfo.parameters.playlist == null ? "playlist.xml" : root.loaderInfo.parameters.playlist;

Like this, flash will look for the flash variable playlist which you can add in the html file. If it’s defined, then the value will be assigned to the variable strSource. Otherwise we just assign a default location. Like this, you can use one compiled SWF file for every playlist you want to publish.
In order to load this file, we need to add three more variables to our video player:

var urlLoader:URLLoader;
var urlRequest:URLRequest;
var xmlPlaylist:XML;

urlLoader will later be used to load and handle the loaded xml file. urlRequest is an object for the urlLoader to load the playlist file. And xmlPlaylist will then contain the loaded xml data from the urlLoader.

We’ve added these code lines add the bottom to the initVideoPlayer() function:

	urlRequest = new URLRequest(strSource);
	urlLoader = new URLLoader();
	urlLoader.addEventListener(Event.COMPLETE, playlistLoaded);
	urlLoader.load(urlRequest);

A new urlRequest will be created with the source location of the xml file. Then we create a new urlLoader, add an event listener when the loading is completed and finally load the file. What’s also important is that we hide the controls of the video player in the first line of the initVideoPlayer() function since we don’t want that the user can click anything if the playlist hasn’t been loaded yet.
As soon as the playlist is loaded we call the playlistLoaded() function which looks like this:

function playlistLoaded(e:Event):void {
	xmlPlaylist = new XML(urlLoader.data);
	playVid(0, false)
	mcVideoControls.visible = true;
}

We assign the received data from the loader to the xml object, set the first video source but not play the video and show the video controls since we’ve loaded all the stuff.

Now we need a back and forward button. We add two event listeners for the buttons in the initVideoPlayer() function:

	mcVideoControls.btnNext.addEventListener(MouseEvent.CLICK, playNext);
	mcVideoControls.btnPrevious.addEventListener(MouseEvent.CLICK, playPrevious);

Then we define a new variable that saves the current number:

var intActiveVid:int;

Now let’s take a closer look at the playVid() function

function playVid(intVid:int = 0, bolPlay = true):void {
	if(bolPlay) {
		tmrDisplay.stop();
		nsStream.play(String(xmlPlaylist..vid[intVid].@src));
		mcVideoControls.btnPause.visible	= true;
		mcVideoControls.btnPlay.visible		= false;
	} else {
		strSource = xmlPlaylist..vid[intVid].@src;
	}

	vidDisplay.visible					= true;

	mcVideoControls.mcVideoDescription.lblDescription.x = 0;
	mcVideoControls.mcVideoDescription.lblDescription.htmlText = (intVid + 1) + ". " + String(xmlPlaylist..vid[intVid].@desc) + "";

	intActiveVid = intVid;
}

As you can see, it now needs to have a video number and a boolean value if the video should be played or just be set to the strSource variable. The function also sets the new description label of the requested video with the value from the xml object and positions it to zero on the x-axis. And finally the intVid value gets assigned to the variable intActiveVid.
The playNext() and playPrevious() function are now ease to implement. We just check if there there is still a video left we can skip or rewind and call the playVid function with the parameter intActiveVid + 1 or intActiveVid – 1 depending on the direction:

function playNext(e:MouseEvent = null):void {
	if(intActiveVid + 1 < xmlPlaylist..vid.length())
		playVid(intActiveVid + 1);

}

function playPrevious(e:MouseEvent = null):void {
	if(intActiveVid - 1 >= 0)
		playVid(intActiveVid - 1);
}

When a video reached it’s end, we stoped the player. But now we want to play the next video in the playlist if there’s still one left, if not, ok then we stop the player ;) So we change this in the netStatusHandler() function:

	if(intActiveVid + 1 < xmlPlaylist..vid.length())
		playNext();
	else
		stopVideoPlayer();

Now there’s only the vertical scrolling of the video description label left for the playlist feature. It could be that you need an extra long title for your video. In that case, we’ve just created a very long one lined textfield that’s masked. On top of that is an invisible button that will be used to know, if the user moves the mouse over the label so we can scroll it if it’s to long. In order to know if we’re currently scrolling the label and to know in which direction the scrolling is going, we need to set two new variables:

var bolDescriptionHover:Boolean = false;
var bolDescriptionHoverForward:Boolean = true;

Now we need to add an event listener on the invisible button:

	mcVideoControls.mcVideoDescription.btnDescription.addEventListener(MouseEvent.MOUSE_OVER, startDescriptionScroll);
	mcVideoControls.mcVideoDescription.btnDescription.addEventListener(MouseEvent.MOUSE_OUT, stopDescriptionScroll);

The functions startDescriptionScroll() and stopDescriptionScroll() are simply setting the bolDescriptionHover variable to true or false depending on the mouse event. startDescriptionScroll() additionally checks, if it’s even necessary to scroll the text:

function startDescriptionScroll(e:MouseEvent):void {
	if(mcVideoControls.mcVideoDescription.lblDescription.textWidth > 138)
		bolDescriptionHover = true;
}

function stopDescriptionScroll(e:MouseEvent):void {
	bolDescriptionHover = false;
}

To actually move the label we just add some new lines of code to the updateDisplay() function which is called by the timer object:

	if(bolDescriptionHover) {
		if(bolDescriptionHoverForward) {
			mcVideoControls.mcVideoDescription.lblDescription.x -= 0.1;
			if(mcVideoControls.mcVideoDescription.lblDescription.textWidth - 133 <= Math.abs(mcVideoControls.mcVideoDescription.lblDescription.x))
				bolDescriptionHoverForward = false;
		} else {
			mcVideoControls.mcVideoDescription.lblDescription.x += 0.1;
			if(mcVideoControls.mcVideoDescription.lblDescription.x >= 0)
				bolDescriptionHoverForward = true;
		}
	} else {
		mcVideoControls.mcVideoDescription.lblDescription.x = 0;
		bolDescriptionHoverForward = true;
	}

First, we check if we’re currently over the label. The we figure out, which way we move the text. Since the updateDisplay() function is called pretty often, we get a smooth motion by incrementing and decrementing the label’s x value just by 0.1. So, when moving forward, we actualy move the label to the left and check, if we’ve reached the end. If so, we invert the bolDescriptionForward value and begin to move the field to the right until it reached zero on the x-axis. If the user’s no hovering over the invisible button, we just reset the position of the label and the direction flag.

Fullscreen support

Since flash player version 9,0,28,0 you can use the fullscreen feature. In order to get this to work, you also need to set this in the HTML code. But since Flash does all the HTML stuff for you, you only need to change the mode to allowFullscreen in the publish settings of HTML

The implementing of the fullscreen support is rather simple in our case because we don’t have too much stuff on the stage we need to reposition/resize once we hit the fullscreen mode. So, first of all, we set the scale mode of the stage to no scale because we want to resize the object individualy and not everything. We also set the stage align mode to the top left corner:

stage.scaleMode	= StageScaleMode.NO_SCALE;
stage.align		= StageAlign.TOP_LEFT;

Then we add two event listeners for the fullscreen button. One to enter it and one for leaving the full screen mode. We also add an event listener when the fullscreen mode changes. The visibility of the btnFullscreenOff button will be set to false. We do all of this in the initVideoPlayer() function:

	mcVideoControls.btnFullscreenOn.addEventListener(MouseEvent.CLICK, fullscreenOnClicked);
	mcVideoControls.btnFullscreenOff.addEventListener(MouseEvent.CLICK, fullscreenOffClicked);
	stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreen);
	mcVideoControls.btnFullscreenOff.visible = false;

To actualy enter and leave the fullscreen mode, all you need to do is to set the display state of the stage to the wanted mode. That’s what we’re doing when the user clicks the fullscreen buttons:

function fullscreenOnClicked(e:MouseEvent):void {
	stage.displayState = StageDisplayState.FULL_SCREEN;
}

function fullscreenOffClicked(e:MouseEvent):void {
	stage.displayState = StageDisplayState.NORMAL;
}

Now we only need to define the resizing action in the onFullScreen() function:
function onFullscreen(e:FullScreenEvent):void {

    if (e.fullScreen) {
        mcVideoControls.btnFullscreenOn.visible = false;
		mcVideoControls.btnFullscreenOff.visible = true;

		mcVideoControls.x = (Capabilities.screenResolutionX - 440) / 2;
		mcVideoControls.y = (Capabilities.screenResolutionY - 33);

		vidDisplay.height = (Capabilities.screenResolutionY - 33);
		vidDisplay.width = vidDisplay.height * 4 / 3;
		vidDisplay.x	= (Capabilities.screenResolutionX - vidDisplay.width) / 2;
    } else {
        mcVideoControls.btnFullscreenOn.visible = true;
		mcVideoControls.btnFullscreenOff.visible = false;
		mcVideoControls.x = 0;
		mcVideoControls.y = 330;
		vidDisplay.y = 0;
		vidDisplay.x = 0;
		vidDisplay.width = 440;
		vidDisplay.height = 330;
    }
}

So, first we check if we’re entering the fullscreen mode. If so, we switch the fullscreen buttons, align the control bar in the bottom center of the screen and size up the video display and center it on to the screen. If we’re leaving the fullscreen mode, what you can also do by pressing the ESC key on your keyboard, we reset all the stuff to how it was before.
That’s was already everything for the fullscreen support :)

Save volume

This is quite an important feature and really ease to implement in flash. To save the last used volume you can use the flash cookies which will be stored on the computer of the user. They are like normal browser cookies, but can only accessed through flash. So, the first thing we need to do is creating a new shared object:

var shoVideoPlayerSettings:SharedObject = SharedObject.getLocal("playerSettings");

The function getLocal returns the shared object you’ve requested. In our case we want to have the playerSettings cookie/shared object. Since we want to set the volume on the start, we add the following line to the initVideoPlayer() function:

	var tmpVolume:Number = DEFAULT_VOLUME;
	if(shoVideoPlayerSettings.data.playerVolume != undefined) {
		tmpVolume = shoVideoPlayerSettings.data.playerVolume;
		intLastVolume = tmpVolume;
	}

	mcVideoControls.mcVolumeScrubber.x = (53 * tmpVolume) + 318;
	mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 371 + 53;
	setVolume(tmpVolume);

First we assign the DEFAULT_VOLUME to a temporary variable. Then we check if the user has already a cookie with the player volume. If so, we override the value from the variable. Then we update the volume bar and set the volume with the setVolume() function. In order to store the new volume in the cookie, we add the following two new lines to the setVolume() function:

	shoVideoPlayerSettings.data.playerVolume = intVolume;
	shoVideoPlayerSettings.flush();

The function flush() writes the new value immediately in the flash cookie.

Clickable progress/volume bar

This is just a beauty hack for the player. We want to be able to click on the progress or the volume bar to begin with the scrubbing. So, we just added two invisible buttons on the off the bars and added the function to it as when you click the scrub buttons directly:

	mcVideoControls.mcVolumeScrubber.btnVolumeScrubber.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
	mcVideoControls.mcProgressScrubber.btnProgressScrubber.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);

And what’s also changed is, that we now lock the center in the startDrag() function. Like this the scrubber will move to where you clicked on the bars:

function volumeScrubberClicked(e:MouseEvent):void {
	bolVolumeScrub = true;

	mcVideoControls.mcVolumeScrubber.startDrag(true, new Rectangle(318, 19, 53, 0));
}

function progressScrubberClicked(e:MouseEvent):void {
	bolProgressScrub = true;

	mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, 2, 432, 0));
}

We’ve already reached the end of the second part of the video player tutorial. We hope that you enjoyed reading it and we appreciate every kind of feedback.

Full code with comments

// ###############################
// ############# 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 user hovers over description label
var bolDescriptionHover:Boolean = false;
// flag for knowing in which direction the description label is currently moving
var bolDescriptionHoverForward:Boolean = true;
// 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 number of the active video
var intActiveVid:int;
// 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;
// shared object holding the player settings (currently only the volume)
var shoVideoPlayerSettings:SharedObject = SharedObject.getLocal("playerSettings");
// url to flv file
var strSource:String					= root.loaderInfo.parameters.playlist == null ? "playlist.xml" : root.loaderInfo.parameters.playlist;
// timer for updating player (progress, volume...)
var tmrDisplay:Timer;
// loads the xml file
var urlLoader:URLLoader;
// holds the request for the loader
var urlRequest:URLRequest;
// playlist xml
var xmlPlaylist:XML;

// ###############################
// ############# STAGE SETTINGS
// ###############################
stage.scaleMode	= StageScaleMode.NO_SCALE;
stage.align		= StageAlign.TOP_LEFT;

// ###############################
// ############# FUNCTIONS
// ###############################

// sets up the player
function initVideoPlayer():void {
	// hide video controls on initialisation
	mcVideoControls.visible = false;

	// hide buttons
	mcVideoControls.btnUnmute.visible			= false;
	mcVideoControls.btnPause.visible			= false;
	mcVideoControls.btnFullscreenOff.visible	= false;

	// set the progress/preload fill width to 1
	mcVideoControls.mcProgressFill.mcFillRed.width	= 1;
	mcVideoControls.mcProgressFill.mcFillGrey.width	= 1;

	// set time and duration label
	mcVideoControls.lblTimeDuration.htmlText		= "00:00 / 00:00";

	// add global event listener when mouse is released
	stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);

	// add fullscreen listener
	stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullscreen);

	// add event listeners to all buttons
	mcVideoControls.btnPause.addEventListener(MouseEvent.CLICK, pauseClicked);
	mcVideoControls.btnPlay.addEventListener(MouseEvent.CLICK, playClicked);
	mcVideoControls.btnStop.addEventListener(MouseEvent.CLICK, stopClicked);
	mcVideoControls.btnNext.addEventListener(MouseEvent.CLICK, playNext);
	mcVideoControls.btnPrevious.addEventListener(MouseEvent.CLICK, playPrevious);
	mcVideoControls.btnMute.addEventListener(MouseEvent.CLICK, muteClicked);
	mcVideoControls.btnUnmute.addEventListener(MouseEvent.CLICK, unmuteClicked);
	mcVideoControls.btnFullscreenOn.addEventListener(MouseEvent.CLICK, fullscreenOnClicked);
	mcVideoControls.btnFullscreenOff.addEventListener(MouseEvent.CLICK, fullscreenOffClicked);

	mcVideoControls.btnVolumeBar.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
	mcVideoControls.mcVolumeScrubber.btnVolumeScrubber.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
	mcVideoControls.btnProgressBar.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);
	mcVideoControls.mcProgressScrubber.btnProgressScrubber.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);

	mcVideoControls.mcVideoDescription.btnDescription.addEventListener(MouseEvent.MOUSE_OVER, startDescriptionScroll);
	mcVideoControls.mcVideoDescription.btnDescription.addEventListener(MouseEvent.MOUSE_OUT, stopDescriptionScroll);

	// 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.connect(null);

	// create a new netstream with the net connection, add event
	// listener, set client to this for handling meta data and
	// set the buffer time to the value from the constant
	nsStream = new NetStream(ncConnection);
	nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
	nsStream.client = this;
	nsStream.bufferTime = BUFFER_TIME;

	// attach net stream to video object on the stage
	vidDisplay.attachNetStream(nsStream);
	// set the smoothing value from the constant
	vidDisplay.smoothing = SMOOTHING;

	// set default volume and get volume from shared object if available
	var tmpVolume:Number = DEFAULT_VOLUME;
	if(shoVideoPlayerSettings.data.playerVolume != undefined) {
		tmpVolume = shoVideoPlayerSettings.data.playerVolume;
		intLastVolume = tmpVolume;
	}
	// update volume bar and set volume
	mcVideoControls.mcVolumeScrubber.x = (53 * tmpVolume) + 318;
	mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 371 + 53;
	setVolume(tmpVolume);

	// create new request for loading the playlist xml, add an event listener
	// and load it
	urlRequest = new URLRequest(strSource);
	urlLoader = new URLLoader();
	urlLoader.addEventListener(Event.COMPLETE, playlistLoaded);
	urlLoader.load(urlRequest);
}
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.play(strSource);
		bolLoaded = true;
	}
	else{
		nsStream.resume();
	}

	vidDisplay.visible = true;

	// switch play/pause visibility
	mcVideoControls.btnPause.visible	= true;
	mcVideoControls.btnPlay.visible		= false;
}

function pauseClicked(e:MouseEvent):void {
	// pause video
	nsStream.pause();

	// switch play/pause visibility
	mcVideoControls.btnPause.visible	= false;
	mcVideoControls.btnPlay.visible		= true;
}

function stopClicked(e:MouseEvent):void {
	// calls stop function
	stopVideoPlayer();
}

function muteClicked(e:MouseEvent):void {
	// set volume to 0
	setVolume(0);

	// update scrubber and fill position/width
	mcVideoControls.mcVolumeScrubber.x				= 318;
	mcVideoControls.mcVolumeFill.mcFillRed.width	= 1;
}

function unmuteClicked(e:MouseEvent):void {
	// set volume to last used value or DEFAULT_VOLUME if last volume is zero
	var tmpVolume:Number = intLastVolume == 0 ? DEFAULT_VOLUME : intLastVolume
	setVolume(tmpVolume);

	// update scrubber and fill position/width
	mcVideoControls.mcVolumeScrubber.x = (53 * tmpVolume) + 318;
	mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 371 + 53;
}

function volumeScrubberClicked(e:MouseEvent):void {
	// set volume scrub flag to true
	bolVolumeScrub = true;

	// start drag
	mcVideoControls.mcVolumeScrubber.startDrag(true, new Rectangle(318, 19, 53, 0)); // NOW TRUE
}

function progressScrubberClicked(e:MouseEvent):void {
	// set progress scrub flag to true
	bolProgressScrub = true;

	// start drag
	mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, 2, 432, 0)); // NOW TRUE
}

function mouseReleased(e:MouseEvent):void {
	// set progress/volume scrub to false
	bolVolumeScrub		= false;
	bolProgressScrub	= false;

	// stop all dragging actions
	mcVideoControls.mcProgressScrubber.stopDrag();
	mcVideoControls.mcVolumeScrubber.stopDrag();

	// update progress/volume fill
	mcVideoControls.mcProgressFill.mcFillRed.width	= mcVideoControls.mcProgressScrubber.x + 5;
	mcVideoControls.mcVolumeFill.mcFillRed.width	= mcVideoControls.mcVolumeScrubber.x - 371 + 53;

	// save the volume if it's greater than zero
	if((mcVideoControls.mcVolumeScrubber.x - 318) / 53 > 0)
		intLastVolume = (mcVideoControls.mcVolumeScrubber.x - 318) / 53;
}

function updateDisplay(e: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(mcVideoControls.mcProgressScrubber.x * objInfo.duration / 432))
	else
		mcVideoControls.mcProgressScrubber.x = nsStream.time * 432 / objInfo.duration; 

	// set time and duration label
	mcVideoControls.lblTimeDuration.htmlText		= "" + formatTime(nsStream.time) + " / " + formatTime(objInfo.duration);

	// update the width from the progress bar. the grey one displays
	// the loading progress
	mcVideoControls.mcProgressFill.mcFillRed.width	= mcVideoControls.mcProgressScrubber.x + 5;
	mcVideoControls.mcProgressFill.mcFillGrey.width	= nsStream.bytesLoaded * 438 / nsStream.bytesTotal;

	// update volume and the red fill width when user is scrubbing
	if(bolVolumeScrub) {
		setVolume((mcVideoControls.mcVolumeScrubber.x - 318) / 53);
		mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 371 + 53;
	}

	// chech if user is currently hovering over description label
	if(bolDescriptionHover) {
		// check in which direction we're currently moving
		if(bolDescriptionHoverForward) {
			// move to the left and check if we've shown everthing
			mcVideoControls.mcVideoDescription.lblDescription.x -= 0.1;
			if(mcVideoControls.mcVideoDescription.lblDescription.textWidth - 133 <= Math.abs(mcVideoControls.mcVideoDescription.lblDescription.x))
				bolDescriptionHoverForward = false;
		} else {
			// move to the right and check if we're back to normal
			mcVideoControls.mcVideoDescription.lblDescription.x += 0.1;
			if(mcVideoControls.mcVideoDescription.lblDescription.x >= 0)
				bolDescriptionHoverForward = true;
		}
	} else {
		// reset label position and direction variable
		mcVideoControls.mcVideoDescription.lblDescription.x = 0;
		bolDescriptionHoverForward = true;
	}
}

function onMetaData(info:Object):void {
	// stores meta data in a object
	objInfo = info;

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

function netStatusHandler(event:NetStatusEvent):void {
	// handles net status events
	switch (event.info.code) {
		// 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 check if there are
		// more video left or stop the player
		case "NetStream.Play.Stop":
			if(intActiveVid + 1 < xmlPlaylist..vid.length())
				playNext();
			else
				stopVideoPlayer();
		break;
	}
}

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
	mcVideoControls.btnPause.visible	= false;
	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) {
		mcVideoControls.btnMute.visible		= true;
		mcVideoControls.btnUnmute.visible	= false;
	} else {
		mcVideoControls.btnMute.visible		= false;
		mcVideoControls.btnUnmute.visible	= true;
	}

	// store the volume in the flash cookie
	shoVideoPlayerSettings.data.playerVolume = intVolume;
	shoVideoPlayerSettings.flush();
}

function formatTime(t:int):String {
	// returns the minutes and seconds with leading zeros
	// for example: 70 returns 01:10
	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";
	}
}

function fullscreenOnClicked(e:MouseEvent):void {
	// go to fullscreen mode
	stage.displayState = StageDisplayState.FULL_SCREEN;
}

function fullscreenOffClicked(e:MouseEvent):void {
	// go to back to normal mode
	stage.displayState = StageDisplayState.NORMAL;
}

function onFullscreen(e:FullScreenEvent):void {
	// check if we're entering or leaving fullscreen mode
    if (e.fullScreen) {
		// switch fullscreen buttons
        mcVideoControls.btnFullscreenOn.visible = false;
		mcVideoControls.btnFullscreenOff.visible = true;

		// bottom center align controls
		mcVideoControls.x = (Capabilities.screenResolutionX - 440) / 2;
		mcVideoControls.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
        mcVideoControls.btnFullscreenOn.visible = true;
		mcVideoControls.btnFullscreenOff.visible = false;

		// reset controls position
		mcVideoControls.x = 0;
		mcVideoControls.y = 330;

		// reset video display
		vidDisplay.y = 0;
		vidDisplay.x = 0;
		vidDisplay.width = 440;
		vidDisplay.height = 330;
    }
}

function playlistLoaded(e:Event):void {
	// create new xml with loaded data from loader
	xmlPlaylist = new XML(urlLoader.data);

	// set source of the first video but don't play it
	playVid(0, false)

	// show controls
	mcVideoControls.visible = true;
}

function playVid(intVid:int = 0, bolPlay = true):void {
	if(bolPlay) {
		// stop timer
		tmrDisplay.stop();

		// play requested video
		nsStream.play(String(xmlPlaylist..vid[intVid].@src));

		// switch button visibility
		mcVideoControls.btnPause.visible	= true;
		mcVideoControls.btnPlay.visible		= false;
	} else {
		strSource = xmlPlaylist..vid[intVid].@src;
	}

	// show video display
	vidDisplay.visible					= true;

	// reset description label position and assign new description
	mcVideoControls.mcVideoDescription.lblDescription.x = 0;
	mcVideoControls.mcVideoDescription.lblDescription.htmlText = (intVid + 1) + ". " + String(xmlPlaylist..vid[intVid].@desc) + "";

	// update active video number
	intActiveVid = intVid;
}

function playNext(e:MouseEvent = null):void {
	// check if there are video left to play and play them
	if(intActiveVid + 1 < xmlPlaylist..vid.length())
		playVid(intActiveVid + 1);

}

function playPrevious(e:MouseEvent = null):void {
	// check if we're not and the beginning of the playlist and go back
	if(intActiveVid - 1 >= 0)
		playVid(intActiveVid - 1);
}

function startDescriptionScroll(e:MouseEvent):void {
	// check if description label is too long and we need to enable scrolling
	if(mcVideoControls.mcVideoDescription.lblDescription.textWidth > 138)
		bolDescriptionHover = true;
}

function stopDescriptionScroll(e:MouseEvent):void {
	// disable scrolling
	bolDescriptionHover = false;
}

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

 

About the Author


Rafael Nuenlist - who has written 7 posts on Flash Platform and ActionScript Tutorials.

Rafael Nünlist is currently working at orange8 as a Richmedia Developer. He will complete his apprenticeship with a swiss federal vocational diploma in information technology this summer. His strengths are Flash, Flex, Actionscript, Php/MySQL and AIR. He is also a member of the dreaminginflash team.

79 Comments For This Post

  1. Neo Says:

    Nice tutorial!:)

  2. Steve Says:

    Great tutorials! I do have a question about advanced settings for advance/retreat. I will encode with a very small keyframe rate (1 or 2)and I want to use the buttons (and the scrubber) to advance/retreat to the keyframes. Do you have a hack for that? Any suggestions?

    Thanks, Steve

  3. Peter Pistorius Says:

    Great tutorial! Thanks a bunch. I can’t seem to get it to play h.264 files?

  4. Peter Pistorius Says:

    I realised that I need to update my version of Flash CS3 to support h.264.

  5. Kristy Says:

    hmm, tutorial is great, but for some reason even when working with the downladed file and code, the fullscreen does not work.
    Any thoughts?

  6. Peter Pistorius Says:

    @Kristy: you have to modify your flash to export it with the fullscreen=true paramater, it will not work in the “test movie” mode. You have to run it through the browser.

  7. Website Design Says:

    Very nice tutorial, I have a question, is it possible to record the length of time someone has been watching the video, for instance if the video is 5 mins long and they have watched 2 mins of it is it possible to get that information from within the flash file?

    A simple timer wouldn’t work as the timer would continue when the video is buffering.

  8. Tdude Says:

    Hi!
    I really appreciate that you’re sharing this. Is there any way one could make a control slider for the framerate in as3?
    /T

  9. Craig Says:

    This is a great FLV player. I’ve integrated it with my FLA and it works perfectly. Thank you for sharing it.
    I’m an AS3 novice and I’m trying to get the player to stop by using my own button that also gotoandplays another frame on the root movie AND toggles my background MP3 player to ‘on’ again. This button has to reside in the root movieclip so that it can use the document class script for my MP3 player. How can I also add:
    “xbuttonshell_btn.addEventListener(MouseEvent.CLICK, stopClicked);
    addEventListener(“stopVideo”, stopClicked);” and reference the movieclip where the FLV player resides?

  10. Michael Cole Says:

    Nice AS3 player!
    Can it have a script snippet to auto-start. Being a newbie to AS3, I looked through the actionscript and couldn’t find it.

    Thanks,
    Michael

  11. Heather Says:

    Hey Michael! I figured out how to auto start the movie.

    1. find this line(around line 402):
    // set source of the first video but don’t play it
    playVid(0,false) ->change false to true

    2. Then add this to the very last line:

    playClicked(null);

  12. Heather Says:

    Nevermind! It worked when I tested it in flash. Once I uploaded to site, it didn’t work:(.

  13. Chris Says:

    Yes same here, please help me to make it auto start, thanks alot!

  14. Michael D Says:

    Nice tutorial, I have a question, when I change the ncConnection.connect(“null”); to ncConnection.connect(“rtmp://My Web Server”); it doesn’t connect.

    It appears the NetStream is not waiting for the NetConnection to be established when connecting to my FM3 server. Can you help me with this issue.

    Best regards,

    Michael

  15. Michael D. Says:

    Can anyone show me how to connect this videoplayer to a FMS3 server???

    ncConnection.connect(”rtmp://My Web Server”) does not work.

    thanks
    md

  16. sunilkumar Says:

    Hi I am also trying to communicate with rtmp server (“rtmp://localhost/vod/”) file source =”sampe”

    It is not working can you please tell me how can I play rtmp file using this player.

    Thanks & regards

    Sunil kumar

  17. Rob Says:

    To fix it for RTMP you will need to make a lot of edits…

    The usual problem with players is that the netStatusHandler does not wait for “NetConnection.Connect.Success” before making the stream connection and trying the nsStream.play() command.

    This is a garbled and convoluted player that was only meant to work with local http files. Here is an example of some of the things you need to change:

    Find the ncConnection and nsStream block of code and pull them out of the init function…

    Replace the both sections with a call to createConnection();

    Add the following 3 functions below the init function…
    function createConnection():void
    {
    // 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, netConnectionStatusHandler);
    ncConnection.connect(“rtmp://serverName.com/path”, true);
    }

    // This should also be seperated, this will be called from the new netConnectionStatusHandler()

    function createNetStream():void
    {
    // create a new netstream with the net connection, add event
    // listener, set client to this for handling meta data and
    // set the buffer time to the value from the constant
    nsStream = new NetStream(ncConnection);
    nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamStatusHandler);
    nsStream.client = this;
    nsStream.bufferTime = BUFFER_TIME;

    // attach net stream to video object on the stage
    vidDisplay.attachNetStream(nsStream);
    // set the smoothing value from the constant
    vidDisplay.smoothing = SMOOTHING;
    }

    // You absolutely HAVE to watch for NetConnection.Connect.Success before instituting a call to the netStream…
    function netConnectionStatusHandler(event:NetStatusEvent):void {
    if(event.info.code == “NetConnection.Connect.Success”)
    createNetStream();
    }

    This isn’t the only changes needed, but it might run…

    While I wouldn’t recommend using this player for RTMP, you could get it to work with a lot of code changes. I would personally look for something on bigstockflash or flashden…

  18. Quirksmode Says:

    Hi,

    great tutorial! Full of really useful info.

    I have a question, at the moment when you click along the progress bar the scrubber does not move to that location, I find that I have to click and drag a little bit to get it to update. Is there a way to get it to respond to a click?

    Thanks,

    Dave

  19. Quirksmode Says:

    Think I solved my own problem, though its been done very crudely. I added the following line of code. I am not sure why I have to minus 62px, but that seemed to allow it to work properly

    mcVideoControls.progressWrapper.mcProgressScrubber.x = mouseX – 62;

  20. pascal Says:

    Hello, i try
    To fix it for RTMP you will need to make a lot of edits…

    but whan i compile i have

    1120: Accès à la propriété non définie netStreamStatusHandler.

    can you help me please (as3 french newbie)

  21. adam Says:

    one way to display a buffering message is to check when the load bar is the wider (plus or minus a few pixels) than the progress bar.
    I used a conditional in the update timer function

    Thanks a million 4 the tutorial by the way

  22. Gurpreet Says:

    Wonderful! ample thankz for beautiful tutorial!

  23. bob Says:

    interesting demo, i get some good code out of this. but you can do one event listener for the controls container, and then create a switch/case statement to control all the different possibilities. this way you’re not setting 15 event listeners for one container. as3 will spot the individual button being moused over or out of or clicked, even control scrubbers.

    also, if you have the same frame labels for buttons (‘off’, ‘on’), you can just do e.target.gotoAndStop(‘off’) as one function for the whole shebang for MOUSE_OUT calls.

  24. vijayan Says:

    hi,

    if do you have any sample pls send to my mail ID.

    thank you
    vijay

  25. codo Says:

    … even better

  26. Stefano Says:

    I’ve converted the action code in a class TTLVideoPlayer adding a parameter to the contrunctor

    then I instantiate the class via AS3

    var firstPlayer:TTLVideoPlayer;
    firstPlayer = new (“myVideo.flv”);
    addChild(firstPlayer);

    I’ve got a lot of compile errors like
    1120: Access of undefined property mcVideoControls
    starting from
    mcVideoControls.btnUnmute.visible= false;

    obviuosly because all the mc are named and create into the stage.

    What I have to do? Any suggestion?

    Thanks in advance
    Stefano

  27. Younus Says:

    Hi
    its really great tutorial.

    Thanks

  28. Rahul Joshi Says:

    Hi, Nice tutorial…

    I was working on you video player and wanted to add some additional functionalities:

    1. I have modified the XML and added another entry for sponsor video in it. If a particular entry in the XML has a sponsor video, it should be played first, then the video in that tag and so on. I am checking through actionscript if a sponsor video is present, then play it else just the normal video.

    2. I also wanted to add provision for forward and Rewind buttons, so that when a user clicks on them he can go, say 10 seconds ahead…

    Can you please guide me on how I can achieve this successfully?

  29. Rahul Joshi Says:

    Hi, is it possible to play youtube videos in this player?

  30. Amit Says:

    hi
    thank u for sharing the nice tutorial.now i need a flv player….and with the following requirements.

    flash player exactly like youtube or jw player
    must have support of lighttpd support for real time seeking to any position before download
    it should stream immediately where the seek bar position
    lighttpd use for saving bandwitdh from download
    like i have 16 MBPS internet
    and downloading a video of 500 mb video
    so if the video is 50 min my high speed will download it immediately and it will cost my full bandwitdh of 500 mb
    so if i want to close browser after 10 min of watching the video
    its wasting my 40 min video bandwidth unecessaryly
    lighttpd do the trick here
    like it will not let user download full 50 min video immediately doesn;t matter if he has high speed internet
    it will download max 3 min advance video according to user bandwidth speed
    this value also can be set from settings of lighttpd
    for example if any one click pause on the player then player will stop downloading video
    download will be pause too
    in one word player only download maximum buffering time
    so if we set buffering to advance 1 min it will always download maximum 1 min advance from its current possition
    real live example is youtube player

    Advertising feature thakte hobe, high defination video , mp4 should run as well FLV for mat something like youtube.

    What can i do.plz help me.
    Thank u .

  31. Rahul Joshi Says:

    I want to play the sponsor videos in the video player. Each vid tag has another video source which is for sponsor videos. Through AS I check if a sponsor video is present then play it else only play the normal video and so on throughout the playlist.

    Also can I play videos from youtube in this player?

  32. Chuck Says:

    The biggest problem I’m having with a player like this is to be able to load in the correct timed text XML file for each video in the playlist. Does anyone have experience in this?

  33. Erik Says:

    Thanks Rafael,

    I added,
    function PlayNext(e:MouseEvent = null):void {
    // check if there are video left to play and play them
    if(intActiveVid + 1 < xmlPlaylist..vid.length()){
    playVid(intActiveVid + 1);
    } else {
    playVid(0, true):
    }
    }

    Respect your work.

  34. Evans Domina Says:

    this is da sh** like 2 h’s after S…this tut’ is a bomb…am building this AIR Application using flex and had problems with the videoDisplay component..so i guess this helped alot…but do you know how to let he videos play from a tile list…i tried using ListEvent.CHANGE but the video resumes rather done change and play new video from my XML play list..please get to me A.S.A.P

  35. Abhi Says:

    Wow !!!

    Excellent Article.. :)

    Keep posting nice article..

  36. Evans Says:

    i found how to display video using a tilelist and if you want to load sponsor XML.. u might as well consider using the XMLListCollecton class..just create a new XMLListCollection(myXml.Videos.Video.(@category.toLowerCase().indexOf(‘ads’) != -1));..something like this but all the myXml,Videos,Video,@category has to be user defined..Email me for more info

  37. chad Says:

    Anyone know how toget this to do two things?

    1. go full screen without the controls and real full screen, covering all of the screen

    2. autostart

    i have been playing with this for 4 days now and have had no luck with either to work!

    i have tried keyboard events, context menu and nothing works

  38. John Says:

    @Quirksmode

    I know this is really late but I thought I’d put it here for everyone’s reference anyway. Here’s a quick and dirty way of making the progress slider move to the mouse position when you click the progress bar.

    Firstly find this line…

    mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, 2, 432, 0)); // NOW TRUE

    then on the line before it, add the following.

    mcVideoControls.mcProgressScrubber.x = mcVideoControls.mouseX – mcVideoControls.mcProgressScrubber.width/2;

    Hope that helps

  39. John Says:

    chad..

    to autostart find playVid(0, false) and change it to playVid(0, true)

    to go ‘real’ fullscreen whilst keeping 4:3 aspect ratio and hide the controls

    remove out the stuff inside

    if (e.fullScreen) {
    }

    and replace it with

    if (e.fullScreen) {
    mcVideoControls.visible = false;
    vidDisplay.height = (stage.fullScreenHeight);
    vidDisplay.width = vidDisplay.height * 4 / 3;
    }

    then inside the else {} below it, add

    mcVideoControls.visible = true;

  40. John Says:

    One last thing!

    I strongly advise you all use

    stage.fullScreenHeight and stage.fullScreenWidth

    instead of

    Capabilities.screenResolutionY and Capabilities.screenResolutionX

    respectively.

    The Capabilities attributes do not support a multi-screen environment, so they will always return the resolution of your main monitor (which isn’t what you want if your secondary monitor’s res differs from that).

  41. amar Says:

    mcVideoControls.mcProgressScrubber.startDrag(true, new Rectangle(0, 2, 432, 0)); //

    i want mcProgressScrubber small but intial handle position don’t change
    how to chang mcprogressscrubber handle

  42. Emiloly Says:

    This is fantastic however I was wondering how easy it would be to have buttons linking too different xml playlists. Wish I had the brain to figure out how to do it myself however I just can’t seem to get my head around it!

  43. Robert Says:

    This is a great tutorial. I’m learning AS3 and I find it very useful. I do have one question:

    I’m having hard time uderstanding the logic behind this (you use this in the unmuteClicked function)

    var tmpVolume:Number = intLastVolume == 0 ? DEFAULT_VOLUME : intLastVolume
    setVolume(tmpVolume);

    Would it be the same if I write:

    var tmpVolume:Number;
    if(intLastVolume == 0) {
    intLastVolume = DEFAULT_VOLUME;
    } else {
    setVolume(tmpVolume)
    }

  44. Richard McMillen Says:

    This is proving extremely useful for me to learn from and implement. It is so well explained.

    What file types can be used with this plater? is it solely .flv? Or can other file types be used aswell?

  45. margot darby Says:

    Visible buttons for the available choices, or even different playlists, would be nice, since it appears to be a single-play player when you first look at it. Another modification I’d like to see or create myself is an all-code OOP version of this player. (Maybe not all-code: some library items are needed for the pretty controls.) A very attractive item, all in all.

  46. Porter Says:

    Hi there.
    First of all I want to say that this tutorial is great. But I have a question:

    I already read about how to stop a flv at the last frame. What I’m now trying to do is, make the forward-button blink, so the user visually recognizes, that he can go on with the next clip.

    Unfortunattely I don’t know how and where to implement that.
    Thanks for any help.

  47. avi Says:

    hi!!!!!!
    I want to make video player in Flex builder in which I want that all the names should appear in tree form in left panel and videos should play in right panel inside video player.how can i do this in Flex builder3 for desktop applications.Kindly help me ……..

  48. Peter Says:

    Hey, great job! Do you know how to make it show all of the descriptions of the movies in the XML file, so that I can move it to the side of the video for a playlist? Then I will make them load a specific video. Thanks for your help!

  49. sam Says:

    need to display the play list in a tilelist Pls. help

  50. Mike Says:

    Fantastic tutorial and really appreciate you giving this stuff out for free. Love the site and there is a need for more of it.

    I did spot a minor bug in the player though. If you dont play the first video and skip to the second it plays fine but if you unpause or stop that and then play it automatically plays the first video. After much playing around i think i have fixed it (not a programmer so forgive me if this is butchered a little :)

    On the function Playclicked i added one line:

    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.play(strSource);
    bolLoaded = true;
    ——> playVid(intActiveVid); <——
    }
    else{
    nsStream.resume();
    }

    vidDisplay.visible = true;

    // switch play/pause visibility
    mcVideoControls.btnPause.visible = true;
    mcVideoControls.btnPlay.visible = false;
    }

    This seems to fix the problem as its seems to tell the player the first video has played and if you skip to the second and play the bug doesn’t seem to happen.

    Hope this is of some help to people.

  51. matew Says:

    Thanks sir

  52. rookie Says:

    Hi there,

    does anybody know a similar tutorial with a player that plays swf-files instead of flvs. Or is there a way to extend the above code, so it allows to play swf-files? I’m searching the web for days but unfortunattely i can’t find anything. It should have the same functions like this one.

    Greets
    Charlie

  53. rodrigo Says:

    hello how do I make the video play as soon as the application is run?

    thanks

  54. Mike Says:

    Excellent tutorial!

    I just have one question,how can i stop the video from playing when i load another swf.

    I’m building my website with URL Request and when I leave the videoplayer swf the sound from the video continues playing,how can i stop it?

  55. Angela Says:

    Great tutorial! I’ve modified the code to work with streaming from a Red5 server and it’s working really well except for one thing I want to do. I want it to load the first video in the player and pause showing the first frame of the video so that it doesn’t play until the user clicks play. I added a boolean variable to check if it is the first video and if so, I do the following:
    nsStream.play(videoSource);
    nsStream.pause();
    nsStream.seek(0.01);

    This works as far as showing the video paused at the first of the video, but when I click play the progress scrubber doesn’t move as the video plays. In using trace I was able to determine that when I do this, the onMetaData doesn’t seem to be executing, so it doesn’t get the length of the video, etc. for the scrubber. Any ideas? Thanks!

  56. jam Says:

    hello Rafael Nuenlist

    when it returns from full-screen , the player not comes in original form

    how i correct this

    rest of things are good work by you

  57. jam Says:

    How we can add subtitles option in the video

  58. Joakim Says:

    Hi great tut. I am having the same problem as some other. The autoplay start the movie but if you use:

    playClicked(null);

    at the end you get an error and is you don’t then the fisrt time you pause and play the movie start from the top.
    Frther I would like the controls to scale with the fullscreen. How do I do this?

  59. Tin Says:

    Hi,

    Your tutorial is great.

    Now i am wondering how can i add an another frame at the end of the movie.

    Bcoz I like to add in some message like, ‘Thanks for watching, for more detail pls click here.’
    then “here” will link to a web page

    Please kindly widen my knowledge.

    Thanks
    Tin

  60. Sameer Says:

    i have used this player for my website but i m facing one problem, when i m giving the remote path or any server path in playlist.xml file, like this

    the player unable to run the .flv file, can anyone please help me out, how can i access server site file through xml.

    suggestion will be regardless.

  61. vijay Says:

    hi,
    nice work
    can u help me how to show playlist under vedioplayer?

    thank u

  62. Bradd Says:

    Thanks for a great player and tutorial!

    I am having an issue trying to have the volume slider be vertical. I am also having trouble with the progress scrubber. It lines up when the player loads however once I click play it jumps to the right. Any ideas how I could fix this?

    Thanks a bunch

    Bradd

  63. Matrich Says:

    Nice tutorial! But I want a combo box xml, that can load the video. How can i do it? Tnx for your time.

  64. Matrich Says:

    Nice tutorial! But I want a combo box xml, that can load the video. How can i do it with your video player? Tnx for your time.

  65. bebOp Says:

    Great tutorial, i love it..
    I’m trying to give my player the way to seek to atime that it dowsn’t have downloaded yet.

    Example: i have downloaded 2:30 minutes of my video and it’s playing..
    Now i click on the progress bar, at a point where 3:00 is.

    How can i make my player seek to that point? the seek method doesn’t work and the play() with start parameter doesn’t work… any ideas?

    thank you

  66. Ernie Says:

    Love this!

    How can I make my music player turn off when the video is click to play?

    Also does anyone know the best way to make a FLV file???

    THANK!

  67. Shelley Says:

    Wonderful tutorial and just what I was searching for. Being able to load several videos and play them is terrific. I learned a lot about constructing the nuts and bolts symbols (movieclips, buttons) and using invisible buttons. As someone very new to ActionScript 3, I really value the comments and explanations. Thank you so much!

  68. Joshua Towle Says:

    I simply have to thank everyone on this site for this fantastic tutorial! It has both increased my Flash capabilities and helped me dramatically improve a currently outdated player.

    Much as Adam has suggested above, I did find a way to implement a buffer that works in the “real-world” expected manner. The problem with the inherent Flash buffer is that it is only accounts for internal file management. The “bufferTime” property can be working just fine, but if a user of the video player scrubs ahead too far in the player, the user is accessing data that is outside the “bufferTime” scope. The “bufferTime”, itself, really has nothing to do with where the user may be actually watching the video and more to do with information in the player, itself.

    Following Adam’s suggestion, I built several functions that incorporate the download progress of an FLV file, as well as the position of the progress playhead (whether scrubbed or playing automatically). Now I am a little new to Actionscript, so I’m sure there may be a more efficient way to write some of what I’ve done. However, I’ve come up with the following:

    public function updateFLVLoad(event:ProgressEvent):void {
    // check flv download progress
    if(asURLFLVLoad.bytesLoaded (mcFLVCntl.mcFLVTimeline.mcFLVLoad.width – 5))) {
    asNS.pause();

    // switch play/pause visibility
    mcFLVCntl.btnPause.visible = false;
    mcFLVCntl.btnPlay.visible = true;

    // display the buffer and start playing the buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = true;
    mcFLVDisplay.mcFLVBuffer.play();

    // remove the buffer text “resume” from the display
    mcFLVDisplay.mcFLVLoadTxt.visible = false;

    // set the buffer setting as on
    asBLBuffer = true;
    }
    else if(asBLBuffer) {
    // remove and stop the buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = false;
    mcFLVDisplay.mcFLVBuffer.gotoAndStop(1);

    // display the buffer directions on the main stage
    mcFLVDisplay.mcFLVLoadTxt.visible = true;

    // switch play/pause visibility
    mcFLVCntl.btnPause.visible = false;
    mcFLVCntl.btnPlay.visible = true;

    // reset the buffer value to allow the updatePlayDisplay function to determine setting
    asBLBuffer = false;
    }
    }
    }

    public function completeFLVLoad(event:Event):void {
    // when the flv file has completely downloaded, remove the progress listening events
    if(asURLFLVLoad.bytesLoaded == asURLFLVLoad.bytesTotal) {
    removeEventListener(Event.OPEN, initFLVLoad);
    removeEventListener(ProgressEvent.PROGRESS, updateFLVLoad);
    }

    // maintain the flv load bar width
    mcFLVCntl.mcFLVTimeline.mcFLVLoad.width = 356;

    // stop the stage buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = false;
    mcFLVDisplay.mcFLVBuffer.gotoAndStop(1);

    // reset the buffer value to allow the updatePlayDisplay function to determine setting
    asBLBuffer = false;
    }

  69. Joshua Towle Says:

    In my previous post I forgot the HTML code the >, < and #&38; characters. Sorry about that! Ugh!:

    public function updateFLVLoad(event:ProgressEvent):void {
    // check flv download progress
    if(asURLFLVLoad.bytesLoaded <= asURLFLVLoad.bytesTotal) {
    mcFLVCntl.mcFLVTimeline.mcFLVLoad.width = ((asURLFLVLoad.bytesLoaded * 356) / asURLFLVLoad.bytesTotal);

    // display buffer animation and text overlay if flv file overlaps buffer
    if((asBLFLV == true) && ((mcFLVCntl.mcFLVTimeline.mcFLVHelve.x + 214.55) > (mcFLVCntl.mcFLVTimeline.mcFLVLoad.width – 5))) {
    asNS.pause();

    // switch play/pause visibility
    mcFLVCntl.btnPause.visible = false;
    mcFLVCntl.btnPlay.visible = true;

    // display the buffer and start playing the buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = true;
    mcFLVDisplay.mcFLVBuffer.play();

    // remove the buffer text “resume” from the display
    mcFLVDisplay.mcFLVLoadTxt.visible = false;

    // set the buffer setting as on
    asBLBuffer = true;
    }
    else if(asBLBuffer) {
    // remove and stop the buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = false;
    mcFLVDisplay.mcFLVBuffer.gotoAndStop(1);

    // display the buffer directions on the main stage
    mcFLVDisplay.mcFLVLoadTxt.visible = true;

    // switch play/pause visibility
    mcFLVCntl.btnPause.visible = false;
    mcFLVCntl.btnPlay.visible = true;

    // reset the buffer value to allow the updatePlayDisplay function to determine setting
    asBLBuffer = false;
    }
    }
    }

    public function completeFLVLoad(event:Event):void {
    // when the flv file has completely downloaded, remove the progress listening events
    if(asURLFLVLoad.bytesLoaded == asURLFLVLoad.bytesTotal) {
    removeEventListener(Event.OPEN, initFLVLoad);
    removeEventListener(ProgressEvent.PROGRESS, updateFLVLoad);
    }

    // maintain the flv load bar width
    mcFLVCntl.mcFLVTimeline.mcFLVLoad.width = 356;

    // stop the stage buffer animation
    mcFLVDisplay.mcFLVBuffer.visible = false;
    mcFLVDisplay.mcFLVBuffer.gotoAndStop(1);

    // reset the buffer value to allow the updatePlayDisplay function to determine setting
    asBLBuffer = false;
    }

  70. Vijay Says:

    hey great work
    but i want ur help!
    how can i show playlist under videoplayer
    im not good in actionscript
    so pls help me out any help would be appriciated
    thnk u

  71. Ems Says:

    Hi there,

    First of all thanks for the great tutorial.. helped me a lot..

    My question is how can I make the fullscreen for the video display only.. I use the player in a bigger stage and when I make it fullscreen it’s not working properly..

    I hope there is a solution for this, thanks anyways…

    Ems

  72. Daryl Says:

    I wish to use multiple xml playlists and a single swf player. What code should I add to the html to pass the name of the xml file to the flash player? The download example doesn’t show the code for setting the variable ‘playlist’

    Many thanks for any help.

  73. Vijay Says:

    hey pls its urgent for me
    how can i show playlist below videoplayer
    is thr any way to show playlist
    so pls help me out any help would be appriciated
    thnk u

  74. Rich Triblets Says:

    Thanks a mil for this code. I’m having one little issue that’s pretty maddening.

    I set the first video to autoplay and it will not pause and restart.

    I simply modified the code as below.

    function playlistLoaded(e:Event):void {
    // create new xml with loaded data from loader
    xmlPlaylist = new XML(urlLoader.data);

    // set source of the first video and play it
    playVid(0, true)

    // show controls
    mcVideoControls.visible = true;
    }

    It doesn’t seem to make sense as it’s simply calling the function playVid and the pause works once I call the next video which appears to be the same function. Please reply to the whole string as there are a few requests for autoplay functionality.

    Thanks again,
    Rich

  75. cherry Says:

    Thanks for the nice tutorial.

    I am also having trouble with the progress scrubber. It lines up when the player loads however once I click play it jumps to the right. Any ideas how I could fix this?

    Thanks a bunch!

  76. klima servisi Says:

    perfect shared. Thank you very much

  77. Jordi Says:

    Hello,

    First of all… nice tutorial :) It helps me a lot to understand the concepts of develop a as3 videoplayer.

    I’m writing because I found something that I don’t know how to solve/develop in this player, once I followed all your points, I realize that If I have a video in internet and I start to play the video, I only can jump with the scroll “of time” to any time that I already download. Is there any possibility to develop a behavior as youtube? I mean, a user can scroll in the line to any time, and if this time isn’t download, starts from there and forget the other previous video that isn’t downloaded.

    Do you know what I mean?

    Thanks for your help,
    Jordi

  78. deeepak Says:

    i would like to auto hide all the controls… Also will this player support for live streaming?

    Reply me anybody…

  79. Chris Says:

    Hi to everybody, great great tutorial :-) :-) it’s a great job.
    I inserted show/hide controls with tween and alpha with the following code which creates a fade-in/out effect:

    //call tween
    import fl.transitions.Tween;
    import fl.transitions.easing.*;
    var outTween:Tween;
    //listeners
    mcVideoControls.addEventListener(MouseEvent.MOUSE_OVER, showControls);
    mcVideoControls.addEventListener(MouseEvent.MOUSE_OUT,HideControls);
    //the 2 funcions
    function showControls(e:MouseEvent):void {
    outTween = new Tween(mcVideoControls, “alpha”, None.easeNone, 0, 1, 0.5, true);
    }
    function HideControls(e:MouseEvent):void {
    outTween = new Tween(mcVideoControls, “alpha”, None.easeNone, 1, 0, 0.5, true);

    }
    The only problem i hade is that when the mouse is on the play/pause and other buttons the mcVideoControls.addEventListeners call the functions again, so the controlbar “fades-in” again when i move, for example, from for the stop to the play button.I tried with mcVideoControls.mouseChildren=false;
    but it doesn’t let works the single buttons anymore .
    Some1 of you expert in as 3.0 can has an idea how to solve?
    Thanks for the help and thanks for this great guide..:-)

7 Trackbacks For This Post

  1. Tutorial | Create a AS3 Videoplayer with playlist and fullscreen support « Flash Enabled Blog Says:

    [...] Tech Labs has just published a new tutorial, about expanding the Videoplayer, with new features like, playlist, fullscreen support, save volume [...]

  2. AS3 Video Player tutorials roundup | Lemlinh.com Says:

    [...] Read more [...]

  3. Todays Links to check out. Says:

    [...]  john harris says: http://www.thetechlabs.com/video/expanding-the-as3-videoplayer/ [...]

  4. Ultimate List Of 40 Quality Flash Tutorials For Your Animated Desire | The Theme Blog Says:

    [...] Expanding the AS3 Videoplayer Take the videoplayer in the previous tutorial several steps further. [...]

  5. 30 Hand-picked Flash and Essential Actionscript 3.0 Tutorials | Noupe Says:

    [...] – Expanding the Flash AS3 Videoplayer [...]

  6. Best of FREE Flash Tutorials - Hidden Pixels Says:

    [...] Expanding the Flash Actionscript 3.0 Videoplayer [...]

  7. StefKob Blog | webdesign, seo, dev... | » » Flash AS 3 tutorial… Says:

    [...] – Expanding the Flash AS3 Videoplayer [...]

Leave a Reply