AS3 FLVPlayback occasionally stuck in buffering on launch - actionscript-3

I've got a Flash CS6 FLA with an instance of the FLVPlayback component (2.5.0.26) and an instance of the Progress Bar component on the stage, loading an external FLV.
I'm trying to preload a specific percentage of video before playing.
When hosted on a server, the video launches and plays as expected 80% of the time, but 20% of the time the video gets stuck in a buffering state on launch (blank area where video should be), and I can't get it to play through AS3 or by clicking the play button on the skin controls. Oddly, if I refresh the browser when it's stuck I see a glimpse of the video before the page reloads and then plays the video as expected.
I've tested on a Mac (Lion) in Chrome, Firefox, and Safari and had the same results.
The video problem gets worse if I limit my bandwidth using SpeedLimit.
Any suggestions would be greatly appreciated.
Code:
public class SimpleVideoLoad extends MovieClip {
var isLoaded:Boolean = false;
public function SimpleVideoLoad() {
// constructor code
loadVideo();
}
function loadVideo():void
{
my_FLVPlybk.x = 0;
my_FLVPlybk.y = 0;
my_FLVPlybk.width = 743;
my_FLVPlybk.height = 300;
my_FLVPlybk.source = "CARSdotCOM_OLD.flv";
//preloader component
pb.source = my_FLVPlybk;
pb.addEventListener(ProgressEvent.PROGRESS, progressHandlerPB);
}
//progress bar component
function progressHandlerPB(event:ProgressEvent):void {
var percentOfVideoLoaded = pb.percentComplete;
if (percentOfVideoLoaded>10 && isLoaded == false){
isLoaded = true;
my_FLVPlybk.play();
}
}
}

Related

Save and Load current frame in Actionscript 3 (Adobe Flash AIR)

I have an interactive flash application Actionscript 3 to be deployed in Android device (thru Adobe Air). There will be a Save button (btnSave) that will save current progress of a user eventhough he closes the app or another will use it. There's also a Load button (btnLoad) to load the progress of the user. This is my code and I can't make it work. Thanks!
var mySharedObject:SharedObject = SharedObject.getLocal(“save”);
btnSave.addEventListener(MouseEvent.CLICK, saveCurrentFrame);
function saveCurrentFrame(event:MouseEvent):void
{
mySharedObject.data.lastframe= this.currentFrame;
mySharedObject.flush();
}
btnLoad.addEventListener(MouseEvent.CLICK, getLastFrame);
function getLastFrame():int
{
return mySharedObject.data.lastframe;
}
You need not only to read the saved last frame, but to move the playhead to it as well.
var mySharedObject:SharedObject = SharedObject.getLocal("save");
btnSave.addEventListener(MouseEvent.CLICK, saveCurrentFrame);
btnLoad.addEventListener(MouseEvent.CLICK, getLastFrame);
function saveCurrentFrame(event:MouseEvent):void
{
mySharedObject.data.lastframe = currentFrame;
mySharedObject.flush();
}
function getLastFrame(event:MouseEvent):void
{
if (mySharedObject.data.lastframe != null)
{
gotoAndStop(mySharedObject.data.lastframe);
}
}

How to Improve FLVPlayback - Reduce Choppy Video

I have a 1920x1080 video playing inside a flash project with the same dimensions, using Firefox. The project is using CC2015, Latest Flash Player, Latest FF. I should note that this project is using locally stored videos.
I'm using AS3, FLVPlayback component, and the videos have been compressed (by production).
Heres the code that uses the playback component
function playVideoByString(source: String): void {
hideTheButtons();
attractTimer.stop();
movie_container = new MovieClip();
addChild(movie_container);
movie_container.x = 0;
movie_container.y = 0;
launchVideo(movie_container, source);
}
function launchVideo(vBox, vFile): void {
attractTimer.stop();
flvPlayer = new FLVPlayback();
flvPlayer.source = vFile;
flvPlayer.skinAutoHide = true;
flvPlayer.skinBackgroundColor = 0x000000;
flvPlayer.width = 1920;
flvPlayer.height = 1080;
flvPlayer.autoRewind = false;
cuePt.time = 0.9;
cuePt.name = "ASpt1";
cuePt.type = "actionscript";
flvPlayer.addASCuePoint(cuePt);
vBox.addChild(flvPlayer);
// adding listeners in here
flvPlayer.addEventListener(MetadataEvent.CUE_POINT, cp_listener);
flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
}
Playback is experiencing some degradation in the form of what looks like frames dropping, or "stutter." The animations look glass smooth when the MP4 is opened in Firefox and played back using FFs player. They also look fine when played in QuickTime (obviously). The video is 30FPS, as is the Flash Project, though from what I understand, FLVPlayback will use the videos encoded frame rate regardless of Flash's FPS.
Is there anything I can do to improve the video playback, and possibly smooth the videos out without loosing quality?

