How to Build an Interactive Flash Video (FLV) Load Progress Bar
A number of readers have expressed interest in the last handful of video-related blog entries. These include “How to Build a Flash Video (FLV) Progress Bar” (Part 1 and Part 2) and, somewhat related, “How to Build a Basic Slider Widget (AS2).” In some of the blog comments, mischa, Marius, and kweku were asking about how to display the load progress of an FLV file. This was in addition to the existing functionality, which allows the user to see how much of the video has played and also to seek by dragging a knob along a track. Questions included a) how to make sure the user couldn’t drag the seek knob beyond the loaded portion of the video and b) how to make the track itself clickable, so the user could bypass the knob if desired. Let’s take a look at how to incorporate these new elements by adding them to the ActionScript 2.0 presented in Part 2 of the progress bar series.
Patching on the new stuff
The code we’re going to build on is laid out under the “An answer, short and sweet” heading of “How to Build a Flash Video (FLV) Progress Bar (Part 2),” so make sure to get yourself acquainted with the project to that point, which may even require that you read its prequel.
Here, in a one swoop, is the updated code. There are four objects on the Stage now, and one of them is new. Starting from the bottom up: an instance of a movie clip symbol shaped like a rectangle, which has the instance name track; another instance of that same movie clip symbol, this time with the instance name loader (this is the new object); an instance of a circular or almond shaped symbol with the instance name knob; and finally, a Video object with the instance name videoPlayer. The registration point of knob is in the center of that movie clip, and the registration point of the rectangle is in its upper left. The loader rectangle has been darkened a bit due to an adjustment of the Color: Brightness property in the Property inspector. Both rectangles are stacked like playing cards, with loader on top (only loader is visible) and knob is positioned on the left side, center, of loader.
Here’s the code:
var duration:Number = 0;
var ratio:Number = 0;
var idTracking:Number = 0;
var idLoading:Number = 0;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
videoPlayer.attachVideo(ns);
ns.play("externalVideo.flv");
ns.onMetaData = function(evt:Object):Void {
duration = evt.duration;
ratio = track._width / duration;
idTracking = setInterval(updateKnob, 50);
idLoading = setInterval(updateLoader, 50);
};
ns.onStatus = function(evt:Object):Void {
if (this.time > 0 && this.time >= (duration - 0.5)) {
trace("Video complete");
clearInterval(idTracking);
delete this.onStatus;
}
};
function updateKnob():Void {
knob._x = track._x + ns.time * ratio;
}
knob.onPress = function():Void {
clearInterval(idTracking);
ns.pause(true);
this.onMouseMove = function():Void {
if (track._xmouse > 0 && track._xmouse < loader._width) {
this._x = track._x + track._xmouse;
}
}
}
knob.onRelease = function():Void {
delete this.onMouseMove;
ns.seek((this._x - track._x) / ratio);
ns.pause(false);
idTracking = setInterval(updateKnob, 50);
}
knob.onReleaseOutside = knob.onRelease;
function updateLoader():Void {
loader._xscale = ns.bytesLoaded / ns.bytesTotal * 100;
if (loader._xscale >= 98) {
loader._xscale = 100;
clearInterval(idLoading);
}
}
track.onRelease = function():Void {
if (this._xmouse > 0 && this._xmouse < loader._width) {
clearInterval(idTracking);
idTracking = setInterval(updateKnob, 50);
ns.seek(this._xmouse / ratio);
}
}
Examining the changes
The above code may look like a lot, but we haven’t gutted the original functionality. It’s still there, for the most part unchanged. The new parts shouldn’t be overwhelming.
The first update is a change in one of the variables’ names. The current idTracking variable used to be called id. In the new version, we need two such “id” variables — one for the previous knob tracking and one for the new loader progress — so to keep them distinguishable, I declared them as idTracking and idLoading within the first few lines, which obviously required a search-and-replace for “id” throughout the remaining code as it was.
The NetConnection and NetStream preparation hasn’t changed. The NetStream.onMetaData handler has one new line:
idLoading = setInterval(updateLoader, 50);
What this line does is repeatedly trigger a new function, updateLoader(), every 50 milliseconds. This happens along with the initialization of the duration and ratio variables from before, and the repeated triggering of the updateKnob() function.
NetStream.onStatus stays the same. The updateKnob() function also stays the same.
The MovieClip.onPress event handler for the knob movie clip changes a bit — not in principle, but in approach. Pressing the knob still initiates a dragging routine, but instead of using MovieClip.startDrag(), as before, this time a MovieClip.onMouseMove event handler is assigned to knob dynamically. The function for this handler updates the MovieClip._x property of knob in relation to the position of the mouse over the track movie clip (MovieClip._xmouse), plus track’s _x position. Because this happens whenever the mouse moves, it looks just like a constrained horizontal drag, but there’s a catch. This mechanism is wrapped in an if statement that causes the dragging to only occur when two conditions are met: a) when track._xmouse is greater than 0 (this keeps the knob from falling off the left edge of the track) and (&&) b) when track._xmouse is less than the width of the loader clip. Why does this matter? Well, loader’s width will be changing over time, as dictated by the updateLoader() function, and its width illustrates how much of the video has loaded. The second condition of the if statement ensures that knob can’t be dragged beyond the representation of the how much of the video is available.
knob’s MovieClip.onRelease handler is close to what it was before: rather than invoking MovieClip.stopDrag(), it deletes the function assigned to the onPress event, which stops the dragging in much the same way conceptually.
Now we come to the two new functions.
The first is updateLoader(), which adjusts the width of loader based on how much of the FLV file has loaded.
function updateLoader():Void {
loader._xscale = ns.bytesLoaded / ns.bytesTotal * 100;
if (loader._xscale >= 98) {
loader._xscale = 100;
clearInterval(idLoading);
}
}
In ActionScript 2.0, the MovieClip._xscale property is based on percentage. Here, the NetStream.bytesLoaded and bytesTotal properties are divided, and the quotient is multiplied by 100. Because the registration point for this rectangle is on the left, the shape will seem to grow from a very narrow sliver to a wide rectangle as the bytes values update. When loader is almost fully grown (loader._xscale >= 98), its _xscale property is set to 100 for good measure and the repeated updateLoader() triggering is halted by way of the clearInterval() function, which is fed the idLoading variable as a parameter.
And finally, here’s the function that handles the clicking version of seeking. Same idea as the draggable knob, but this is taken care of simply by mouse clicks.
track.onRelease = function():Void {
if (this._xmouse > 0 && this._xmouse < loader._width) {
clearInterval(idTracking);
idTracking = setInterval(updateKnob, 50);
ns.seek(this._xmouse / ratio);
}
}
Again, an if statement checks to ensure that seeking only occurs when the mouse is clicked within a meaningful area (rightward from the left edge and leftward from the width of loader). The current onStatus event handler kills tracking when the video reaches its end. Dragging and releasing knob restarts tracking, so that part is fine, but the clicking needs to do the same thing, in case the video has already reached completion. That explains the clearInterval() and setInterval() lines. Finally, seeking is performed based on the location of the mouse horizontally divided by the same ratio used in the knob logic.
August 28th, 2007 at 7:23 am
Hi David,
I got it, thanks a bundle.
August 28th, 2007 at 8:27 am
kweku,
Sure thing.
September 7th, 2007 at 2:32 pm
Hi David,
Thank you for this article which really saved me - I had tried to get Flash video right for weeks. Your blog is awesome, simple and complete at the same time, your texts do teach a lot of people.
That’s it.
September 10th, 2007 at 1:37 am
Hi David,
A small query. How to get the knob back to the original position when the video has finished playing.
September 10th, 2007 at 7:40 am
To Antonio …
Thanks for the comment! Love to hear that.
To ace …
Two things: first, determine the end of the video clip; second, set the knob’s
MovieClip._xpropertyMovieClip._xproperty of the track.September 14th, 2007 at 8:24 am
This is bloody great, thanks for the help. I have put together a nice flash movie using your blog, just wondered if you know how this site has done there loading.
Are the just delaying the movie depending on the bandwidth of the viewer, whist play the loading clip?
http://stage.friendsofbright.com/
September 14th, 2007 at 11:09 am
Guy,
Orbit presumably has the money for Flash Media Server, so it may be that you’re seeing true streaming, which allows the user to seek not only to any frame (rather than just video keyframes) but also to seek ahead to content that would take progressive download severals seconds or minutes to load.
September 16th, 2007 at 11:27 am
Ahhh right, thanks for clearing that up.
September 19th, 2007 at 12:59 am
first of all David, love your work,.. direct and to the point!
having said that,… now …
not directly related to this current post,.. but curious how would one go about trying to control various cue points ….. for example the html (file thats contains the embedded file) would have several links (anchors) that would cause the flv file to jump to the relevant embeded cue points….
curious if anyone has done this before
thanks
September 20th, 2007 at 3:12 am
Hi there,
Thanks for providing such a wonderful and a really helpful tutorial…
One thing that I want to ask is how can we distinguish by color the part of video that is already played and that will be played. Something like the part that is already played should be a bit darker than the remaining part of the progress bar.
Any Ideas?
September 25th, 2007 at 1:49 pm
To Larry …
Aha. What you’re after is certainly possible, and there are a number of ways to go about it. You mentioned anchors, and Flash has had HTML anchor support for a while now, even to the point where “deep linking” — that is, linking directly into a particular frame or state in a SWF — doesn’t even require ActionScript. For your endeavor, you’ll probably want to go with a code-based solution after all, so you don’t have to fill your main timeline with unnecessary frames.
The key is to interact with the HTML page itself, whether by PHP or some other server-side language, as described here …
http://probertson.com/articles/2006/12/14/deep-linking-flash-application-states/
… or by JavaScript, which could either write out FlashVars as shown in Paul Robertson’s article or communicate with your SWF via the
ExternalInterfaceclass. The point is to gather information from the browser’s address bar (see JavaScript’s Location object; in particular, thesearchandtargetproperties — and use that in Flash in cahoots with theNetStream.seek()method.Your question is a really good one, and to do it right, I’ll need to write out a full article on the subject. I’ve added this to my to-do list.
To Prashant …
In the example above (the actual article), the loader and track movie clips can be given whatever color you like. Using the same approach above, you could create a third movie clip rectangle — again, whatever color you like — and update the third movie clip’s width using the same expression used by the
updateKnob()function. Maybe something like this:October 3rd, 2007 at 3:45 am
Hi David….brilliant tutorial, I’m relatively new to this and its making sense.
I have one issue, I’m using MX2004. Its telling me
Line 11: There is no property with the name ‘onMetaData’.
ns.onMetaData = function(evt:Object):Void {
I put this. in front and it gets it working but the knob goes to random spots in the .flv after scrubbing.
Any ideas.
Apart from that its awesome.
thanks
Graeme
October 4th, 2007 at 12:25 pm
[Follow up on graeme’s comment …]
After looking at Graeme’s files directly, I’m compelled to concede befuddlement. My own FLV files worked fine when loaded into his exact FLA, so my hunch is that something must be awry with his encoding process from the QuickTime MOV originals. Interestingly enough, a
trace()statement in theMovieClip.onReleaseevent handler forknobdid show appropriate values, so it seems ActionScript wasn’t able to performNetStream.seek()correctly on his FLVs, which were converted from H.264 format. But that’s as far as Graeme and I can figure.October 9th, 2007 at 2:18 pm
Hi David, first off I have to tell you. You’re blog is amazing and has helped me so much that I probably couldn’t thank you in a lifetime. Everything is easily understood and certainly to the point. No messing around. This whole FLV playback section on your blog has basically saved me.
There is one thing that I haven’t been able to figure out. I currently work on a web site for a fishing television show and I had built a complete media center to display all of the episodes that were shown on television. The problem I am having is getting a TV commercial playing before the actual episode plays and of course to disable all the controls so they cannot pause it. Then after the commercial has ended it automatically plays the episode and the play/pause controls are again active. You see this done on ABC.com and other television networks.
I am very frustrated and just wondering if it can be implemented within the code you have written above and if not is there anyway you can steer me in the right direction?
I am probably going off the road with this question, I hope thats not a problem.
Thanks a billion!
October 10th, 2007 at 9:24 am
Paul,
Thanks for the compliments!
I means a lot to hear that these articles are helpful.
For what you’re after … well, it could get as simple or complex as you like. If you’re building your own interface, then your controls (knobs, buttons, etc.) are likely to be movie clips, which means your first course of action will be to check out the
MovieClipclass entry of the ActionScript 2.0 Language Reference in detail. You’ll noticeenabledand_visibleproperties, which allow you to temporarily disable and hide your controls.I could see disabling/hiding the controls by default, then playing your commercial. Then, using an approach along the lines of “How to Determine the Completion of a Flash Video (FLV) File” triggering a) the re-enabling/showing of those controls and b) loading the second (content) video all in one swoop.
If you wanted to get fancy, you might use
_alphainstead of_visibleto hide/show your controls with a gentle fade transition.Your question is a good one, and I could see writing an actual article to explain it in more detail. I’ve added it to my list, so keep your eyes peeled. Not exactly sure when I’ll be able to get to it, but I imagine that one would be useful to a lot of people.
October 11th, 2007 at 5:12 pm
Thanks David, I appreciate it. You have no idea how priceless the information you post is The biggest part about your blog is that it always seems that you have answers to stuff I cant find anywhere else. I always check your blog and am exciting to see what I can learn next. Thanks again for all your hard work!
On topic, I did build my own interface using all the stuff that you taught in this lesson. It was something that I never thought I could do but again with your easy instruction it was a piece of cake.
I almost figured this commercial thing as well. The commercial was 30 seconds long and I did a
if (ns.time > 30){
ns.play(”mainMovie”);
controlsMc._visible = true;
playBtn.enabled = true;
}
which worked fine UNTIL the main movie reached 30 seconds it would restart. So basically all I need to find out is how to distinguish the two different movies inside the actionscript. I’m guessing I need 2 seperate ns.time(s) or ns functions if that makes any sense. I am by no means an expert in actionscript. I just learn all the stuff I can online. I think I failed math in high school too. lol.
Ill keep messing around with it until you get a chance to post something further on it. Thanks again.
October 11th, 2007 at 8:30 pm
Paul,
Wow! Well … shoot, I’m glad to hear that! You just made my evening.
As for your adjacent clips, looks like you’re getting closer.
As you’ve seen, the hard-coded 30 in there is going to cause trouble because it’s only valid for videos that are 30 seconds long. The trick is to let ActionScript determine the length of each video programmatically. There are a number of ways to go about it, and one of those ways is illustrated above in the
NetStream.onMetaDatahandler: namely, the previously declareddurationvariable is set to the expressionevt.duration, which is taken from the incomingevtparameter carried by theonMetaDataevent. Thedurationparameter would automatically be 30 in the case of your commercial, and then it would automatically be 60 (or 90, or whatever) for the following video, depending on whatever information was embedded into the FLV. Now, unfortunately, not all FLV encoders embed metadata, which is why you may want to try the littlefor..inloop shown in the last paragraph of the other article (How to Determine the Completion …). Assuming your FLVs do have that embedded metadata, you can program yourifstatement to look for something like this …if (this.time > 0 && this.time >= (duration - 0.5)) { ...… rather than a static number like 30. In the above, the condition checks to make sure the
NetStream.timeproperty is greater than 0 and is greater than or equal toduration(or, as shown above,durationminus half a second, just to cover the bases). That way, yourifcondition will work for both videos, regardless of length. You can leave the_visibleandenabledparts in, because the second time around it doesn’t matter anyway — they’re already on.In any case, it’s definitely a good idea to re-use code whenever you can. Having two blocks of code do the same (or nearly the same thing) isn’t the absolute, nuclear end of the world, but (semi)duplicated code does widen the margin for error, because revisions usually require that you remember to update all duplicates … and the can of worms pops its lid.
I’m catching up on some articles for Community MX and have to wrap up some other loose ends this week, but I’ll try to follow up soon.
October 12th, 2007 at 6:31 pm
Hey David, Im going to start from scratch with the exact code you have above. Ill just continue to try experimenting until you have some more time to post a follow up. At some point Ill post the actionscript I have so far or maybe even send you the fla.
Thanks again
Paul
October 13th, 2007 at 8:27 am
Hi David, back again after some experimentation etc, I had the issue with scrubbing way back on the 3rd Oct (this Blog)….a couple of things have come up, I have managed to get scrubbing to work a lot better after messing about with encoding (still playing with that). Tonight I was trying to get the “loader” bar working and couldnt for the life of me get it working till I realised that the preview in MX2004, even when set to simulate download does not seem to recognise the flv that is to be streamed……..henceforth, no load time is registered and loader bar comes up fully extended. I had to load the whole shebang up to the server and stream it from there to see it do its stuff….thought that might be useful info if anyone else has similiar experience.
One other thing…(creeping into aesthetics here if I may)…I did the widget tutorial and set it up to control volume of an flv, was wondering how to set it up so it works in a vertical fashion like the slider on an amp or eq….tried a few things but didnt get close.
Once again thanks a million for your amazing work and generosity. Its a rare thing.
Graeme
October 15th, 2007 at 6:50 am
Hi David,
Firstly fantastic work, I have never failed to find your blog helpful.
Secondly, could you please help me with a buffering issue. I have a movieclip on the root timeline called ‘bufferClip’ which I would like to display when the flv is buffering then disappear when the flv starts to play. I have tried using the following code:
ns.setBufferTime(10);
ns.onStatus = function(info) {
if(info.code == “NetStream.Buffer.Full”) {
bufferClip._visible = false;
}
if(info.code == “NetStream.Buffer.Empty”) {
bufferClip._visible = true;
}
}
The setBufferTime action works as the video does buffer ten seconds then starts to play. I had the other code working before but that was before used the code within this page and I’m sure that this is due to conflict on the onStatus function.
Could you recommend the best way to implement a ‘buffering’ movieclip please.
Thanks, David
October 15th, 2007 at 9:03 am
To graeme …
Continued luck with the FLV encoding!
Yeah, for preloading tests, the best bet is to upload assets to a server. It seems like more recent versions of Flash actually do take external files into account when simulating downloads — at least, I’ve noticed that with JPGs — but in the end, some testing should always be done in the same environment that users will see.
As for a vertical slider, I’m thinking you mean “< href="http://www.quip.net/blog/2007/flash/how-to-build-basic-slider-as2/" target="_blank">How to Build a Basic Slider Widget (AS2),” right? If that’s so, here’s some code to turn the thing 90 degrees:
Most of the code overlaps with what’s already shown in the article, but the
_xand_yreferences needed to be swapped. In thetrace()function, I preceded the expression(knob._y - track._y) / ratiowith100 -in order make the slider’s value at full (100) when the knob is at the top and empty (0) when the knob is at the bottom.To Neal …
Since you mention a conflict on the
onStatusevent handler, I’m wondering if you overwrote a previous function with your new one. For example, if you already had this (from the article above):… and followed it with a separate function later, the second function would simply replace the first, and you’d end up no longer having a way to determine when the video had reached its end.
Try combining those:
Note that I replaced your parameter name of
infowithevt, only because I had already been usingevtin the article (doesn’t matter what you name the parameter, as long as you reference the name consistently inside the function.October 15th, 2007 at 11:52 am
Thanks for the rapid response David.
I’ve sort of got it working. What is odd is that when using your previous code I would more often than not get the “Video complete” trace output when the flv started playing, then again when it finished.
If I use the code you have provided above (thank you for this) my bufferClip would only disappear when I did not get the “Video complete” trace output when the flv started playing. Strangely if I removed the code for the “Video complete” functionality completely it works every time.
Not sure if I’m doing something wrong and it works now but it concerns me that I’ve not understood something correctly considering your code is always spot on.
October 15th, 2007 at 4:37 pm
Hey David, I got it to work! It has something to do with the buffering. I stripped the code of any buffering completely and it works. Now I just have to figure out how to get the buffering to work with both videos.
THANKS A MILLION!
October 15th, 2007 at 9:32 pm
To Neal …
Thanks for the kind words. I wish my code really was always spot on! I’m often baffled myself, but I’ve gotten pretty good at troubleshooting.
I’m curious about your seeing “Video complete” when the video first began. The first portion of the
ifcondition,this.time > 0, should have kept that from happening. Off the top of my head, I can’t think of why that would have happened for you.As for this …
… that may be happening because of the
delete this.onStatusline: I added that part so that Flash could take a break from responding toNetStream.onStatusdispatches, but it consequently means that the event handler stops responding after the fullifcondition is met. Trying commenting out just that line.If you haven’t understood something, it may very well be that I haven’t explained it well enough yet, so if you’d like me to go over something again, let me know.
To Paul …
Glad to hear it!
October 16th, 2007 at 3:49 am
Hi David, once again thanks for the rapid response - I’m enjoying my flash development at the moment and feel I’m really learning new things which is always good so many thanks.
Having read your response and in particular your comments regarding the if condition, “this.time > 0″ I realised it might not be working due to my various fiddling around with my scrubber and progress track. I have changed the code to “this.time > 1″ and now it works perfectly and I don’t need to comment out the “delete this.onStatus” line either.
Thanks for your help once again Obi-Wan!
Neal
October 16th, 2007 at 8:45 am
Neal,
Yesss!
October 18th, 2007 at 7:21 am
Hi David, sorry to ask another question on this so soon (I thought I had got things exactly how I wanted them but alas no)!
I have created three buttons within a movieclip which when loads a new flv into the player when clicked on by the user. The buttons all have the follwing code:
on (release) {
var nc:NetConnection = new NetConnection();
_root.nc.connect(null);
var ns:NetStream = new NetStream(nc);
_root.theVideo.attachVideo(ns);
_root.ns.play(”videos/video1.flv”);
_root.bufferClip._visible = true;
this.gotoAndStop(1);
}
Everything works fine and the new videos load and play as they should but the problem I’m now having is that after the user clicks on a button to load a new video the scrub seeking functionality stops working although the track functionality works ok.
Do you have any ideas please?
Thanks as ever, Neal
October 18th, 2007 at 8:23 am
Neal,
I recommend that your forego
on()— in other words, direct code attachment — in favor of the dot syntax described in my “Museum Pieces” article. Even more importantly, though, I would definitely lift theNetConnectionandNetStreamparts from each button and combine them into a single block of code. You’re reusing that video object (theVideo), right? so in like fashion, you only need a single instance of those other classes. All the buttons need to do is invokeNetStream.play()and specify which new FLV to load.Does that make sense? I’m not sure, yet, if that’s what’s causing your problem, but that might just be it.
October 18th, 2007 at 9:51 am
Thanks for the response David, hope life is treating you well.
I take your point about sing the dot syntax code (old habits die hard) thanks for the reminder.
You are right about me reusing the video object (theVideo) and so I have removed the NetConnection and NetStream code which wasn’t needed and have gone with just the NetStream.play() to specify the new FLVs.
Unfortunately this still has not solved the problem. I have placed some code which I use to display the timecode of the FLVs within the scrub code but I don’t think this is affecting things as I get the same problem without this code. I have pasted my scrubbing code below and would appreciate you casting your eye over it.
October 19th, 2007 at 8:24 pm
Hi David , hope all is well in your part of the world….thanks for the code for turning the widget over,(yes sorry I forgot to include which page I was talking about…you were right in your assumption). Brilliant,am looking forward to experimenting with that shortly.
Coincidentally I am also enjoying similiar scrubbing issues as Neal (oct 18th 7.21am).
(Hi Neal..) page loads, first vid scrubbing works fine then soon as you load another movie scrubbing starts acting up (other functionality is fine)….I’ve noticed though that you can click on the progress bar and go to other (loaded) spots in the vid that way. Very wierd indeed….. I’ve tried a number of things but so far no joy.
check out what I mean at
http://www.fallfordays.com/crayfishtv/crayfishtv.html
it continues to be an inspiring journey
thanks a million.
October 22nd, 2007 at 1:26 pm
To Neal …
If you’ve removed the extraneous
NetConnectionandNetStreaminstances, then my hunch is that something must be amiss with the way you’re loading new videos. Notice that the currentonPressevent handler clears theidTrackinginterval, which is important: that’s what stops the knob from updating its position based on the video’s progression. Letting the knob go (onRelease) re-establishes thatsetInterval()loop, so there needs to be a similar clearing of the interval when a new video is loaded — otherwise you’ll have two (or more!) conflictingupdateKnob()functions.To graeme …
My guess is, you’re seeing the same thing as Neal, and your issue is also happening because of your current approach in loading new videos. Whatever code you’ve got doing that, make sure to use
clearInterval()to killidTrackingand, heck, evenidLoading(or whatever you’ve named your versions of those variables).e.g.
October 23rd, 2007 at 8:25 pm
thats exactly it
………thanks again David
October 24th, 2007 at 3:06 am
David,
Seriously wonderful work, and your answer was spot on correct.
Thanks for all your help,
Neal
October 25th, 2007 at 11:29 am
Hi David,
First of all, thanks for articles. Very usefeull. There’s only one more thing i’ve trying to do but i can’t.
Regarding the uTube example i would like a bar to appear with the knob representing the amount of video played.
How can i do that?
Thanks in advance
October 25th, 2007 at 1:24 pm
Daniel,
You could create a new bar yet again — either by drawing another or reusing (and tinting) the existing loader bar — and set its
MovieClip._widthproperty based on the location of the knob. In fact, theupdateKnob()could handle this addition along with its existing tasks:… That would assume that the new bar’s position is also on the left edge shared by the other bars. As the knob moves to, say, 50 pixels toward the right, its position is subtracted from
track’s — the difference would be 50 — and the new bar’s width would become 50 to match.You would have to update your knob dragging code as well:
October 26th, 2007 at 3:59 am
Thanks David…
Daniel
November 29th, 2007 at 11:37 am
Hi David, hope you are well. I’ve just implemented the code you provided to Daniel above and it works great.
One more question if you don’t mind. I’ve set my player to buffer the first ten seconds of video with “ns.setBufferTime(10);” and I’ve noticed that when doing this the loadbar doesn’t display the scaling animation until the video starts to play (when its buffered 10secs of content).
Is there a way to buffer the video for say 10secs but have the loadbar scaling begin immediately instead?
Thanks
Neal
December 11th, 2007 at 2:53 pm
Neal,
That’s a good question.
The
NetStreamclass provides two buffer related properties,bufferLengthandbufferTime. In a sense, those are the buffer versions ofbytesLoadedandbytesTotal, respectively. It might get a bit tricky to combine bufferTime with the total time of the video … you could grab the total seconds (i.e. duration) out of the metadata and compare that against thebytesTotalproperty to determine an approximate duration-to-filesize ratio (this will change per FLV, of course, depending on its compression, bitrate, and the like). Subtract yourbufferTimefrom that, maybe, so you can track buffer first, then switch over tobytesLoaded(perhaps minusbufferTime) whenbufferLengthhas reached the value ofbufferTime.Sounds like a fun challenge, actually! But gosh, I haven’t thought it through in detail at all yet. This one isn’t something I can just spout off the top of my head.
January 26th, 2008 at 6:22 pm
Does anyone know how to apply a script for a total video time?
This is the one that I have:
ns.onMetaData = function(metadata)
{
timerDuration = metadata.duration;
var dur_seconds:Number = timerDuration;
var minutes_dspl = Math.floor(dur_seconds/60);
var seconds_dspl = Math.floor(dur_seconds%60);
if (minutes_dspl
April 18th, 2008 at 1:59 pm
Hi David,
I’m working on a flv player myself and was just curious if you’ve had anyone reply that has had trouble with the ‘knob’ actually updating its ‘x’ position based on the mouse onPress in real time so the user can watch the knob travel along the scrub bar? I’ve followed your tutorial very closely and this is the only piece of functionality I’m currently lacking. If you have a moment, please respond. Thank you so much for the tutorial and your help.
April 24th, 2008 at 3:11 pm
To HeavyPops …
Looks like WordPress gobbled your code! Give it another shot.
To David …
When readers do run across the trouble you’ve described, it’s usually because of a missing object reference. Sometimes people declare their
idTrackingvariable out of scope, so that it doesn’t clear withclearInterval(), which means theupdateKnob()function executes more twice and sometimes thrice over — and the loop continues even while they’re dragging.Put
trace("updateKnob");somewhere inside your version of theupdateKnob()function, then test again. That will let you see immediately if the function continues to trigger while you attempt to drag the knob.October 20th, 2009 at 9:43 pm
hello.
i´m having a little problem with the loading bar, it reaches only to 3/4 and it freezes there. The video loads entirely, perfect, and continues to the end, but the loading bar stops at that point. the knob goes right to the end, but if i wnat to drag it, it stops in the same place the loader does…
Do you have any idea what can be hapening?
thank you very much in advance!