Copy link to clipboard
Copied
Hi,
Back in 2009 I created seamless video loops using the FLVPlayback component and 'addEventListener' (as3)—and they worked great! looping round and round seamlessly—equally well in browsers as in flash. The videos were of varying lengths, small (all between 50—500K), and they looped perfectly.
Recently I've gone back to update things and noticed that my video loops are no longer seamlessly looping in any of the web browsers. Now there's a big pause interrupting the seamless flow.
??? why? Has something in the delivery (browsers/flashplayer) changed? All my video loops still run seamlessly when tested in Flash (CS5). I spent a good amount of time investigating various angles but could not find any solution.
Anyhow, here's the actionscript:
stop();
import fl.video.*;
toggleButton.addEventListener(MouseEvent.MOUSE_OVER, rolloverToggle);
toggleButton.addEventListener(MouseEvent.MOUSE_OUT, rolloutToggle);
toggleButton.addEventListener(MouseEvent.CLICK, toggleClick);
toggleButton.buttonState = "off";
function rolloverToggle(event:MouseEvent):void {
toggleButton.gotoAndStop(toggleButton.buttonState+" over");
}
function rolloutToggle(event:MouseEvent) {
toggleButton.gotoAndStop(toggleButton.buttonState);
}
function toggleClick(event:MouseEvent):void {
if (toggleButton.buttonState == "on") {
toggleButton.buttonState = "off";
vid_16_monty.pause();
}else {
toggleButton.buttonState = "on";
vid_16_monty.play();
vid_16_monty.addEventListener(VideoEvent.COMPLETE, rewind);
function rewind(event:VideoEvent) {
vid_16_monty.play();
}
}
toggleButton.gotoAndStop(toggleButton.buttonState+" over");
}
the video that goes with the above script can be viewed here: http://www.designfail.us cat should be in seamless motion... but it's not.
Also, not sure it would make much difference, but I'd be happy to attach an fla file—Adobe says it's a good idea but nowhere do they tell you how to attach an fla file... very peculiar, especially in these emphatic UI/UX times we live in.
Copy link to clipboard
Copied
You're welcome and here's a link to the bugbase:
Copy link to clipboard
Copied
bug report, Adobe Flash Player 11.0 - Bug 3349340 -
is here:
https://bugbase.adobe.com/index.cfm?event=bug&id=3349340
it's an election year, so go vote!
Copy link to clipboard
Copied
Hey folks!
I finally found a workaround for this issue after some time of trying... Simply embed a Cuepoint to the very end of the FLV and listen to that instead of the EndOfStream- / Complete-Event.
(Unfortunately you cannot use "addASCuePoint" (or a similar method) with the netstream object)
Here is the Code:
var customClient : Object = new Object();
customClient.onCuePoint = function(infoObject : Object):void {
trace("Found CuePoint. Resetting video to start...")
ns.seek(0);
ns.play();
};
ns.client = customClient;
Works fine for me. I hope this is helpful for you!
Best wishes!
Message was edited by: caa_sion
Copy link to clipboard
Copied
Didn't work for me, in fact there's just some really weird cuePoint action going on in my testing.
I made a really ugly 3.0 second long video and made 2 FLVs from it. One with an embedded cue point at 3.0 seconds like you mentioned and the other has no cue points. I'm rotating a circle colored via the standard rainbow gradient so loop studders would be more obvious. I'm also moving a line up and down the screen with no easing as that's another thing that's easy to see loops failing on.
I tested the 3 methods, using the traditional STOP event, using an embedded cue like mentioned and also using FLVPlayback to insert a cuepoint. When testing locally I'm not having any issue continuously (and quickly) looping using all 3 methods. Most notably (actually) the STOP and FLVPlayback method are the smoothest.
However when I upload and test it in a browser it stops working. Perhaps because I have FP debuggers installed in my browser.
What I see is the original STOP method continuously loops but you get that 1 second lag between loops (as we knew).
When I embed a cue point and try to loop on that I'm getting a video that is hitting the cue point early (like 1 second) instead of where the cue is placed.
The FLVPlayback AS3 cue point works well for the first loop but on every second loop it has a delay.
I have a limitedly useful TextField just giving information like when a cue is hit, what the .time property is. It's useful to see the embedded cue is set at 2.999etc but is firing off completely wrong.
Live example:
http://www.ertp.com/tmp/vidlooptest/ (FP11.5 needed)
Click any button to try that test. When a different button is called I clean up and then start again. I don't believe I missed any cleaning up so the results should be accurate.
CS5.5 FLA Source w/ vids:
http://www.ertp.com/tmp/vidlooptest/VideoLoopTest.zip
Here's just the frame script for reference:
It's a pretty simple, straight forward test. Any code blunders in there?
Copy link to clipboard
Copied
I have to admit that I was a little hasty with my comment. Sorry.
Thanks for uploading your example sinious! I did not find any blunders after the first look.
I hope I find time to take a closer look at it today.
In fact the looping with an embeded CuePoint works only sometimes. It seems to be the "NetStream.Seek.Complete"-Event that cause the problems.
My sequence:
Can you reproduce that too?
Copy link to clipboard
Copied
I don't see the NetStream.Seek.Complete event at all. I see a NetStream.Seek.Notify as soon as the cue hits but no "Complete" event. I don't even see that event in documentation:
I did a quick search on it and found one post asking what that event was because they got it and they couldn't find documentation on it. Oh the fun .
Show me your event handler code.
Copy link to clipboard
Copied
I am wondering too, now that you mentioned it
Here´s my EventHandler-Code:
unit.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); private function netStatusHandler(event:NetStatusEvent):void {
switch (event.info.code) {
case "NetConnection.Connect.Success":
break;
case "NetStream.Play.Start":
if(!inited) {
inited = true;
NetStreamWrapper(unit.Stream).path = path;
width = video.videoWidth;
height = video.videoHeight;
log.info(Path+": Size of video: "+video.videoWidth+" "+video.videoHeight);
CalculateMemory();
}
break;
case "NetStream.Buffer.Full":
if (!initializedStream) {
log.info(Path+": Pausing and rewinding stream: "+unit.Stream.time);
log.info(Path+": Size of video: "+video.videoWidth+" "+video.videoHeight);
unit.Stream.pause();
//NetStreamWrapper(unit.Stream).initialized = false;
initializedStream = true;
if(unit.Stream.bytesLoaded == unit.Stream.bytesTotal) {
SetCurrentPreparationLevel(CommittedDesiredPreparationLevel);
}
}
break;
case "NetStream.Seek.Notify":
break;
case "NetStream.Play.Stop":
if(initializedStream) {
dispatchEvent(new AssetEvent(END_OF_STREAM, this));
}
break;
case "NetStream.Play.StreamNotFound":
RaiseError("File for stream not found", event);
break;
case "NetStream.Seek.InvalidTime":
log.warn("Illegal seek(should not happen, but more or less harmless)");
break;
case "NetStream.Seek.Complete":
log.warn("Finished seeking");
break;
default:
if(event.info.level == "error")
RaiseError(event.info.code, event);
break;
}
}
Copy link to clipboard
Copied
I don't use NetStream, I use the FLVPlayback component, which does exactly what we need, and we're able to loop the video; well, I guess it doesn't really loop, it's stops itself, listens for the COMPLETE event, and then reloads itself when completed. It's as close as we need to get when it comes to looping.
function loadVideo(videoSource:String, videoName:String):void
{
video.source = videoSource;
trace("video.source = "+ video.source);
video.addEventListener(VideoEvent.COMPLETE, videoComplete);
video.name = "video";
video.play();
addChild(video);
}
function videoComplete(e:VideoEvent):void
{
var videoObj:DisplayObject = MovieClip(root).getChildByName("video");
if(videoObj != null)
{
removeChild(videoObj);
}
loadVideo(vidoeSource, "video");
}
Not what you're looking for, and probably doesn't offer much insight, just thought maybe it would help someone.
Cheers,
~Chipleh
Copy link to clipboard
Copied
caa_sion~ Weird, I don't get that event at all, but I'm using a tiny 3 second loop. I even played with bufferTime set to 0.01, inBufferSeek, etc and I never get the event (or the loop to be seamless). I'm pretty sure it's just because I use a tiny 3 second video but who would want to wait 1 minute to verify a loop is working .
If it's not documented I'd be weary of it (depreciated at some point?).
Chipleh~ They're trying to achieve flawless looping. Unloading and reloading the whole video won't do that, it'd loop even worse.
You also do use NetStream (FLVPlayback uses it under the hood).
Overall I'm starting to wonder if some binary technique of attaching a byteArray streamed via something besides netStream (like FileStream) and attaching to that might be possible. I haven't even lifted a finger to test it but as for now, we're up the creek.
Timeline embedded video plays flawlessly when looping, for what it's worth . That was my "old days" solution to this issue I always had.
Copy link to clipboard
Copied
Hello again
The previous Bug-Report was closed. So I created a new one.
https://bugbase.adobe.com/index.cfm?event=bug&id=3474727
Now they ask for more Information.
Sinious~ Due my duty of secrecy I cannot send them my original Code (It is pretty geared with stuff I'am not allowed to publish).
Am I allowed to send them your Source Code?
Copy link to clipboard
Copied
Yes of course. It was created as a simple, provable and reusable bug example. Feel free!
Copy link to clipboard
Copied
Thanks. I've attached your code to the bugreport.
Nothing else remains to be done. Stay tuned
Copy link to clipboard
Copied
While reading this interesting thread I stumbled over this
With seamlessLooping considered a High-End Feature for the Flash Media Server (adaptive Streaming)...
Would it be too much to muse that it could be of vital Business-interest for Adobe to remove that Feature artificially from their "Free-for-all-Flashplayer"?
Copy link to clipboard
Copied
Adninja -
There are no duplicate frames in the cat vid. Not a single one. sinious has confirmed it as well. I could post screen shots from the editor, but I really don't want to go there. It's simply distracting, so can we please lay that tangent to rest?
As for the actionscript, you're suggesting that I spend hours and days re-writing my AS3 back to AS2 ? Just because Adobe no longer supports the full functionality of their AS3 components with their new Flash Player? And what happens when the next Flash Player no longer fully supports AS2 ?
I appreciate you looking into this problem Adninja, but I'm really not keen on circumventing problems; it's just an endless can of worms, I'd really prefer to solve them.
Copy link to clipboard
Copied
If you'd like to give me a sample looping video to save me a little time I'll test out StageVideo looping for you. I'm curious on it myself, I just lack the time to whip out AE a the moment. I don't want a FLV/F4V however, I'd need something as lightly compressed as possible so I can encode it to mp4/h.264. Believe me, mp4/h.264 is far, far better then FLV/F4V and it plays natively in HTML5 without flash at all. It's the correct path going forward.
If you can't get me some loop source I can convert a FLV to MP4 but obviously the video rule follows, garbage in, garbage out. I can't guarantee the final keyframe will perfectly match the intro keyframe, but it's probably good enough to test.
I do agree that this issue shouldn't exist. Though it does and I'm just trying to move you forward through the problem. That may require some work.
Copy link to clipboard
Copied
@ sinious - I'll have to do a little digging, but I can get you something. Is ertp a good place to send it to you? I took a look at yr profile but it doesn't look like I can pm you... you can pm me.
Been thinking a lot of HTML5 vid... can't wait for the days of universal delivery method!
Copy link to clipboard
Copied
Another option is to import the video, choosing to embed it as a movieclip. You could load the swf(s) with embedded video/movieclip as needed. Here's an example: http://www.chrismanuel.ca/testing/looptest.html. Since the goal is to loop short clips you won't need to stream anything which circumvents the issues with the netstream class and looping.
Copy link to clipboard
Copied
Hey folks!
Adobe finally reproduced this issue. Now they closed the Bugreport as deferred....
As long as there are no other votes on it, they willnot try to fix this bug.
Please vote for it! Here is the BugReport:
Copy link to clipboard
Copied
Hey Chris.
You´re right. This is a workaround for one or maybe two short streams. But if you want to loop way more videos, you will get in trouble. (Especially if you not only want to loop it, but show other videos according to the loop)
I hope are you following me?
Greetings!
Copy link to clipboard
Copied
I've just hit on this thread, having the same problem.
And I found this solution:
http://tactilejp.blogspot.cz/2012/08/geek-stuff-as3-seamless-video-loop.html
Handling the seek(0) on "NetStream.Buffer.Empty" works for me (playing f4v).
Hope it helps!
Copy link to clipboard
Copied
It really depends on your tolerance using the word "seamless".. I can visually see the studder even seeking on buffer empty. The only way I've ever came close was managing the loop point in such a way it happens where you wouldn't expect it while seeking slightly into the video, e.g. seek(0.1). Otherwise, embedding on a timeline is the only (non AMS-requiring) way to truely be visually seamless.
Copy link to clipboard
Copied
Thanks Robin,
I've implemented the same, and although it's still pausing for a moment (maybe 1/3 sec.), it's at least not blinking off momentarily as it did with FLV Playback.
(2.5 mb, flv with alpha channel "falling snow" loop)
Copy link to clipboard
Copied
I'm going to reply with some code that has worked for a simple loop for me. I'm not as experienced at AS3 as some, but here goes. My videos have a fraction of a second where they are relatively still and I am using that point to make the move, but with some experimenting, it may work elsewhere, and perhaps it could be optimized:
import fl.video.FLVPlayback;
import fl.video.VideoEvent;
myvideo.addEventListener(fl.video.VideoEvent.PLAYHEAD_UPDATE, onPlayhead);
function onPlayhead(event: fl.video.VideoEvent):void {
if (event.playheadTime < 7.75) return; //do nothing until just before 8-second clip ends
myvideo.pause(); //so it won't blink
myvideo.seek(0);
myvideo.play();
}
Essentially, I have an 8 second looping video. PLAYHEAD_UPDATE fires every .25 of a second. So I watch it until it hits about a quarter second before the end of the video (7.75 seconds), and when it does, pause, seek and play again. I think the pause is important to prevent the 'blink' that I was getting. It might require adding a bit of dead space or repeated frames to the end of your clip to work optimally, since I find that once COMPLETE fires, playing back again causes a blink. Speak up if it works / doesn't on your side, I'd like to know.
Meanwhile, I voted on the bugreport too.
Copy link to clipboard
Copied
Keeping away from COMPLETE will be important, you can't stop it internally from its behavior. Also if the video exceeds the in-memory buffer you might not be able to loop so seamlessly (e.g. 60 seconds of video). I found setting a keyframe on the time you wish to jump helps with the flicker as well (easy to set in most encoders).
That said, is this a website? As it's pretty obvious most sites are correcting their old ways of abusing the Flash platform for doing simple things like video playback, you could use a .mp4 in a HTML5 video tag with the loop attribute to seamlessly loop. That's of course if your needs are simple, like a page full of looping videos for sale.
Copy link to clipboard
Copied
No, it's for an iOS app. I had to abandon FLVPlayback, I could not get it to play an mp4 on iOS, though it would play flv's but slowly. I've moved to netstream and stagevideo, which is blazing fast, even with full HD. But stagevideo is competing with my other use of stage3D, so it isn't as simple as I'd like. Here's my stagevideo looping code, I hope it makes sense, I don't have time to nicen it up tonight. There's more to it, but if you set up a video using NetStream and stagevideo, this should work.
function onEnterFrame(e:Event):void
{
var current_time :Number = mynetstream.time;
if (!stream_paused) //my own boolean
{
if( current_time > (video_duration-0.1) ) //almost at the end of the clip
{
mynetstream.pause();
stream_paused = true;
mynetstream.seek(0);
}
}
else
{
if (current_time < 0.1) //i.e. = 0
{
mynetstream.resume();
stream_paused = false;
}
}
}
function onMetaData(mynetstream_data:Object):void
{
video_duration = mynetstream_data.duration;
}
Find more inspiration, events, and resources on the new Adobe Community
Explore Now