AS3 Preloader doesn't work locally, loaderInfo ProgressEvent.PROGRESS event does not fire

Making a custom AS3 preloader, I noticed that when my SWF is executed locally (file:///) the preloader gets stuck in the loading screen when previewed in a web browser like Chrome.
When executed from a remote server or through the standalone Flash Player, then it works. I noticed other SWF that have preloaders do not have this issue. What I need to change?
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, preloaderProgress);
function preloaderProgress(event:ProgressEvent):void {
var loadedPercent:Number = event.bytesLoaded/event.bytesTotal*100;
if (loadedPercent == 100){
this.gotoAndStop(2);
}
}
Loading locally goes very fast. Not only you should check if the file is completely loaded using the Event.COMPLETE and not the ProgessEvent but you should also make sure to register your listeners before actually calling load or the file might end up completely loaded before you register your listeners.
Following the example at http://stephenscholtz.com/201110/single-movie-flash-preloading-as3
It seems that there was no ProgressEvent.COMPLETE, but there is a Event.COMPLETE instead, a bit confusing.
I changed my code to the following, (also including some tweaks for right click menu to prohibit the user from right clicking and pressing Play before movie has loaded and such)
//Initialize any variables
var loadedPercent:Number = 0;
//Remove all items from right click Flash Player menu (except Quality, and the mandatory About... & Settings...)
var cxMenu:ContextMenu = new ContextMenu();
cxMenu.hideBuiltInItems();
cxMenu.builtInItems.quality = true;
this.contextMenu = cxMenu;
/* or disable right click menu completely (Flash Player 11.2.202.228 and over) */
/* this.addEventListener(MouseEvent.RIGHT_CLICK, onMouseRightClick);
function onMouseRightClick(event:MouseEvent)
{
return false;
} */
//Disable shortcut keys and window menubar when played from desktop Standalone Flash Player app
if (Capabilities.playerType == "StandAlone" || Capabilities.playerType == "External") {
fscommand("showmenu", "false");
fscommand("trapallkeys", "true");
}
/* Preloader: begin */
//Update loading bar and percent text as SWF loads
function onProgress(e:Event) {
//Get the amount of bytes that have been loaded / bytes total to load
loadedPercent = this.loaderInfo.bytesLoaded/this.loaderInfo.bytesTotal*100;
//Update the text of _preloaderProgress movieclip
_preloaderProgress.text = int(loadedPercent)+"%";
//Update the _preloaderBar amount by scaling horizontally as it loads
_preloaderBar.scaleX = loadedPercent/100;
}
//Go to next frame after everything loads
function init(e:Event) {
gotoAndStop(2);
}
//Attach the events to the stage
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
this.loaderInfo.addEventListener(Event.COMPLETE, init);
/* Preloader: end */
//Stop to 1st frame and wait until it is loaded
stop();
This will allow the movie to play both remotely and locally with no problems.

How to loop FLV seamlessly

