How to Determine the Completion of a Flash Video (FLV) File (AS2)
Nearly a year ago, I posted a short entry on Flash video, “How to Load External Video (FLV).” As of today, that article has received more feedback than any other on this blog, often asking how to tell when a video file has completed. The article describes a technique for loading external FLV files without the use of either the FLVPlayback Component or the older Media Components. Looking back, I believe I should have referenced that detail somehow in the title, because many of the questions have ended up pertaining to FLVPlayback, which has its own complete event. If you’re using that Component, handling the built-in event is the easiest way to respond to the end of a Flash video, and we’ll cover that in just a moment. In the spirit of the original article, however, we’ll also take a look at how to determine the completion of a Flash video loaded with ActionScript and a Video object only.
An answer, short and sweet
If you’re using the FLVPlayback Component, here’s what you can do. The following code sample assumes:
- you have an instance of the FLVPlayback Component on the Stage
- its instance name is
videoPlayer(or use what you like, but update the code to suit) - its
contentPathparameter, in the Parameters tab of the Property inspector, is set to the location of your FLV file
Type the following into your scripts layer:
var listener:Object = new Object();
listener.complete = function(evt:Object):Void {
trace("Video complete");
trace(evt.state);
trace(evt.playheadTime);
}
videoPlayer.addEventListener("complete", listener);
How it works
An arbitrarily named variable, listener, is declared and set to an instance of the Object class. This object will be used, in a similar fashion described in the “Event Listener” heading under “Event Handlers versus Event Listeners,” to act as liaison for the FLVPlayback.complete event. This is shown in line 2, where a function is assigned to a complete property of the listener object. The function receives an arbitrarily named parameter, evt, which is also an Object instance. This evt object can be used inside the function to report two properties (state and playheadTime) dispatched by FLVPlayback along with its complete event. In fact, that’s the very next part. Inside the function, there are three trace() statements. The first sends a short “Video complete” message to the Output panel. The next two reference the evt object and the values of the two passed-in properties (state will be “stopped” and playheadTime will indicate the length of the video). Finally, the complete event is associated with the listener object and subscribed to the FLVPlayback instance itself.
In actual practice, you’ll want to use something other than trace() statements inside that function. You might, for example, have paused the timeline as the video began; if so, now would be the time to start it again with a play() action. The choice is yours.
What if I’m using one of the Media Components?
You’re in luck. The ActionScript works practically the same way. Drag an instance of MediaDisplay (for example) to the Stage and give it an instance name. Use the same ActionScript, making sure to match that last line with whatever instance name you choose. The Media Components don’t pass along properties with their complete event, so omit the evt:Object part between the parentheses. (That means you should also omit the evt.state and evt.playheadTime references, because they no longer apply.)
What if I’m using no Components at all?
This is where it gets interesting, because the non-Component approach has taken me on a wild goose chase, off and on, since I first wrote the “How to Load” article last April. The NetStream class, used in the non-Component approach, has no complete event. The closest we get is an onStatus event that carries with it a code property — similar in principle to the state and playheadTime properties mentioned above — whose message can be “NetStream.Play.Stop” under the right circumstances. When I first experimented with this property, I wasn’t sure exactly when it might occur. Sure, it would presumably indicate that a Flash video had ended, but might it not also happen if a video paused because of network traffic?
To make matters worse, I’ve seen notes on other blogs that seem to indicate the “NetStream.Play.Stop” value doesn’t always appear when expected. In light of that, I’ve been looking for another approach and believe I’ve found it in the NetStream.onMetaData event. My suggestion still uses the onStatus event, but with assistance from onMetaData.
Another answer, short and sweet
This code sample assumes:
- no FLVPlayback or Media Component on the Stage; instead, a Video object as described in “How to Load External Video (FLV)”
- an instance name of
videoPlayeron this Video object (or use what you like, but update the code to suit)
Enter the following ActionScript into your scripts layer.
var duration:Number = 0;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
videoPlayer.attachVideo(ns);
ns.play("myVideo.flv");
ns.onMetaData = function(evt:Object):Void {
duration = evt.duration;
};
ns.onStatus = function(evt:Object):Void {
if (this.time > 0 && this.time >= duration) {
trace("Video complete")
delete this.onStatus;
}
}
How it works
If you’re familiar with non-Component video playing, most of the first several lines should already make sense (if not, read that “How to Load” article). The only different is an arbitrary new variable, duration, declared and initialized to zero in the first line. This variable will have its value set by feedback from the NetStream.onMetaData event.
Following the first six lines, a function literal is assigned to the onMetaData event of the ns (NetStream) instance. This event relies on a smattering of extra information attached to the FLV file itself by the video encoder. For this example, I used Flash 8 to encode an AVI, but 3rd party encoders exist, and their documentation should tell you if they include a duration property among the data they attach. The onMetaData event passes along an object, which is collected as evt in the function. This evt object contains a duration property whose value is passed to the previously declared duration variable. This value represents the playing length of the video.
Finally, in like fashion, a function literal is assigned to the NetStream.onStatus event of the ns instance. NetStream does support a time property, which indicates the current position of the video as it plays. An if statement checks the value of ns’s time property to ensure that it’s a) greater than 0 and b) equal to or greater than our duration variable. If so, the video must have finished. In addition, the onStatus function is deleted, otherwise this event may fire more than once. In your own testing, comment out the delete line to see what I mean.
Some readers have noticed (by using trace()) that the time property never quite reaches duration. If that’s true for you, change the if condition to something like this:
if (this.time > 0 && this.time >= (duration - 0.5))
… where you’re subtracting half a second (or whatever works).
Note: this approach depends entirely on metadata bring present in your FLV file(s). Not only metadata, but specifically a duration property. The Flash video encoder itself supports this property, but your own preferred encoder may not. To see for sure what metadata (if any) is getting included in your FLVs, change the above onMetaData handler to the following. You’ll get a list of the whole shebang.
ns.onMetaData = function(evt:Object):Void {
// duration = evt.duration;
for (prop:String in evt) {
trace(prop + ": " + evt[prop]);
}
};
My test video, encoded in Flash, returned the following output:
canSeekToEnd: true
audiocodecid: 2
audiodelay: 0.038
audiodatarate: 96
videocodecid: 4
framerate: 29.9699859619141
videodatarate: 400
height: 480
width: 720
duration: 71.538
Lots of useful information!
April 2nd, 2007 at 3:38 pm
Thanks for your input… I don’t really understand much on FLV handling on flash, so I posted with a lot of code… also added some custom buttons… Great blog, I’ll be sneaking around!. I just placed the video on my website. Have a nice day!
:)
April 4th, 2007 at 11:50 am
Another thing I’ve run across is a flicker at the end of an flv playing. And it ending on an all black screen instead of the last frame of the movie… I wrote this last night…
bg_listener.ready = function(eventObject:Object):Void {
trace(”Total play time for this video is: “+bg_flv.totalTime);
var pauseTime = (bg_flv.totalTime*1000)-2;
trace(”pauseTime: “+pauseTime);
setTimeout(bg_flv, “pause”, pauseTime);
};
bg_flv.addEventListener(”ready”, bg_listener);
that way it makes the movie pause 2 miliseconds before it ends.
It feels sort of hackey though… any ideas Stiller?
April 4th, 2007 at 12:39 pm
var,
The only thing I worry about with such an approach is that you’re relying on a timer mechanism (
setTimout()) that may or may not match up with the actual playback speed of the video on a given user’s machine.If you’re using the FLVPlayback Component — that’s my guess, since you’re handling a
readyevent — you may want to use theplayheadUpdateevent to continuously check the video’s current position against a revisedtotalTimeproperty, but honestly … if you felt your approach was hacky, I feel the same way about mine, because it uses such a tight loop that might go on for several minutes.April 22nd, 2007 at 5:09 am
hey,
With the non-Component methed,
(using duration from metadata)
The Time and the end of the clip is(almost always) not be the duration so in my case it works less often then the “NetStream.Play.Stop” methed.
any ideas?
May 1st, 2007 at 3:57 am
Complistic,
I’m not sure why your metadata would be incorrect (is that what you’re saying?) but if so, and if you know the duration of your videos before hand, you can always use a loop (like
setInterval(), for example) to repeatedly check theNetStream.timeproperty against that known value. Does that make sense?May 2nd, 2007 at 4:22 pm
Ok i’m having a little bit of trouble with this method. I copy and pasted the code into the file and followed it step by step. I loaded the video very simply. It came straight out of the Adobe FLV encoder. The duration of the video is 10 seconds. The problem is that it never seems to get to the end of the video. When I list variables this is what i get:
___________________________________
Level #0:
Variable _level0.$version = “WIN 8,0,22,0″
Variable _level0.duration = 10
Variable _level0.nc = [object #1, class ‘NetConnection’] {
contentType:”application/x-fcs”
}
Variable _level0.ns = [object #2, class ‘NetStream’] {
onMetaData:[function ‘onMetaData’],
onStatus:[function ‘onStatus’],
time:[getter/setter] 9.95,
currentFps:[getter/setter] 0,
bufferTime:[getter/setter] 0.1,
bufferLength:[getter/setter] 0,
liveDelay:[getter/setter] 0,
bytesLoaded:[getter/setter] 266361,
bytesTotal:[getter/setter] 266361,
decodedFrames:[getter/setter] 0,
videocodec:[getter/setter] 4,
audiocodec:[getter/setter] 0
}
Variable _level0.prop = “duration”
_________________________________
Additionally, here is my metadata:
canSeekToEnd: true
videocodecid: 4
framerate: 20
videodatarate: 200
height: 286
width: 234
duration: 10
_________________________________
It seems to me like my video is stopping at a duration of 9.95 and therefor never reaching video complete. Is there something very obvious here that I could be doing wrong?
May 3rd, 2007 at 9:52 pm
Matt,
That’s 1/20th of a second off, which could arguably fly in many cases — we’re talking about one or two clipped frames, in a 30fps FLV — but if you need greater accuracy than that, you may want to test for the
timevs.durationcomparison under circumstances other thanonStatus. I could see using anonEnterFrameevent handler instead, for example …… but you’d have to increase your SWF’s framerate to compensate for the FLV’s framerate. I suppose you could also pad the end of your FLV with a quarter second of silent black, or set up a
setInterval()loop that polls for the comparison in a very tight loop — but then I’d start worrying about excessive CPU cycles just to correct for a relatively small inaccuracy.May 7th, 2007 at 9:35 am
I am definitely cool with the 1/20th thing, I don’t mind clipping frames. The problem is that because it is checking against duration, it is never greater than or equal to (only getting to 9.95 instead of 10.00), which means it never triggers a video complete. Is the best solution for this to check against:
(this.time > 0 && this.time >= duration - .05)
That is the only way I can figure out to make the event trigger.
May 8th, 2007 at 9:34 pm
Matt,
Yeah, that’s a good, clean approach. Much simpler than my last reply.
So weird, though, that you’re seeing what you’re seeing!
May 14th, 2007 at 1:54 am
Thanks Dave for your great tips and insights into Flash development. One thing just to clarify (you alluded to this earlier), is that none of the code-based techniques are 100% frame-accurate, video-speaking. For example if you had two videos that needed to play together seamlessly (i.e., frame #1 of the second video needs to start playing immediatley follwing the last frame of the first video, so they appear seamless), none of the code-based approaches will really work. That’s partly due to the difficutly in triggering an event exactly at the end of the last frame of video, and partly due to the lack of exact control when the next NetStream will start playing.
We recently did a project (disc based) which was similar to the old Dragon Quest game where different video clips played in sequence based on user input. In order to keep the transitions absolutley seamless, we had to go old-school and embed the video into the timelines themselves. You lose a lot of FLV’s inherent advantages this way, but if you need absolute frame-accurate control of the clips, AFAIK that is the only way to do it.
May 18th, 2007 at 1:40 pm
Steve,
Thanks for the insight! Man, I’d love to work on a Dragon’s Lair type project. That one took many fistfuls of quarters from me.
May 19th, 2007 at 4:40 am
David, Steve,
In case it’s helpful, I’ve found a way to get FLV’s to playback seamlessly — for a disc-based app at least.
When I was using a single FLVPlayback instance to stream the clips, I always got a 1-2 second gap between clips. My app needed to run seamlessly, so I layered two FLVPlayback instances on top of each other - sort of like an A & B roll you get in video editing apps.
I then wrote some actionscript to flip between the two players whenever the current player gets to the end. At the same time, I’m pre-loading the next clip into the non-active player in the background.
The script goes something like this…
function doNextScene() {
currentScene++
if (currentPlayer == “a”) {
currentPlayer = “b”;
} else {
currentPlayer = “a”;
}
if(currentPlayer == “a”) {
videoPlayerA._alpha = 100;
videoPlayerB._alpha = 0;
videoPlayerA.play();
videoPlayerB.contentPath = “clips/” + selectedClips[currentScene+1];
} else {
videoPlayerB._alpha = 100;
videoPlayerA._alpha = 0;
videoPlayerB.play();
videoPlayerA.contentPath = “clips/” + selectedClips[currentScene+1];
}
}
Both video players need their autoPlay param set to false for this to work.
You could probably get this technique to work for web-based apps too by using the bufferTime parameter to cache some of the next clip in the background (assuming your bandwidth profile would allow concurrent loading).
Hope this is useful to someone.
May 27th, 2007 at 4:50 pm
Hello David,
Very useful info on this blog! Thanks a ton!
I have reached a roadblock that I hope someone could shed some light on. I would like to load the flv files via ASP. I am looking to do something like this:
videoload.asp output:
&video1=http://www.site.com/testvideo1.flv&video2=http://www.site.com/testvideo02.flv
Actionscript:
loadVariables(”videoload.asp”, “”);
timeOut = getTimer();
var listenerObject:Object = new Object();
listenerObject.stopped = function(eventObject:Object):Void {
RL_FLVPlybk.contentPath = video2;
RL_FLVPlybk.skin = “SteelExternalAll.swf”;
};
RL_FLVPlybk.addEventListener(”stopped”,listenerObject);
RL_FLVPlybk.contentPath = video1;
I have several specific questions:
1) Do I need an ‘&’ ampersand at the beginning of the asp output? I’ve seen it done with and without an ampersand on several sites discussing passing multiple variables between flash and server side script.
2) I keep getting “null url sent to VideoPlayer.load” when I run the page, even when trying to access a static text file in place of the asp file. What am I doing wrong?
Any info would be appreciated. Thank you.
June 1st, 2007 at 7:45 am
Has anyone had experience with looping flv files. I’ve been using the “complete” listener to loop a video, but have found that there is a slight skip whenever the video restarts. I’m wondering if it’s to do with the complete event returning slightly late, or if it’s the flvplayback component struggling at the beginning of the video.
See: http://www.nab.com.au/socceroos for the project in action to see what I am talking about. (you will note the skips in the video in the background players and in between moves of the main character during gameplay)
June 1st, 2007 at 10:47 am
Having an issue with playing one video after the other in a timeline.
Right now im entering
————————————————–
stop();
var listener:Object = new Object();
listener.complete = function(evt:Object):Void {
gotoAndPlay(”next”);
}
videoPlayer.addEventListener(”complete”, listener);
————————————————————-
Then it goes to the “next” frame which is good. The problem I’m having is that it wont keep doing this, if i add the same code with a new goto it doesnt seem to wan to go there.
Im somewhat of a code dunce so any ideas on this would be greatfully appreciated.
cheers
June 1st, 2007 at 3:05 pm
Hi!!…Thanks for the tip!….I am having another problem with Media Components…i am using it to load an mp3..and adding some CuePoints, i need to play the movie, just when it has been loaded…because if i play it before…the cuePoints get crazy…Thanks!!
June 1st, 2007 at 4:09 pm
To Grant …
Hey, thanks for the input!
To Alfred …
In my personal experience, it hasn’t been necessary. Normal query strings start with a question mark (
?), then enumerate urlencoded name/value pairs separated by ampersands (&). That’s how it is for ASP pages that talk to other ASP pages, PHP pages that talk to other PHP pages, and so on — including Flash. Though I haven’t tested the following yet myself, I read on one of the Adobe forums that, in fact, AS3 doesn’t allow an ampersand prefix.It looks like you’re requesting for data, but not waiting for it. You’re assigning
RL_FLVPlybk.contentPath = video1;before thatvideo1variable comes back. Instead of theloadVariables()function, I recommend theLoadVarsclass, which dispatches an event when it completes. Your event handler, in that case, would set thecontentPathTo Clint …
I haven’t personally tried what you’re trying, but I would imagine the skipping might occur for any number of reasons, including the possible Component “struggle” you mention and discrepancies between SWF framerate and FLV framerate(s). Depending on your needs, Grant’s response from May 19 may give you something to experiment with.
If this were my project, I would probably do without the FLVPlayback Component and use two
NetStreaminstances (and two Video objects) — one preloading the second clip while the first is playing. I would start the second clip a half second (give or take) before the first one ends, then send the first one off to fetch the third clip, and so on, tag-teaming.None of this would be especially easy, I’m sure. Clearly, a number of people have had trouble with this sort of looping … and my curiosity is piqued. I’ve added this topic to my (now monstrous) list of blog “things to write about,” and I can’t say for sure when this topic will surface … but I trust it will at some point.
To JamieG …
Is the same FLVPlayback instance (here with the instance name
videoPlayer) in the same frame that thegotoAndPlay()sends the playhead to? If not — if that’s a new (different) FLVPlayback instance — you’ll have to write a new event handler for that one, too.To Igo …
I’m afraid I don’t understand your question — sorry!
June 1st, 2007 at 6:12 pm
Hello David,
I ran across something interesting that other readers may (or may not) find useful. I was using the method you outline above to listen for the end of an flv running through the FLV Playback component, and it was just not working. If I changed to listening for the ’stopped’ event, and then pressed the stop button during playback, the event fired just fine, but never after the clip ended. After some troubleshooting, I decided that the problem was with the flv itself; what I eventually discovered was that clips I transcoded using the Adobe Flash video encoder all seemed to have this issue, while flvs from other transcoders did not. So I’m curious if anyone else has run across this issue, or if it’s just me?
June 2nd, 2007 at 12:43 am
Hi David, thanks for the response. I had actually tried something in the same vain as Grants suggestion, but I just noticed that he states AutoPlay must be disabled. I don’t think I checked this out, so I am going to go back and rewrite teh video sequencer to give it a try at least.
June 18th, 2007 at 10:14 pm
To Paul …
Thanks for that insight! I don’t use the FLVPlayback Component very often, so I can’t say off the top of my head that I’ve run into the same issue, but it wouldn’t surprise me. There are definitely differences between how
FLVPlaybackandNetStreamdispatch their various events (some overlap and some don’t). I’m curious to see what others may have encountered.To Clint …
Cool. Write back if you come up with something nifty!
August 6th, 2007 at 6:49 am
Thanks for the blog David - very helpful.
I’m having a similar problem that Matt had (back in May) where the playback is stopping a few milliseconds before the end and therefore is not triggering the complete event.
Could you advise me on how to implement the fix (this.time > 0 && this.time >= duration - .05)? I’m not really sure where to put this code in order to make it work. Thanks for your help! Andy
August 6th, 2007 at 3:22 pm
Andy,
Sure thing.
In the original article, under the “Another answer, short and sweet” section, here’s a block of code that handles an
onStatusevent for video displayed via theNetStreamclass. ThatonStatusevent handler is where the replacement line needs to go, and this only applies (I believe) if you’re going the Video object/NetStreamroute. Relace that event handler in the article with the following:Note that I dropped the
trace()line, which is only for testing anyway, and you may want to adjust 0.5 (half a second) with a slightly higher or lower value, until you find what works for your situation.Now, on its own, the above revision doesn’t actually do anything. That’s why the earlier
trace()was present, as a stand-in. Replacetrace()with whatever ActionScript meets your needs, such as starting up the main timeline again (if it had been stopped), or something along those lines.August 7th, 2007 at 1:24 pm
Great stuff! I like how you also have code/tips for non-FLVPlayback apps. How, though, could I get playheadTime? (I’m trying to sync slides with video).
Thanks,
Mike
August 7th, 2007 at 1:25 pm
oops…I forgot to add the I’m using the mediaPlayback component.
Thanks again,
Mike
August 7th, 2007 at 1:36 pm
Mike,
If you’re using any of the Media-related Components (MediaPlayback, MediaDisplay, or MediaController), you’ll find your answers in the
Mediaclass of the Components Language Reference. It sounds like you’ve already consulted that, becauseMedia.playheadTimeis indeed inherited by MediaPlayback and MediaDisplay, so you should be good.If you’re hoping to sync up other assets with the video, though, you’ll probably want to use cue points instead — otherwise, you’ll have to loop continuously (with
MovieClip.onEnterFrame, say, orsetInterval()) to repeatedly check theMedia.playheadTimeproperty associated with your particular instance. Check out the sample code snippet for theMedia.cuePointentry for a good start.September 7th, 2007 at 3:34 pm
Here’s a code snippet I created that fixed my problem with the “progressive download” that keeps downloading when a video is stopped:
1st, I put an image on frame 1 relative to the movie about to be played (mine are dynamically loaded), with a play button for the user to click, which, when clicked, plays the root to frame 2
2nd, I put the flvplayback component ON frame 2 which is autoplay=false, and this code:
var listenerPlay:Object = new Object();
listenerPlay.playing = function(evt:Object):Void {
var listenerStop:Object = new Object();
listenerStop.stopped = function(evt:Object):Void {
_root.player.removeEventListener(”stopped”);
_root.gotoAndStop(1);
}
_root.player.addEventListener(”stopped”, listenerStop);
_root.player.removeEventListener(”playing”);
}
player.addEventListener(”playing”, listenerPlay);
if there is a more elegant method of achieving this, please share.. but this works for my needs with dozens of movies on the stage, allowing a user to click play/stop and choose another, without bogging down the users’ pc etc if they click one, then another, and another.. etc.
September 7th, 2007 at 3:53 pm
correction: I stated in the last paragraph “..with dozens of movies on the stage..”.. this isn’t accurate and could lead to confusion. It should have been “.. with dozens of movies formatted on the html page (ie. multiple instances of swf’s each with the above).
September 12th, 2007 at 6:10 pm
David,
I am working on a SWF which calls in turn some other SWF animations and FLV movies based on an xml playlist. I am using the way you explain here to check the playback status and turn to the next SWF or FLV to play. During the first playlist loop everything semms to be ok, second time when the FLV plays, the onStatus does not trigger the end event. I tried putting -0.5 or -1 seconds but nothing changes. Anything to suggest? Thanks!
September 14th, 2007 at 5:22 pm
To Jayson …
That’s a pretty neat approach! You can certainly collapse the code a teensy bit by using a single generic
Objectinstance for your listener. (As a matter of fact, as long as event names don’t overlap, you can use a single listener object for as many events as you need, even if those events are dispatched by more than one object.)Note that you don’t need the
_rootreference because of how these event handler functions determine scope. They look inside themselves first — for example, looking for an object with the instance nameplayer— and when they don’t find it, they look “up the chain,” so to speak, until the object is discovered.Note, too, that instead of sending the main timeline’s playhead to frame 1, I used the expression
_currentframe - 1. The functions will look for theMovieClip_currentframeproperty in themselves, won’t find it, then will look up the chain to the nearestMovieClipinstance. By using an expression rather than a hard coded number, you can pop this snippet into any frame you like, if need be (as long as it has a previous frame to step back to).If you don’t care about the extraneous event handlers — and for a small project, it shouldn’t matter — you can do away with the
removeEventHandler()references. In fact, all you really need (if I understand your goal) is to handle thestoppedevent:var listener:Object = new Object();
listener.stopped = function(evt:Object):Void {
gotoAndStop(_currentframe - 1);
};
player.addEventListener(”stopped”, listener);
To Damiano …
Do all your FLV files have a
durationproperty in their metadata? (Note: you also mentioned you’re loading SWFs — but SWF files don’t have adurationproperty and aren’t loaded usingNetStream. I’m guessing your issue only pertains to the FLVs.)September 20th, 2007 at 9:33 pm
Hey Great stuff!! Thanks for that, 95% of the time it works great although when my video rebuffers due to the network or a slow connection, it does detect when the video has finished (i am doing this through actionscript so i am using your last method.
Please help asap!!
Thanks all
September 23rd, 2007 at 3:09 pm
In addition, for those of you who, like me, have been looking for a way to convert the duration time into 00:00 (minutes:seconds), here’s a function that does it:
September 26th, 2007 at 9:52 am
To George …
The non-component example makes use of the
NetStream.onStatusevent, which may not fire the way we’re expecting (read, as often) during network latency. You can certainly try another event — perhaps something more consistently repetitive, such asMovieClip.onEnterFrame. The downside is that too many concurrentonEnterFramehandlers, or too much going on in a single such handler, can potentially slow down your SWF, but it’s worth a shot. Assuming this code is written in a keyframe (in which casethisrefers to aMovieClipinstance; namely, the main timeline) …To Pedro …
Thanks! For readers interested in more about the modulo operator used in Pedro’s code, see “Lesser Known Operators: Modulo (%)” and “How to Convert Milliseconds to Minutes and Seconds.”
October 16th, 2007 at 4:31 am
..any idea how i could scale an flv video? the default scaling is screwing up the quality
October 16th, 2007 at 9:35 am
Bonifar,
Just like with images, video scaling isn’t an especially recommended practice, especially when the scaling goes up (bigger). As scaling increases an image’s size, its pixels begin to show — that’s just how it works, for better or worse. You should definitely experiment with all your various encoding options (bitrate, framerate, compression, etc.).
October 24th, 2007 at 7:13 pm
David, Thanks for sharing your Flash know-how. It really helped.
October 25th, 2007 at 7:59 am
chris,
Sure thing!
October 25th, 2007 at 2:06 pm
Wow great info on your top section “How to Determine the Completion of a Flash Video (FLV) File”. I had that problem for awhile now. All i did was paste your code in and Bam, i detected the end of my embedded FLV - Good job!
Louis
October 25th, 2007 at 2:09 pm
Louis,
Glad to hear it!
October 25th, 2007 at 5:54 pm
Hi,
I am a complete newbie to Flash and am having a real issue with the following;
I have an fla with 3 frames, frame 1 has some information and a link to frame 2 where an external flv is to be played. The issue I have got is that I want after the flv has finished the fla to move to frame 3 and display some more information but I cannot seem to find a solution to this.
Please please please could someone explain to me how this is achieved as simply as possible.
Your help would be so much appreciated.
Thank you
October 27th, 2007 at 9:21 pm
David,
Your answer depends entirely on what mechanism you’re using to display the video. If you’re using the FLVPlayback component, then you’d use the FLVPlayback approach shown above. In the event handler, you’d set the playhead moving again by way of the
MovieClip.play()method orplay()function.That code would go in frame 2, right alongside your component (which would have the instance name
videoPlayer.October 29th, 2007 at 2:09 pm
Hello,
It was really a good experience to go through your article.I have a doubt,can we do this program in Adobe Captivate(software for flash).I need to build up an e-learning system.I would like to know how much amount video is being viewed by a particular client,and Can I include questions in between the video clip.Please help me to resolve this issue.
Regards,
Ann
October 29th, 2007 at 2:11 pm
Thank you for this, I am using the FLVPlayback component. I simply imported the externally hosted video to the frame. I tried putting the code you suggested but it just keeps cycling around the 3 frames.
And I get the error 1046: Type was not found or was not a compile-time constant: Void.
I am at a complete loss about this
October 29th, 2007 at 7:51 pm
To Ann …
Your endeavor is certainly possible, and it’s even possible with Flash, but you’ll need some sort of server-side middleware (PHP, ASP.NET, Ruby on Rails, Cold Fusion, etc.) in order to record user interactions as you’ve described. Flash would comprise the front end and would communicate with the back end via GET or POST, web services, or the like. Whether this is something Captivate can do — that’s beyond my knowledge, I’m afraid.
To David …
When you see numbered error messages like that, it’s almost certain you’re authoring a document configured for ActionScript 3.0. This particular error message (type not found,
Void) nudges that “almost certain” into “definitely sure.” In ActionScript 3.0, theVoidtype is lowercased (void), but AS3 is considerably different in other respects as well, to the point where the code in this article simply doesn’t apply to the AS3 version of FLVPlayback.You can either: a) delete the FLVPlayback instance, go to File > Publish Settings > Flash tab and change the ActionScript version to 2.0, then replace the FLVPlayback instance, or b) leave your FLA as is and use ActionScript 3.0 syntax instead.
I’ve been meaning to “upgrade” the most popular articles on this site for ActionScript 3.0, and this is another gentle reminder. I’ve added most of my video articles (like this one) to the revision list.
November 1st, 2007 at 7:27 am
Great post, youve got me out of a sticky situation!!
dogs danglies!!
Cheers
November 1st, 2007 at 2:28 pm
neil,
Bob’s your uncle, man.
November 8th, 2007 at 12:01 pm
Hi David its Neal, hope you are keeping well.
I’m sure you know my flash player quite well but I’ve come across a new problem.
What I’m trying to achieve is that when the currently playing video gets to the end the playhead moves back to the beginning and my toggle play/pause button changes state.
Code I’ve tried (with duration established as per your code) is:
ns.onStatus = function(evt:Object):Void {
if (this.time > 2 && this.time >= duration) {
ns.seek(0);
ns.pause(true);
btnToggle.toggled = true;
btnToggle.gotoAndStop(3);
}
}
I’ve used the code within the if statement on my stop button which works perfectly yet in the above it dosen’t work and causes other videos called from my buttons to not load and play?
Your help David as ever would be welcome.
Thanks, Neal
November 8th, 2007 at 2:47 pm
David,
Thanks in advance for your help. I have used your code to deploy flash video on what will be our new home page. I am designing the new site fully in flash.
I ran into a snag, where the video (at least the audio) keeps playing when the end user navigates to a different scene. You can hear the audio still when navigating other areas of the site. How can I put the kibosh on this?
Here is the url: http://www.180group.com/180FlashBeta.html, check it out. Notice the audio keeps playing if you hit Services or any other pages…
The site is not public yet, but I run it from this address to quality control it online.
Your help is appreciated!
Howard
November 11th, 2007 at 12:46 pm
To Neal …
Without seeing the code from your other buttons, I’m not sure I can figure out what’s going wrong here. Part of the problem may be one of scope. Your
onStatusevent handler function is associated with thensinstance itself. References tonsinside that function should bethis(as done in theifstatement) — so,this.seek(0);, etc. — and then, btnToggle may or may not be scoped to that function (meaning, may not be visible from that function’s point of view). To test for that, addtrace(btnToggle);inside that function and keep an eye on the Output panel to see if you get a proper reference tobtnToggleor if you getundefined.To Howard …
I checked out your beta page and didn’t see (rather, didn’t hear!) the problem. Did you already figure out a solution, maybe? If not, let me know. Off the top of my head, though, I would think that in addition to sending the user to a new Scene, those nav buttons might also have to be programmed to halt the video stream.
November 14th, 2007 at 2:40 pm
Yes David, I did figure out the problem. Thank you for your response. I ended up having to do exactly what you said, and halt the video stream when the user navigated to a new page.
We went live with the page last Friday and have recieved some really positive responses. Thank you so much for your blog on externally streaming fla’s, as our site wouldn’t have been the same without it.
The 180 Groups New Flash Website
November 14th, 2007 at 8:15 pm
Howard,
Congrats!
November 22nd, 2007 at 11:52 am
Hi David, hope you are well.
Thanks for your response, I’ve made your suggest changes. I’m still having problems with trying to reset the video to the beginning when the current video gets to the end. I’ve tried using the following:
ns.onStatus = function(evt:Object):Void {
if (evt.code == “NetStream.Buffer.Full”) {
bufferClip._visible = false;
}
if (evt.code == “NetStream.Buffer.Empty”) {
bufferClip._visible = true;
}
if (this.time > 0.5 && this.time >= duration) {
bufferClip._visible = false;
this.seek(0);
this.pause(true);
}
}
All I want is to the video to reset back to the start when it gets to the end, but still now luck. Any further ideas,
Thanks, Neal
November 24th, 2007 at 8:57 pm
Hi David-
I’m not very familiar with working with video and the various actionscript functions that go along with it. I managed to implement the example you provided that allows for actions to be run when the video is complete. How would I then run a set of actions once it has moved away from the last frame of the video? This would either be from someone pressing play again, scrubbing the playback head or rewinding.
Thanks, James
November 27th, 2007 at 1:04 am
To Neal …
It sounds as if you’re just not getting the results you’re expecting, so a number of
trace()statements may be in order. Since you can’t really see what’s going on with code like this, it often helps to instruct ActionScript to tell you what it’s doing. Immediately inside youronStatusevent hander, put a generictrace("onStatus has been triggered");just so you know the event is getting handled at all. I would also addtrace(evt.code);— not inside any of theifstatements, but right inside the function. That way you’ll know which of thoseifs is getting hit (if either). Finally, addtrace(this.time);andtrace(duration);, to make sure those values are present.To James …
The approach you take is going to depend on the mechanism you’re using to play your videos. If you’re using FLVPlayback, for example, you might look into the
FLVPlayback.stateChangeevent, which you can handle the same wayFLVPlayback.completeis shown above. If you’re usingNetStream, the sameNetStream.onStatusevent should do it, but you’ll want to listen for the messageNetStream.Play.Start
(for example) in the way Neal is listening forNetStream.Buffer.Fullin the question just before yours. See how he’s usingifstatements before the finalifstatement that checkstimeagainstduration? You can do the same, and put as many additional instructions as you like. Does that make sense?November 29th, 2007 at 11:00 am
Hi David,
Thanks for this, having looked through, and rebuilt some of my player components this now is working great. I think my problem was not deleting the onStatus event when the video had finished. Thanks very much for your help.
November 29th, 2007 at 11:01 am
Neal,
Sure thing! Glad you nailed it.
December 5th, 2007 at 4:08 pm
I’m trying your script, and I’m sure I’m doing something really stupid, but when I try to publish the flash file it says:
**Error** Scene=Scene 1, layer=Actions, frame=20:Line 75: There is no property with the name ‘onMetaData’.
netStream.onMetaData = function(evt:Object):Void {
Now I know you use ns instead of netStream. But I’m adding this to an existing project where I use netStream in many different places, so I kept it. Here’s the code I use for that:
var netStream:NetStream = new NetStream(netConn);
December 10th, 2007 at 10:49 am
It is was so much easier in Director i just don’t get why Flash is so complicated it calls it self a multimedia platform but you cant even control a video file and one that they created them self FLV why not embed a meta tag to tell flash when the video is completed like in quicktime and director.
Just dont get macromedia for developing such a stupid way of showing video
December 10th, 2007 at 10:50 am
Example in director
if movie.duration => movie.length then goto frame 5
thats it
so simple
December 10th, 2007 at 10:59 am
Russ,
There are plenty of differences between Flash and Director — not the least of which being that Flash output is mainly intended for Web, while Director is intended for disc delivery — and of course, Director is much older than Flash, which means it’s had longer to work out its kinks.
That’s entirely possible with Flash. In fact, it’s metadata that allows for the
durationvariable to take hold in some of the above suggestions. But I hear what you’re saying. Certain things truly are easier in Director, and some things truly are easier in Flash. The important thing, I think, is whether or not they’re possible.December 14th, 2007 at 11:07 am
Brett,
Woops! Sorry, I missed your comment before Russ’s.
Yeah, that’s odd. The name of your
NetStreaminstance really shouldn’t matter (as long as you’re using a valid variable name, which you are).In a case like this, where the error simply seems baffling, I recommend you try to re-create the issue in a new, otherwise empty FLA. Bring it down to a bare bones scenario and get the most basic setup to to its thing. Often (for me, anyway), this sort of isolation brings useful insights to light.
December 20th, 2007 at 7:29 am
Hi David,
Just to follow up on this, I was having problems with is on pc while on a mac it was all fine. Now that I have replaced:
if (this.time > 0.5 && this.time >= (duration - 0.5)) {
with:
if (evt.code == “NetStream.Play.Stop”) {
Seems to work perfectly now on both mac and pc. Hooray!!
Thanks again, Neal
December 20th, 2007 at 10:20 am
Neal,
Thanks for sharing this. I’ve been hesitant to suggest the
NetStreamevent code approach because of comments I’ve seen on other blogs — and unfortunately I didn’t make notes on those comments, so I don’t even remember which blogs had them. Hearing enough success stories like yours will encourage me to update this article.December 21st, 2007 at 4:37 pm
David,
I have searched for a couple days trying to find out how you load and loop multiple external flvs with a single video component. I know this can be done, I just don’t know how to do it. If anyone could shed some light–that would be nice.
December 29th, 2007 at 5:33 pm
Hi,
I have a problem when using the FLVPlayback component and the code below:
[code]import mx.video.*;
videoPlayer.contentPath = videoUrl;
var listenerObject:Object = new Object();
listenerObject.complete = function(eventObject:Object):Void {
if (videoPlayer.contentPath == videoUrl) {
trace(”done”);
}
};
videoPlayer.addEventListener(”complete”,listenerObject);[/code]
In that if someone pauses, rewinds or moves the timeline / interferes in anyway the action doesnt fire when the video completes… Is there anyway around this? Because at the moment im stuck using a player with no control.
Thanks in advance,
Chris
December 30th, 2007 at 5:54 pm
Scratch that, am now using the netstream approach, thanks
December 30th, 2007 at 8:09 pm
To Michelle …
Take a look at “How to Play Flash Video (FLV) Files Sequentially” and let me know if that does it for you.
To Chris …
Off the top of my head, I can’t imagine why user interaction would interfere with the
FLVPlayback.completeevent, but I’m certainly glad you found a solution that works for you!January 18th, 2008 at 10:17 am
Hello,
Your tutorials have helped me so much- thanks for them.
I’ve built an flv player that uses xml and a combo box to choose which flv the user wishes to view.
Everything works fine, except that the knob does not return to the beginning of the track once the flv has reached the end. I’ve read and tried everything I can see on your blogs, but being new at this, I just can’t figure out how to fix this. Please show me what to do to make my code work. Thanks in advance:
var duration:Number = 0;
var ratio:Number = 0;
var idTracking:Number = 0;
var idLoading:Number = 0;
// Net Connection
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
myVideo.attachVideo(ns);
ns.setBufferTime (3);
//ns.play(”externalVideo.flv”); replaced by line 146
//can use to play single file then comment out ns.play below
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;
}
};
// controls the draggable slider
function updateKnob():Void {
knob._x = track._x + ns.time * ratio;
newBarMC._width = knob._x - track._x;
}
knob.onPress = function():Void {
clearInterval(idTracking);
ns.pause(true);
this.onMouseMove = function():Void {
if (track._xmouse > 0 && track._xmouse = 98) {
loader._xscale = 100;
clearInterval(idLoading);
}
}
track.onRelease = function():Void {
if (this._xmouse > 0 && this._xmouse
January 22nd, 2008 at 7:23 pm
Hi David,
Further to Damiano’s post on September 12th, 2007…
I have used your script from How to Build an FLV Progress Bar (Part 2), and have left the trace(”Video complete”) line in. I am using this method to determine the end of a single flv stream upon which a movie appears on screen which, on clicking, starts the netstream again through seek (0) and ns.play.
This all works fine on the first loop - upon completion the “Video complete” output is generated, the movie appears and on clicking, the flv starts again. On subsequent loops however, the end event is not triggered, hence no popup if the flv is watched 2 or more times.
Any suggestions?
January 23rd, 2008 at 8:46 pm
lookitsdave,
Probably time to look under the hood.
In my suggested code, everything hinges on that
onStatusevent handler. I would start puttingtrace()statements in there to a) make sure it’s firing at all after the first play and b) find out what the values forthis.timeanddurationare.January 24th, 2008 at 2:41 pm
Hi again, Dave,
Short and Sweet:
Thanks for the additional info in your last message. I understood enough to know that I am NOT using the FLV player. Therefore, after reading more on your notes on “How to Determine the Completion of a Flash Movie,” I realize I should be using this script:
var duration:Number = 0;
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
videoPlayer.attachVideo(ns);
ns.play(”myVideo.flv”);
ns.onMetaData = function(evt:Object):Void {
duration = evt.duration;
};
ns.onStatus = function(evt:Object):Void {
if (this.time > 0 && this.time >= duration) {
trace(”Video complete”)
delete this.onStatus;
}
}
My question now is: Where do I interject the “gotoAndPlay (Scene, frame)” script to get the results I want?
Also…I’m really not sure why my original script worked for the one movie I mentioned since I’m not using the FLV player. But that’s probably moot at this point.
Thanks in advance,
Robert
January 27th, 2008 at 9:02 pm
To Kate …
Thanks for sending me your code via email!
Now I can see what’s going on. Here’s my take on it. If you want the knob to return to its starting point at the end of the video — at least, in this scenario — you’ll have to send it there yourself. The end of the video is “caught” in that
onStatusevent handler, so you could update it like this:… which places
knobat its original position againsttrack.Now, here’s a bit more, and it’s important. Notice the
deleteline in this same handler? Once thatdeleteexecutes, theonStatusfunction is removed. It’s simply gone. That means that the next video to be played through the sameNetStreaminstance (ns), no longer has the benefit of it. You’ll want to update your handler like this:The only difference, really, is that the function is now a named function, which goes by the arbitrary name
statusHandler(). Why is this important? By giving the function a name, you can refer to it more easily down the line. You’ll want your ComboBox to be able to re-assign this event handler when it tellsNetStreamwhat new FLV to play:See the re-assignment after that
ns.play()line?Finally, when playing more than one video, you’ll want to update the
onStatushandler altogether by adding one final element to the condition inside thatifstatement. See “How to Play Flash Video (FLV) Files Sequentially” for details on a “ready” Boolean variable.To Robert …
Agreed. I’m not sure why your earlier script (in comments of another post) worked either, but stranger things have happened.
Sometimes it really is okay to just roll with what’s working now.
I should point out that my suggestion of comparing time against duration isn’t the only way to go. If I remember right, your other post used the
infoproperty of theNetStream.onStatusevent — that’s a different approach, and many people have success with it. In the above snippet, thetrace()function is your give-away: that’s where the end of the video is found, so you could replace this line …trace("Video complete");… with your
gotoAndPlay()statement. If you wanted to keep thetrace()statement for testing purposes (it only shows in the Output panel in Flash), you could putgotoAndPlay()immediately below that.February 5th, 2008 at 12:45 pm
David ::
Fantastic blog you have, this is the first time I have ever seen it and will definitely be subscribing to your RSS.
My question is, is there any reason the “complete” listener would trigger with one set of videos, but fail to trigger with another set of videos? I have a video player that loads up a playlist from a database & plays the videos sequentially. All of the functionality to play them one after another is implemented, and when I tested it with a set of FLV’s that I typically use for testing it worked perfectly. Yet when I put in the actual set of FLV’s that will be used when the player goes live the “complete” listener fails to trigger.
Any insight would be appreciated. And again, great job providing people with a fantastic resource!
February 6th, 2008 at 8:56 pm
Brandon,
What you’re seeing can be the result of improperly encoded FLVs, or simply FLVs that were encoded without metadata. If you’re on a Windows machine, you can download FLV MetaData Injector, by Manitu Group, and see if that will help. It’s a freeware app that adds metadata to FLV files.
February 28th, 2008 at 12:31 pm
How about if, instead of having the url hardcoded in the contentPath of the paramaters property inspector, you’re using actionscript to determine the URL? (i.e. via nc.connect(”rtmp://flash.myserver.net/myvideo.flv”); )
Your code isn’t working for me, and I can only assume it’s because I don’t have the content path hard coded in the property inspector.
Great blog, by the way!
February 28th, 2008 at 12:39 pm
mrwizzer,
Hrm … hard coding or not shouldn’t make a difference, actually. If you’re using
nc.connect(), that tells me you’re using a Video object, rather than the FLVPlayback component. If you’re not using a component, you’ll have to employ something like the code suggested under the “Another answer, short and sweet” heading. Does that work for you?March 18th, 2008 at 9:27 am
Hi David!
First of all, wonderful blog. As a teacher, it is wonderful to find that someone has managed to combine so many skills together with such a pleasant and patient delivery style!
I am trying to teach myself Actionscript, and have put together a couple of decent little apps to help teach number sense to pre-kindergarten students. So far, I am finding the learning curve to be a bit steep! I am reading Essential Actionscript, but must have been through the first 50 pages about 10 times now. Sometimes I think that trying to figure out what the book is teaching me, while at the same time creating with the Adobe authoring tool can be confusing.
For example, in reading about packages, it seems rather clear until I go to the authoring tool and don’t seem to have a need for packages… so it is difficult for me to “see” or “explore with” what the book is trying to teach me.
Well, I’ve gone on long enough now… I actually have a QUESTION here!
1. I have an instance of FLVPlayback on the stage. However, I don’t want this to be played until the student has earned it as a reward. So I issued
videoPlayer.stop();
videoPlayer.visible=false;
What I can’t figure out is why, in function which is called later, the
videoPlayer.play();
videoPlayer.visible=true;
shows the video, but does not play it. It just sits at its first frame.
2. The article to which I am replying is for AS2. Do you have code to determine that FLVPlayback has completed for AS3?
Thank you for putting up with my rambling, and my lack of much AS knowledge.
March 19th, 2008 at 12:35 pm
I seem to have solved one video problem, and perhaps introduced another.
videoPlayer.load(”videoClip”);
and
videoPlayer.play(”videoClip”);
are working fine. But the output screen shows this error: Error #2044: Unhandled IOErrorEvent:. text=Error #2032: Stream Error.
at MethodInfo-610()
How do I add an IOError listener to the FLVPlayback? Assuming that is what I need to do…
March 19th, 2008 at 8:12 pm
Back again! Solved the Stream Error… seems it was related to a sound file. So the video is working perfectly. Hooray!
March 22nd, 2008 at 9:09 pm
Dave, once again, your advice was spot on! Nobody else (including Adobe Live Docs) gave me anything that worked.
April 3rd, 2008 at 11:03 pm
To Chris …
Ah, wow, glad to hear that! I’ve been so behind in blog replies lately … I was just getting ready to start thinking about your questions, but then I saw that you found the solution yourself! Kudos!
To tunghoy …
Thanks!
April 10th, 2008 at 8:00 am
I just want to thank you David for taking the time to make this blog and making it what it is…It is so great and has helped me so much.
So I wanted to give you a very appreciated “Thank You!”
Joe
April 10th, 2008 at 9:07 am
Joe,
Glad to hear that. Thanks!
April 22nd, 2008 at 6:47 pm
this saved me. I’ve been trying to figure this out for a week. Thank you so much!!!!
April 24th, 2008 at 3:23 pm
jerrspud,
Rockin’!
May 3rd, 2008 at 8:03 am
I’ve been having a slight problem with flv video.
When I load in video externally with actionscript (there is an Embedded Video object on stage named theVideo and the actionscript is calling in video dynamically) - the video loads and plays fine to the end. But when I hit Stop on the controls half way through the video and then hit Play again, the video starts back at the beginning like it should but immediately before it restarts, the last frame that it played before I clicked stop flickers on screen briefly. It is more prominent with videos that have black backgrounds it seems. Anyone else had this issue?
Thanks
Dean
deanphillips2005@hotmail.co.uk
May 14th, 2008 at 9:53 pm
Dean,
I can’t say I’ve never seen that — but that’s only because it doesn’t sound especially familiar to me. I’m curious, too, if anyone else has seen this (or at least, has seen it often enough to reliably reproduce it). Maybe what you’re seeing is related to framerate, as well as background color?
May 18th, 2008 at 6:48 am
Dear David,
Thank you very much, i’ve been working this out for the whole day since this morning when i realise that my FTP server does not support FLV. And google brought me here, and you’ve save my life!
Now, it works!
Thanks,
jeep
May 19th, 2008 at 2:29 am
Hi there,
I both understand and know how to use the FLVplayback component and the MetConnection and NetStream ActionScript, but what I cannot figure out is how I can play more than one .flv video file. What I want to be able to do is have three .flv videos in a directory, named say:
video1.flv
video2.flv
video3.flv
Each time I convert a ivdeo into the .flv video format and name it one of the above names, I want to be able to place it into the desired directory and have it overwrite the old .flv video file and playback in iether the FLVplayback component or useing the NetConeection and NetStream ActionScript.
Thanks in advance, Nicholas.
May 19th, 2008 at 4:00 pm
To jeep …
Glad to hear that!
To Nicholas …
What you describe — overwriting FLV files on a server — isn’t something Flash Player can do (and I figure you know that), but by all means, the idea is a good one. You can certainly upload and overwrite existing files with an FTP client. As long as they’re named the same thing (here, always video1.flv, video2.flv, and video3.flv), Flash Player will simply load the newest ones. Just reference those files names in your code. What’s your question?
May 21st, 2008 at 10:01 pm
Hi David, thanks for that post.
I have managed to acomplish what I was after. Although, now I have run into a new problem.
I have created an FLVplayback component which loads .flv video files externaly, given the .flv is named one of the selected names in the array below.
Here is the ActionScript I have used thus far:
var videoList:Array = new Array();
videoList[0] = “video1.flv”;
videoList[1] = “video2.flv”;
videoList[2] = “video3.flv”;
videoList[3] = “video4.flv”;
var currentlyPlaying = 0;
videoPlayer.contentPath = videoList[currentlyPlaying];
videoPlayer.play();
videoPlayer.bufferingBar = bufferClip;
trace(currentlyPlaying);
var listenerObject:Object = new Object();
listenerObject.complete = function(eventObject:Object):Void {
currentlyPlaying++;
if (currentlyPlaying >= videoList.length) {
currentlyPlaying = 0;
}
trace(currentlyPlaying);
videoPlayer.contentPath = videoList[currentlyPlaying];
videoPlayer.play();
};
videoPlayer.addEventListener(”complete”, listenerObject);
If one of the .flv video files is missing from the directory the FLVplayback will continue to buffer and look for the missing .flv video file rather than continue to the next .flv video file.
Would you David or anyone out there possibly know the solution to this problem?
Many thanks, Nicholas.
June 2nd, 2008 at 7:29 am
Anyone out there??
:P
Nicholas.
June 2nd, 2008 at 10:51 am
Nicholas,
Times are a bit tight lately. I’m working on two books at the moment, and it’s taking quite a toll.
What you need, here, is a way to determine when an FLV load has gone bad. The AS2
FLVPlaybackclass features astateChangeevent that lets you know when the component starts playing, pausing, rewinding, and so on — and it even includes info on connection errors, such as when an FLV file is not present.Continuing on with your variable naming convention, consider the following new event handler:
When a video fails to load, you’ll see “connectionError” in the Output panel. Instead, you may want to increment
currentlyPlayingand update thecontentPathproperty again. That would skip to the next video. Or you could handle that particular sort of status change event in some other way.June 4th, 2008 at 4:23 am
Hi Dave,
Thank you very much!
Although, as good as you are at Flash I am unfortunately not.
With the above ActionScript you gave me, Do I replace the old script or simlply add it?
In regards to the updating of the currentlyPlaying and contentPath, I dont quite understand…
By any chance are your two books based on Flash? Because I would realy love to have a copy of my own!! Hope all goes well.
Thanks, Nick
June 4th, 2008 at 12:20 pm
Nicholas,
In the code you pasted, you already have a
completehandler present:That event handler references
currentlyPlayingandcontentPath, and I’m proposing that you add a second event handler that does the same thing for a video that fails to load. Your second event handler would presumably do the same thing — to an extent. ThestateChangeevent handler should probably not loopcurrentlyPlayingto the beginning again, because that loop would repeat forever in the off-chance that none of the video files are present.So … you’ll continue to have your
completehandler, but you’ll also add astateChangehandler:June 4th, 2008 at 6:49 pm
OK David,
I completely understand now. Except, if “video4.flv” is missing from the directory the videoPlayer continues to buffer. Rather than skip to the first video and start over.
The videoPlayer works and skips to the next .flv file, it is only when the last .flv is missing that it does not skip to the first .flv and start over.
Thank you very much for contribution thus far!
Nick.
July 19th, 2008 at 9:51 pm
Hello. I think you are eactly thinking like Sukrat. I really loved the post.
August 18th, 2008 at 2:02 pm
David,
Thank you for pointing me to your blog site. I’ve read the tutorials on working with cue points in Flash and understand this topic so much better. I finally understand how Flash recognizes cue points with specific names.
I also understand your tutorial on how to determine when video reaches completion using onMetadata and onStatus. Taking this a step forward, how do I tell the video to return to the beginning AND STOP once the video reaches the end or the stop button is pressed? I’ve tried using ns.seek(0), but this statement returns the video to the beginning and starts playing again.
Thanks for all your help.
October 8th, 2008 at 5:46 am
Hi david,
I just want to get video complete message for a embedded video in a time line OR the meachanisim we need to use for getting the video playback complete message
Pls send the code to my e-mail