Today we explain you how to create a videoplayer with some basic features like this one.
These are: - Play/Pause - Stop - Preloading - Scrubbing - Volume handling There will be another tutorial, which will extend this player. So be sure to check it out.
Requirements
Adobe Flash CS3
Source Files
Constants
As always, we begin with setting the constants. The BUFFER_TIME constant stores the time to buffer for the video in seconds. This one will later be assigned to the netstream object
const BUFFER_TIME:Number = 8;
DEFAULT_VOLUME holds the start volume when the player starts
const DEFAULT_VOLUME:Number = 0.6;
Our player has a timer, that updates all the visual parts. We store the update delay in milliseconds in a constant.
const DISPLAY_TIMER_UPDATE_DELAY:int = 10;
To make the video a bit smoother, we can the the Video.smoothing variable to true. This may slow down old computers. If you want to deactive the smoothing on runtime, just open the html file in the zip file, right click on the video player and choose low for the quality. This way the smoothing will automaticaly be deactivated by the flash player.
const SMOOTHING:Boolean = true;
Variables
Let’s move on with the variables. We need to know, if the flv has been loaded when clicking the play button in order to load it or just play the video.
var bolLoaded:Boolean = false;
For the timer function we need to know, if we’re currently scrubbing the volume or the porgress bar.
var bolVolumeScrub:Boolean = false; var bolProgressScrub:Boolean = false;
Our player has also a mute/unmute button. So, we need to store the last used volume. Like this when you click on unmute, the scrubber will jump back to it’s previous position as the volume does. This value is always greater than zero. We asign the value from DEFAULT_VOLUME.
var intLastVolume:Number = DEFAULT_VOLUME;
Then we need to have a net connection object for net stream and of course also a net stream object.
var ncConnection:NetConnection; var nsStream:NetStream;
To store the received meta data from the flv file, we create an object
var objInfo:Object;
You can change your url to the flv file here. We just set it to the sample movie that’s in the same folder as the swf.
var strSource:String = "hancock-tsr2_h480p.flv";
And last of all, we create a timer object for updating the stuff from the player.
var tmrDisplay:Timer;
Functions
Now we need to initialize our player. First of all, we hide the unmute and pause button. Then we set the width of the progress and preload fill to 1.Our next step is adding a global eventlistener when the mouse button is released and adding event listeners to all buttons. Then we create ourtimer object for
updating all parts of the player and add the event listener. Next we create a new net connection, add the event listener and connect it to null because we don’t have a media server. The net stream object needs the net connection for initizalizing. Once we have our net stream object ready, we add the event listener, set the client property to this for handling the meta data and set buffer tim eto the value from the constant BUFFER_TIME. Then we attach the net stream to the video object on the stage and set the smoothing property to the value from the constant SMOOTHING. Last of all we set the default volume to the value from the constant DEFAULT_VOLUME. Note that only values from zero to one are allowed.
function initVideoPlayer():void {
mcVideoControls.btnUnmute.visible = false;
mcVideoControls.btnPause.visible = false;
mcVideoControls.mcProgressFill.mcFillRed.width = 1;
mcVideoControls.mcProgressFill.mcFillGrey.width = 1;
stage.addEventListener( MouseEvent.MOUSE_UP, mouseReleased);
mcVideoControls.btnPause.addEventListener(MouseEvent.CLICK, pauseClicked);
mcVideoControls.btnPlay.addEventListener(MouseEvent.CLICK, playClicked);
mcVideoControls.btnStop.addEventListener(MouseEvent.CLICK, stopClicked);
mcVideoControls.btnMute.addEventListener(MouseEvent.CLICK, muteClicked);
mcVideoControls.btnUnmute.addEventListener(MouseEvent.CLICK, unmuteClicked);
mcVideoControls.mcVolumeScrubber.btnVolumeScrubber.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
mcVideoControls.mcProgressScrubber.btnProgressScrubber.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);
tmrDisplay = new Timer(DISPLAY_TIMER_UPDATE_DELAY);
tmrDisplay.addEventListener(TimerEvent.TIMER, updateDisplay);
ncConnection = new NetConnection();
ncConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
ncConnection.connect(null);
nsStream = new NetStream(ncConnection);
nsStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nsStream.client = this;
nsStream.bufferTime = BUFFER_TIME;
vidDisplay.attachNetStream(nsStream);
vidDisplay.smoothing = SMOOTHING;
mcVideoControls.mcVolumeScrubber.x = (53 * DEFAULT_VOLUME) + 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
setVolume(DEFAULT_VOLUME);
}
The most important part is now done. We’ve set all variables and added all event listeners. We’re now going to go through all button event listeners. When the user hit’s the play button, we need to check, if the flv download has already begun. If that’s the case, we resume the playback with the NetStream.resume() function. If not, we call the play() function and add the source to the flv file as the parameter.
Then we show the video display object that’s on the stage. And finaly we switch the pause/play visibility.
function playClicked(e:MouseEvent):void {
if(!bolLoaded) {
nsStream.play(strSource);
bolLoaded = true;
} else {
nsStream.resume();
}
vidDisplay.visible = true;
mcVideoControls.btnPause.visible = true;
mcVideoControls.btnPlay.visible = false;
}
The pause button only calls the pause() function from the net stream object and switches the pause/play visibility.
function pauseClicked(e:MouseEvent):void {
nsStream.pause();
mcVideoControls.btnPause.visible = false;
mcVideoControls.btnPlay.visible = true;
}
When the user click’s the play button, the stopVideoPlayer() function will be called. We’ll explain this function below.
function stopClicked(e:MouseEvent):void {
stopVideoPlayer();
}
The mute button sets the volume to zero and updates the volume scrubber and fill position/width.
function muteClicked(e:MouseEvent):void {
setVolume(0);
mcVideoControls.mcVolumeScrubber.x = 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = 1;
}
The unmute button sets the volume to the last used volume and updates the volume scrubber and fill position/width.
function unmuteClicked(e:MouseEvent):void {
setVolume(intLastVolume);
mcVideoControls.mcVolumeScrubber.x = (53 * intLastVolume) + 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
}
When the volume scrubber is clicked, the scrub flag will be set to true. Then we start dragging it withing the boundings that are described as a rectangle.
Exactly the same goes for the progress scrubber except that we’re setting another flag variable and bounding.
function volumeScrubberClicked(e:MouseEvent):void {
bolVolumeScrub = true;
mcVideoControls.mcVolumeScrubber.startDrag(false, new Rectangle(341, 19, 53, 0));
}
function progressScrubberClicked(e:MouseEvent):void {
bolProgressScrub = true;
mcVideoControls.mcProgressScrubber.startDrag(false, new Rectangle(0, 2, 432, 0));
}
Last of all, we have our mouseReleased() handler. This function is needed for knowing, when the user stops the scrubbing. First, we set the progress/volume scrub flag to false. Then we stop all dragging actions and update the width of the progress/volume fill. And if the volume is greater than zero, we store it in the variable intLastVolume.
function mouseReleased(e:MouseEvent):void {
bolVolumeScrub = false;
bolProgressScrub = false;
mcVideoControls.mcProgressScrubber.stopDrag();
mcVideoControls.mcVolumeScrubber.stopDrag();
mcVideoControls.mcProgressFill.mcFillRed.width = mcVideoControls.mcProgressScrubber.x + 5;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
if((mcVideoControls.mcVolumeScrubber.x - 341) / 53 > 0)
intLastVolume = (mcVideoControls.mcVolumeScrubber.x - 341) / 53;
}
The updateDisplay() function will be called by the timer object 100 times a second. If you want, you can decrease this value by increasing the value from the constant DISPLAY_TIMER_UPDATE_DELAY.
First of all, we check if the user is scrubbing on the progress bar. If that’s the case, we seek in the video. If not, we just update the position of the scrubber according to the current time.
Then we set the time and duration label. We format the values with the function formatTime() which we explain later.
Now we update the width from the progress bar. The grey one displays the loading progress while the red one shows the progress from the video.
Last of all we update the volume and the red fill width when the user is scrubbing.
function updateDisplay(e:TimerEvent):void {
if(bolProgressScrub)
nsStream.seek(Math.round(mcVideoControls.mcProgressScrubber.x * objInfo.duration / 432))
else
mcVideoControls.mcProgressScrubber.x = nsStream.time * 432 / objInfo.duration;
mcVideoControls.lblTimeDuration.htmlText = "” + formatTime(nsStream.time) + “ / ” + formatTime(objInfo.duration);
mcVideoControls.mcProgressFill.mcFillRed.width = mcVideoControls.mcProgressScrubber.x + 5;
mcVideoControls.mcProgressFill.mcFillGrey.width = nsStream.bytesLoaded * 438 / nsStream.bytesTotal;
if(bolVolumeScrub) {
setVolume((mcVideoControls.mcVolumeScrubber.x - 341) / 53);
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
}
}
The onMetaDataFunction will be called as soon as the net stream object gets the meta stuff from the flv file. We store these informations in a object. Now can start the timer object because we have all the neccesary data.
function onMetaData(info:Object):void {
objInfo = info;
tmrDisplay.start();
}
Once a net status event will be fired, the netStatusHandler() function will be called. The event holds the info code of the event type. We only need to handle NetStream.Play.StreamNotFound in case the stream is not found and NetStream.Play.Stop to know, when the video reached its end to stop the player with the stopVideoPlayer() function.
function netStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case "NetStream.Play.StreamNotFound":
trace("Stream not found: " + strSource);
break;
case "NetStream.Play.Stop":
stopVideoPlayer();
break;
}
}
There are 2 ways to stop the playback: One is clicking the stop button, the other is reaching the end of the video. That’s the reason why we’ve put this in a function.
First we pause the netstream and set the playback position to zero. In order to clear the display where the last frame of the video will be shown we need to set the visibility to false. We can’t use the Video.clear() function since it has a bug. But this one has already been reported to adobe. This workaround works fine. Finaly we switch the play/button visibility.
function stopVideoPlayer():void {
nsStream.pause();
nsStream.seek(0);
vidDisplay.visible = false;
mcVideoControls.btnPause.visible = false;
mcVideoControls.btnPlay.visible = true;
}
To set the volume of the video we use the setVolume() function.
First we create a soundtransform object with the value from the parameter. Then we assign this object to nsStream.soundTransform.
And we hide or show the mute and unmute according to the volume. If it’s greater than zero, we show the mute button and vice versa.
function setVolume(intVolume:Number = 0):void {
var sndTransform = new SoundTransform(intVolume);
nsStream.soundTransform = sndTransform;
if(intVolume > 0) {
mcVideoControls.btnMute.visible = true;
mcVideoControls.btnUnmute.visible = false;
} else {
mcVideoControls.btnMute.visible = false;
mcVideoControls.btnUnmute.visible = true;
}
}
The last function formatTime() is used to format the seconds to the format mm:ss.
function formatTime(t:int):String {
var s:int = Math.round(t);
var m:int = 0;
if (s > 0) {
while (s > 59) {
m++;
s -= 60;
}
return String((m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s);
} else {
return "00:00";
}
}
Call init function
The only thing left to do is calling the init function for the player.
initVideoPlayer();
We hope you liked this tutorial. If you have any question don’t hesitate to ask. Also we’ve already mentioned be sure to check back for the next part that will be coming soon.
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 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;
// url to flv file
var strSource:String = "hancock-tsr2_h480p.flv";
// timer for updating player (progress, volume...)
var tmrDisplay:Timer;
// ##########################
// ############# FUNCTIONS
// ##########################
// sets up the player
function initVideoPlayer():void {
// hide buttons
mcVideoControls.btnUnmute.visible = false;
mcVideoControls.btnPause.visible = false;
// set the progress/preload fill width to 1
mcVideoControls.mcProgressFill.mcFillRed.width = 1;
mcVideoControls.mcProgressFill.mcFillGrey.width = 1;
// add global event listener when mouse is released
stage.addEventListener( MouseEvent.MOUSE_UP, mouseReleased);
// 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.btnMute.addEventListener(MouseEvent.CLICK, muteClicked);
mcVideoControls.btnUnmute.addEventListener(MouseEvent.CLICK, unmuteClicked);
mcVideoControls.mcVolumeScrubber.btnVolumeScrubber.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
mcVideoControls.mcProgressScrubber.btnProgressScrubber.addEventListener(MouseEvent.MOUSE_DOWN, progressScrubberClicked);
// 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
mcVideoControls.mcVolumeScrubber.x = (52 * DEFAULT_VOLUME) + 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 52;
setVolume(DEFAULT_VOLUME);
}
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();
}
// show video display
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 = 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = 1;
}
function unmuteClicked(e:MouseEvent):void {
// set volume to last used value
setVolume(intLastVolume);
// update scrubber and fill position/width
mcVideoControls.mcVolumeScrubber.x = (53 * intLastVolume) + 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
}
function volumeScrubberClicked(e:MouseEvent):void {
// set volume scrub flag to true
bolVolumeScrub = true;
// start drag
mcVideoControls.mcVolumeScrubber.startDrag(false, new Rectangle(341, 19, 53, 0));
}
function progressScrubberClicked(e:MouseEvent):void {
// set progress scrub flag to true
bolProgressScrub = true;
// start drag
mcVideoControls.mcProgressScrubber.startDrag(false, new Rectangle(0, 2, 432, 0));
}
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 - 394 + 53;
// save the volume if it's greater than zero
if((mcVideoControls.mcVolumeScrubber.x - 341) / 53 > 0)
intLastVolume = (mcVideoControls.mcVolumeScrubber.x - 341) / 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 - 341) / 53);
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 53;
}
}
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
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 stop the player
case “NetStream.Play.Stop”:
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;
}
}
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″;
}
}
// ##########################
// ############# INIT PLAYER
// ##########################
initVideoPlayer();