I am playing looped FLVs in the "standard way":
netstream.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
...
public function onStatus(item:Object):void {
if (item.info.code == "NetStream.Play.Stop") {
if (loop) netstream.seek(0);
}
When played through Flash CS 5.5 authoring tool (Test Movie or Debug Movie), the videos loop seamlessly. But! When played in the browser or standalone debug Flash player (both v.11.2.202.233) there is an abnormal pause of about 1 sec before the video "rewinds".
Is this a bug with the latest Flash player?
For People who have the same issue, try changing the aforementioned code to this:
public function onStatus(item:Object):void {
if (item.info.code == "NetStream.Buffer.Empty") {
if (loop) netstream.seek(0);
}
It will get rid of the flicker. If you listen to "NetStream.Play.Stop", it will cause a flicker.
You don't need to embed anything. This works just fine on IOS, Android and PC.
This is a known bug with Flash Player 11+ and AIR 3+. Bug report is here, and you should upvote & : https://bugbase.adobe.com/index.cfm?event=bug&id=3349340
Known workarounds that will create a seamless loop:
1) Embed the video in the SWF. Not ideal, and not possible in some cases.
2) Create dual NetSteam objects and switch between them. An example of the event fired when ns1, the first of two NetStreams objects, reaches it's end:
if (e.info.code == "NetStream.Play.Stop"){
vid.attachNetStream(ns2);
ns2.resume();
activeNs = ns2;
ns1.seek(0);
ns1.pause();
}
Replace ns1 with ns2 on the other event listener. A useless duplication of objects and handlers, but there you go.
3) Use AIR 2.x / Flash Player 10.x (not really a solution at all, except for Linux users)
We noticed this on the transition from Flash 10 to to Flash 11. Flash 10 loops seamlessly, but Flash 11 has a ~1 second stall when calling seek(0) from NetStream.Play.Stop.
Embedding the media in the SWF is not an option for us.
The following code provides a more seamless loop - still not perfect, but much better.
var mStream:NetStream;
var mDuration:Number;
...
addEventListener(Event.ENTER_FRAME, onEnterFrame);
...
function onEnterFrame(e:Event):void
{
if( mStream.time > (mDuration-0.05) )
{
if( mLooping )
{
mStream.seek(0);
}
}
}
function onMetaData(info:Object)
{
mDuration = info.duration;
}
Hope it helps.
I seem to have achieved this using an FLVPlayback component along with a few tips.
What's more, it's running seamlessly on desktop, iPhone 4S and 3GS! (via an AIR app)
_videoFLV = new FLVPlayback();
_videoFLV.fullScreenTakeOver = false;
_videoFLV.autoPlay = false;
_videoFLV.autoRewind = true;
_videoFLV.isLive = false;
_videoFLV.skin = null;
_videoFLV.y = 150;
_videoFLV.bufferTime = .1;
_videoFLV.width = 320;
_videoFLV.height = 320;
_videoFLV.addEventListener(MetadataEvent.CUE_POINT, video_cp_listener, false, 0, true);
_videoFLV.source = "includes/10sec.flv";
addChild(_videoFLV);
With the listener function...
function video_cp_listener(eventObject:MetadataEvent):void {
if (eventObject.info.name == "endpoint") {
_videoFLV.seek(0);
_videoFLV.play();
}
}
Importantly I think you must set the width and height to match your flv file. i.e. no scaling whatsoever.
The flv has a cue point named 'endpoint' added 1 frame before the end of the file (assuming your start and end frame are the same this will be required).I added this using Adobe Media Encoder.
The only way to loop an flv seamlessly is to embed inside the swf. It is converted to a MovieClip and you then handle it with play(), stop(), nextFrame(), prevFrame() etc.
When embedding in Flash Authoring tool (dragging flv file on stage), make sure that you select:
"Embed FLV in SWF..."
Symbol Type : "Movie clip"
All checked : "Place instance on stage", "Expand timeline...", "Include audio"

AS2 Gallery swf loaded into Main web AS3 swf

I've loaded a AS2 swf into a AS3 swf but the onLoadInit function for a MovieClipLoader object isn't executing; which leaves my images not centered and not reduced in dimensions (width/height)
It works if i run the AS2 swf (gallery) directly.
listenerObj.onLoadInit = function (target:MovieClip) {
if (target._height > _root.maxHeight)
{
var ratio = target._height / _root.maxHeight;
target._height = target._height/ratio;
target._width = target._width/ratio;
}
if (target_mc._width > _root.maxWidth)
{
var ratio = target._width / _root.maxWidth;
target._height = target._height/ratio;
target._width = target._width/ratio;
}
target._x = ((Stage.width/2)-(target._width/2));
target._y = ((Stage.height/2)-(target._height/2));
}
MCL.addListener(listenerObj);
There are unfortunately some subtle differences in behavior and bugs when loading an AS2 movie in AS3. I also experience the behavior you're seeing--none of the load handlers work on the listener when the movie is loaded in AS3. There are some strange issues when loading AVM1 movies, particularly when nesting loads.
Perhaps the best you can do is to look onEnterFrame to poll for when the clips are loaded. One way is to watch for _width != 0. This should happen once the clip has loaded. Then you can initialize the position:
function onEnterFrame()
{
if(target._width)
{
// your positioning+init code here
onEnterFrame = null;
}
}