NetStream: bufferTime, Buffer.Full not working properly

I hope someone can help with this. Adobe’s documentation states that a netstream object has a bufferTime value, which causes the stream to accumulate buffer prior to playing a hosted .flv file. What I find is that the video starts playing well before the bufferTime value has been accumulated, verified by checking bytesLoaded on enterFrame.

I tried creating an event listener that only adds the video obj when the “NetStream.Buffer.Full” event is thrown, but this does not fix the problem as the video is playing in memory space before being added to the display list. Again, I find that the video is playing well before the “Full” event is thrown.

The only hack I have come up with is to constantly do a seek(0) on the stream before the “Full” buffer event is thrown, but this causes visual problems once the video is ready - sometimes the video will be added to the display list while it is mid-seek and it flickers, esp on slower machines. This hack is pretty ugly.

Any advice is appreciated - has anyone dealt with this problem? My code (minus the seek hack) is below. Note that startVideo() is called by a button.

Thanks
ds

VideoElement:

package codebase.electroland {
    
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.display.Shape;
    
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormatAlign;
    import flash.text.TextFieldType;
    import flash.text.AntiAliasType;
    
    import flash.net.URLRequest;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    
    import flash.events.*;
    
    import codebase.gs.TweenLite;
    import codebase.electroland.utils.ELGfx;
    import codebase.electroland.ProjectNavButton;

    public class VideoElement extends MovieClip {
        
        private var baseURL:String;
        private var flvURL:String;
        private var posterFrameURL:String;
        
        private var video:Video;
        private var nc:NetConnection;
        private var ns:NetStream;
        
        private var posterFrameLoader:Loader;
        private var bg:Sprite;
        private var bigPlayButton:ProjectNavButton;
        private var videoLoadingWarning:ProjectNavButton;
        
        private var bufferPercentage:Number;
        private var percentLoaded:Number;
        
        private var elementWidth:Number = 900;
        private var elementHeight:Number = 560;
        private var vidWidth:Number;
        private var vidHeight:Number;
        private var vidDuration:Number;
        
        public var type:String = "video";
        
        public function VideoElement(flvURL:String,baseURL:String,vidWidth:Number,vidHeight:Number,posterFrameURL:String):void {
            // setup FP params
            this.flvURL = flvURL;
            this.baseURL = baseURL;
            this.vidWidth = vidWidth;
            this.vidHeight = vidHeight;
            if (posterFrameURL != "") {
                this.posterFrameURL = posterFrameURL;
                //trace(posterFrameURL);
            } else {
                trace("VIDEO WARNING: no poster frame for " + flvURL);
            }
            
            //draw a black background, or show the image
            drawBG();
            setupButton();
            
            video = new Video();
            video.width = vidWidth;
            video.height = vidHeight;

            video.deblocking = 3;
        }
        
        
        
        /* ------ VIDEO PLAYBACK FUNCTIONS ------ */
        /* -------------------------------------- */

        
        public function startVideo(e:Event):void {
            trace("DEBUG: starting video");
            
            this.addChild(videoLoadingWarning);
            this.removeChild(bigPlayButton);

            nc = new NetConnection();
            nc.connect(null);
            ns = new NetStream(nc);
            ns.addEventListener(NetStatusEvent.NET_STATUS, onStatusEvent);
            
            bufferPercentage = 50; // % of video loaded before play
            this.addEventListener(Event.ENTER_FRAME, bufferStatus);

            var meta:Object = new Object();
            meta.onMetaData = metaDataHandler;
            ns.client = meta;
            
            function metaDataHandler(meta:Object):void {
                //trace("VIDEO: metadata= " + meta.duration,meta.width,meta.height);
                
                vidDuration = meta.duration;

                ns.bufferTime = vidDuration/bufferPercentage;
                trace("VIDEO BUFFERTIME: " + ns.bufferTime);
            }
            
            video.x = (elementWidth/2) - (video.width/2);
            video.y = (elementHeight/2) - (video.height/2);
            
            video.attachNetStream(ns);
            
            ns.play(baseURL + flvURL);
            
        }
        
        private function onStatusEvent(stat:Object):void {
            //trace("VIDEO NETSTREAM: " + stat.info.code);
            if (stat.info.code == "NetStream.Buffer.Full") {
                
                this.addChild(video);
                this.removeChild(videoLoadingWarning);
                if (posterFrameLoader && bg.contains(posterFrameLoader)) {
                    bg.removeChild(posterFrameLoader);
                }
            }
        }

        private function bufferStatus(e:Event):void {
            percentLoaded = (ns.bytesLoaded/ns.bytesTotal) * 100
            //trace("BUFFER % " + percentLoaded); 
            
        }
        
        private function updateLayout():void {
            video.x = (elementWidth/2) - (video.width/2);
            video.y = (elementHeight/2) - (video.height/2);
        }



        
        
        
        
        
        
        
        
        
        
        /* ------ SETUP FUNCTIONS ------ */
        /* ------------------------------ */
        
        
        private function drawBG():void {
            bg = new Sprite();
            bg.addChild(ELGfx.filledRect(0,0,elementWidth,elementHeight,0x000000));
            this.addChild(bg);
        }
        
                private function getPosterFrame():void {
            if (posterFrameURL) {
                trace("DEBUG: VIDEO: setting up posterframe " + baseURL+posterFrameURL);
                
                posterFrameLoader = new Loader();
                var ur:URLRequest = new URLRequest(baseURL+posterFrameURL);
                
                posterFrameLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadProgress,false,0,true);
                posterFrameLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete,false,0,true);
                posterFrameLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError,false,0,true);
    
                posterFrameLoader.load(ur);
                
                posterFrameLoader.alpha = 0.3;
                bg.addChild(posterFrameLoader);
                
                function loadProgress(e:ProgressEvent):void {
                    //trace(e);
                }
            
                function initComplete(e:Event):void {
                }
                    
                function loadComplete(e:Event):void {
                    trace("VIDEO: showing posterframe");
                }
                
                function ioError(e:Event):void {
                    trace(e);
                }
            }
        }
        
        
        private function setupButton():void {

            bigPlayButton = new ProjectNavButton("PLAY VIDEO",14,true,0xFFFFFF,0xFFFFFF,0x000000, 0.3, 0.9, 8, true);
            bigPlayButton.x = elementWidth/2 - bigPlayButton.width/2;
            bigPlayButton.y = elementHeight/2 - bigPlayButton.height/2;
            bigPlayButton.addEventListener(MouseEvent.CLICK,startVideo);
            
            videoLoadingWarning = new ProjectNavButton("PLEASE WAIT: VIDEO LOADING",14,false,0xFFFFFF,0xFFFFFF,0x000000, 0.3, 0.9, 8, false);
            videoLoadingWarning.x = elementWidth/2 - videoLoadingWarning.width/2;
            videoLoadingWarning.y = elementHeight/2 - videoLoadingWarning.height/2;
            
            this.addChild(bigPlayButton);
        }
        

        


        /* ------ PUBLIC FUNCTIONS ------ */
        /* ------------------------------ */
        
        
        public function activateVideo():void {
            if (posterFrameLoader) {
                bg.addChild(posterFrameLoader);
                posterFrameLoader.alpha = 0.3;
            } else {
                getPosterFrame();
            }
        }
        
        public function deactivateVideo():void {
            trace("DEBUG: stopping video");
            if (ns) {
                ns.close();
                video.clear();
            }
            
            if (posterFrameLoader && bg.contains(posterFrameLoader)) {
                bg.removeChild(posterFrameLoader);
            }
            
            if (this.contains(video)) {
                this.removeChild(video);
            }
            
            this.addChild(bigPlayButton);
        }

    }
}