Patrick Hübner
July 31st, 2008 at 9:58 am
Beautifully made tutorial! I appreciate your thoroughness.
Not sure if you’re taking requests for that extended tutorial (hehe) but there is something that I’d love to be able to do that I can’t find a tutorial about.
I’d like to be able to select a section of the video (designate start and end points along the timeline) to loop.
Any thoughts?
August 1st, 2008 at 4:04 pm
Your video player is terrific. I’ve been trying to find something like this for months. I downloaded the code and modified it for my flash project. Everything works perfectly. Now I have a new problem that maybe you can easily solve. My flash site uses one instance of the video display and one instance of the video controls across all the frames. When I want to show a video I make it visible and when I don’t need it I make it invisible. There are navigation buttons at the top to jump to various frames.
I can get everything to behave when the navigation buttons are used. The video will stop, the visibility of the buttons is updated, etc. But when I click on the play button to start a new flv there is a brief frame at the beginning of the previous video. How can I clear the video player so the new stream will play without this problem?
Thanks.
Right now I’m using a progressive download. I’m using the close() method of the netstream to clear it, but the buffer still seems to contain the previous video.
August 1st, 2008 at 11:01 pm
@Lulu: I have to disapoint you, I can’t include your request in the next part. But it shouldn’t be a problem to implement this functionality.
@Bill Roughen: Mmmh, since the Video.clear() function doesn’t work, you will have to set the visibility of the video to false. As soon as the playpack starts, you can set it to true.
Just adding a new case to the netStatusHandler() function should be enough:
================================
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 stop the player
case “NetStream.Play.Stop”:
stopVideoPlayer();
break;
case “NetStream.Play.Start”:
vidDisplay.visible = true;
break;
}
}
================================
And be sure to comment the vidDisplay.visible line in the playClicked() function:
=====================
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();
}
// show video display
//vidDisplay.visible = true;
// switch play/pause visibility
mcVideoControls.btnPause.visible = true;
mcVideoControls.btnPlay.visible = false;
}
================
Hope this works out.
cheers
August 6th, 2008 at 7:10 pm
Love the player, one question. How do I make it start playing the second it loads instead of having to click on play?
August 7th, 2008 at 5:36 pm
@COle: Thank you. To Autoplay you can just add the following line at the very end of the script (After initVideoPlayer()):
playClicked(null);
cheers
August 8th, 2008 at 1:21 pm
Excellent!!!!!!!!
I had seen many players, but this one looks very good in look and functioning.
I had a question, What are changes to the code when we using a Flash Media Server?
ie; streaming from a media server.
August 8th, 2008 at 4:43 pm
@sooraj: Thank you!
When using a Flash Media Server you just need to set it to the net connection. So, the only change would be:
ncConnection.connect(null);
Which will then become:
ncConnection.connect(”rtmp://example.com/”);
That’s it.
August 16th, 2008 at 12:20 am
Great tutorial! Answers a lot of questions I’ve been struggling through with AS 3.0!
Two quick questions, what is the method for stopping the video at a specific point, i.e. I want to hold on the last frame of the video file after it’s played through.
And secondly, I’ve adapted the player for larger video dimensions and everything works great with the exception of the Progress Scrubber. I can restrain it to the new, longer progress bar, but every time the video starts, it jumps 200 or so pixels to the right. I know this is probably simple, I just don’t think I’m looking in the right place within the code.
Thanks.
August 16th, 2008 at 11:54 am
Hey Craig
Thank you for your feedback!
If you want the video player to show the last frame you just need to comment this line:
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 stop the player
case “NetStream.Play.Stop”:
// ################# COMMENT THIS LINE HERE
// stopVideoPlayer();
break;
}
For the other thing you need to adjust the width of the progressbar in the code since it’s static:
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;
So, the number 432 represents how far the scrubber can go. Try to set this number to the width of the progress bar, this should help you out
Greetings
Rafael
August 19th, 2008 at 12:47 am
Awesome site, I just found this. I have been adding flash sites to my rss feeds reader to keep up with things. This is a great tutorial, Im working on building my own AS3 Video Player so this definitely helps!
August 19th, 2008 at 12:50 am
One thing, had you thought about putting all of the code into a class? or into OOP?
August 20th, 2008 at 10:24 am
Fantastic tutorial — best I have seen in a long time!
I am having one problem using it in my SWF, though. In my SWF the user can toggle between looking at some still images, or a video. The still image viewing area and video area each take the entire stage area. That is, when viewing the still images, I hide all the video elements and vice versa (when viewing the video, I hide all still image elements).
My problem is that when I first toggle to the video elements part (default is still image mode) everything works hunky dory with the video elements as expected. But, if I toggle back to still image mode and then try to go back to the video mode, the player is unresponsive.
I have a feeling that the problem has something to do with trying to run the initVideoPlayer(); function after is has already been run once (at the very first toggle) — but some tests that I have run have been unsuccessful.
The behavior I would love to have is that when toggling away from the video mode elements, the video pauses (I can handle this part) and the stream suspends while I am over in still image mode. When I toggle back to video mode, the video resumes and streaming picks up where it left off.
Any ideas how this may be attained?
Regards,
-john
August 20th, 2008 at 11:49 pm
Rafael,
Thanks for the tips on how to stop the video on the last frame. Would I use the same type of technique to trigger another event after the video has finished playing?
For example, I’m trying to program a “Play All” button for x number of FLVs. I imagine the function would detect the end of each video and then go to the next label on the timeline (or whatever code I put here I suppose).
Thanks in advance for your help.
August 26th, 2008 at 4:02 pm
Hi Rafael,
I do not have a query that is directly related to this tutorial but it is relevant here I hope. I m working on a site that is heavily animated and uses the flv playback component at various points in the animation. So for example a section loads with a lot of animation and comes to point and stops where a flv playback component is placed. The when another section is loaded, this section animates to its end and launches the ‘clicked’ sections animation which again goes through an elaborate animation and stops where it has a FLV Playback component on the stage which plays videos. And so on..
The problem is, when a user has requested a section and the flv playback component is still to buffer/load the video, there can be some lag on a slower internet connection hence the user changes the section before any video content had reached his computer. After a few moments, the video that could not load earlier just starts to play abruptly without any component on the stage!
While leaving a section I m checking if a flv is playing (flv.playing) and if so then stopping it. But since the video never loaded, this condition is not met. Also stopping video anyways results in an error as the script doesnt know what to stop.
So what I wanted to know is, is there some way to stop all video like there was stop all sounds in earlier versions of AS? OR is there some way I can make sure that a video request is successfully terminated?
Lastly I m terribly sorry if this query does not belong here. Many Thanks in advance AND of course… this is a gr8 tutorial… very straightforward.
August 26th, 2008 at 7:31 pm
Hi Walmik,
No problem to post a query here. I will try to add a new feature at The Tech Labs, a place where you add your doubts and questions and where developers will try to help you.
Cheers,
Carlos
August 27th, 2008 at 7:54 pm
Where do you instantiate the mcVideoControls object? I’m getting errors for undefined properties since
September 2nd, 2008 at 9:23 am
YOU ARE AWESOME!
you saved me like 50 hours of research. Your code is great!
September 11th, 2008 at 1:06 am
Your script is really cool and exactly what I was looking for.
I tried to connect it to the sample vod file (sample.flv) on FMS using the modified code:
ncConnection.connect(”rtmp://ip-address/vod”);
But then i get an error:
“ArgumentError: Error #2126: NetConnection object must be connected.
at flash.net::NetStream/construct()
at flash.net::NetStream()
at videoplayer_fla::MainTimeline/initVideoPlayer()
at videoplayer_fla::MainTimeline/frame1()”
It can’t seem to connect.
When i use the vodtest file everything works (on my server and development pc), but that one does not connect with the netConnection code.
I hope you can help me.
Best regards,
Roy
September 12th, 2008 at 9:18 pm
NetStream does not wait for the NetConnection to be established, when connecting to a Flash Media Server. So Roy, you’ll to move the NetStream code under netStatusHandler, as below (hope this displays fine):
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 stop the player
case “NetStream.Play.Stop”:
stopVideoPlayer();
break;
case “NetConnection.Connect.Success”:
// 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
mcVideoControls.mcVolumeScrubber.x = (52 * DEFAULT_VOLUME) + 341;
mcVideoControls.mcVolumeFill.mcFillRed.width = mcVideoControls.mcVolumeScrubber.x - 394 + 52;
setVolume(DEFAULT_VOLUME);
//plus other stuff if you need.
break;
}
}
September 17th, 2008 at 1:06 am
Hi Sems,
Thanks.. i’ll look into it right away.
Best regards,
Roy
September 23rd, 2008 at 9:59 am
Hi Rafael,
Great video player=) Think you did a awesome job…
I’m trying to implement the player in a project. The project requires a skip video button to jump to another frame and when the video is finished it should also jump to the same frame as the skip function!
can you please help me to get on the right track=)
regards
Thomas
September 29th, 2008 at 10:53 am
thanks for the tutorials. please am using AS2, can i use the code for it. if not, kindly send me a tutorials on that. am new to flash.
October 1st, 2008 at 11:20 am
@mmdguru: just call the same function that goes to the next frame from a skip button and also call it when the netstream event is fired for stop.
:::::
case “NetStream.Play.Stop”:
callYourFunctionThatGoesToTheNextFrame();
break;
:::::
@william: no, you can’t use the code for as2. but there are many video players out there made with as2
October 2nd, 2008 at 4:47 pm
Thanks for the tutorial, great videoplayer! I do have a question. I’m trying to connect to a FMS. Followed example from post Aug 8, 2008 4:43 pm and I get the following message:
ArgumentError: Error #2126: NetConnection object must be connected.
at flash.net::NetStream/flash.net:NetStream::construct()
at flash.net::NetStream$iinit()
at videoplayer_fla::MainTimeline/initVideoPlayer()
at videoplayer_fla::MainTimeline/videoplayer_fla::frame1()
I lost here, any ideas?
thanks
October 3rd, 2008 at 9:56 am
Hi Rafael
I can just repeat what other already said. This site is a gem.
I’m getting my movies from a FMS. I had to adopt your player with the already mentioned function netStatusHandler(event:NetStatusEvent):void and add a not yet mentioned
ncConnection.client = this;
function onBWDone():void {
trace(”onBWDone called”);
}
in order to catch all required callbacks.
I’m now wondering why I receive a NetStream.Play.Stop notification after a while even if the videostream is paused.
Any idea why this notification is fired?
Fabio
October 3rd, 2008 at 10:02 am
Hi Rafael and all
Again I’m getting my movies from a FMS with rtmp. I’d like to have the videostream pause when the player is loaded, but having the first frame displayed. How can I achieve that?
Fabio
October 7th, 2008 at 8:31 pm
I am trying your AS3 Videoplayer with red5 streaming server but i can not get it to work, i cant figure what i am doing worng. Is there anyway you can post or send me a working streaming copy i would greatly appreciate it
You did a very nice job on the player.
Jimmy
October 22nd, 2008 at 11:28 am
This is fantastic! Very thorough tutorial.
I wonder if anyone (more advanced than me) has managed to turn this into a class?
November 5th, 2008 at 2:53 pm
Great tutorial. Sometimes it’s hard getting all the pieces together in one place and you did an excellent job here.
November 24th, 2008 at 4:28 pm
good work!!
but i have a real problem to connect it to my fms server (influxis)
i changed the code connect(”rtmp……”);
and on play(”file”);
and its always give me that:
ArgumentError: Error #2126: NetConnection object must be connected.
at flash.net::NetStream/flash.net:NetStream::construct()
at flash.net::NetStream$iinit()
at videoplayer_fla::MainTimeline/initVideoPlayer()