Highlighted

No audio after switching between StageVideo and Video rapidly

New Here ,
Oct 26, 2014

Copy link to clipboard

Copied

I am using a slightly modified version of SimpleStageVideo to play videos.

When the SWF runs on IE or the standalone flash player, fullscreen switching does not cause any problem.

However, when the SWF runs on Firefox, clicking the full screen switch button causes the SWF to freeze for a few seconds. If I escape full screen at this moment, both audio and video stop playing and the video time (NetStream.time) doesn't advance anymore.

If I seek the video (by dragging the custom time indicator), video plays but no audio comes out.

This happens with both NetStream.play("Video URL") and NetStream.appendBytes().

This is how I use SimpleStageVideo:

// onAddedToStage

this.nc = new NetConnection(null);

this.nc.connect(null);

this.ns = new NetStream(this.nc);

this.ns.client = this;

this.ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);

this.ns.bufferTime = 0;

this.video = new SimpleStageVideo();

this.video.video.smoothing = true;

this.video.attachNetStream(this.ns);

this.addChild(video);

// when the app receives data from server

this.ns.appendBytes(receivedData);

And this is the code of SimpleStageVideo:

package playercore.hwacceleration
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.StageVideoAvailabilityEvent;
        import flash.events.StageVideoEvent;
        import flash.events.VideoEvent;
        import flash.geom.Rectangle;
        import flash.media.StageVideo;
        import flash.media.StageVideoAvailability;
        import flash.media.Video;
        import flash.media.VideoStatus;
        import flash.net.NetStream;

        /**
         * @author Thibault Imbert (bytearray.org)
         */
        public class SimpleStageVideo extends Sprite
        {               
                private var _available:Boolean;
                private var _stageVideoInUse:Boolean = false;
                private var _classicVideoInUse:Boolean = false;
                private var _played:Boolean;
                private var _rc:Rectangle;
               
                private var _videoRect:Rectangle = new Rectangle(0, 0, 0, 0);
                private var _reset:Rectangle = new Rectangle(0, 0, 0, 0);
               
                private var _on:Boolean;
                private var _initEvent:Event = new Event(Event.INIT);
               
                private var _ns:NetStream;
                private var _video:Video;
                private var _sv:StageVideo;
               
                private var _whRatio:Number; // _whRatio = width / height
                private var _displayArea:Rectangle;
               
                /**
                 * @param whRatio specify the ratio (width / height)
                 */               
                public function SimpleStageVideo(whRatio:Number = 1.0)
                {
                        _on = true;
                        _whRatio = whRatio;
                        _displayArea = new Rectangle(0, 0, whRatio * 100, 100);
                        init();
                }
               
                /**
                 * Forces the switch from Video to StageVideo and vice versa.
                 * You should not have to use this API but can be useful for debugging purposes.
                 * @param on
                 *
                 */               
                public function toggle(on:Boolean):void
                {
                        _on = on;
                       
                        if (!stage)
                                return;

                        if (_on && _available)
                        {
                                if (_classicVideoInUse)
                                {
                                        stage.removeChild(_video);
                                        _classicVideoInUse = false;
                                        _video.attachNetStream(null);
                                }
                                _stageVideoInUse = true;

                                _sv = stage.stageVideos[0];
                                _sv.addEventListener(StageVideoEvent.RENDER_STATE, onRenderState);
                                _sv.viewPort = getVideoRect();
                                _sv.attachNetStream(_ns);
                                dispatchEvent(new SimpleStageVideoToggleEvent(SimpleStageVideoToggleEvent.TOGGLE, SimpleStageVideoToggleEvent.STAGEVIDEO));
                        }
                        else
                        {
                                if (_stageVideoInUse)
                                {
                                        _stageVideoInUse = false;
                                        if (_sv)
                                                _sv.attachNetStream(null);
                                }
                                _classicVideoInUse = true;
                                _video.attachNetStream(_ns);
                                dispatchEvent(new SimpleStageVideoToggleEvent(SimpleStageVideoToggleEvent.TOGGLE, SimpleStageVideoToggleEvent.VIDEO));
                                stage.addChildAt(_video, 0);
                        }
                       
                        if (!_played)
                        {
                                _played = true;
                                dispatchEvent(_initEvent);
                        }
                       
                        resize();
                }
               
                /**
                 * sets video display area. ratio is preserved. (width / height = _whRatio)
                 */
                public function setDisplayArea(x:Number, y:Number, width:Number, height:Number):void
                {
                        _displayArea.x = x;
                        _displayArea.y = y;
                        _displayArea.width = width;
                        _displayArea.height = height;
                        resize();
                }
               
                /**
                 * Resizes the video surfaces while always preserving the image ratio.
                 */               
                private function resize():void
                {
                        var viewPort:Rectangle = getVideoRect();
                        if (_stageVideoInUse)       
                        {
                                _sv.viewPort = viewPort;
                        }
                        else
                        {
                                _rc = viewPort;
                                _video.width = _rc.width;
                                _video.height = _rc.height;
                                _video.x = _rc.x;
                                _video.y = _rc.y;
                        }
                }
               
                /**
                 *
                 * @param stream The NetStream to use for the video.
                 *
                 */               
                public function attachNetStream(stream:NetStream):void
                {
                        _ns = stream;
                        if (_classicVideoInUse)
                        {
                                _video.attachNetStream(_ns);
                        }
                        if (_stageVideoInUse)
                        {
                                _sv.attachNetStream(_ns);
                        }
                }
               
                /**
                 * Clears the image currently displayed in the Video object (not the video stream).
                 * This method is useful for handling the current image.
                 * For example, you can clear the last image or display standby information
                 * without hiding the Video object.
                 * <p> Only works with Video (not StageVideo)
                 */
                public function clear():void
                {
                        if (this._classicVideoInUse)
                                _video.clear();
                }
               
                /**
                 *
                 * @return Returns the internal StageVideo object used if available.
                 *
                 */               
                public function get stageVideo():StageVideo
                {
                        return _sv;
                }
               
                /**
                 *
                 * @return Returns the internal Video object used as a fallback.
                 *
                 */               
                public function get video():Video
                {
                        return _video;
                }
       
                /**
                 *
                 * @return Returns the StageVideo availability.
                 *
                 */               
                public function get available():Boolean
                {
                        return _available;
                }
               
                /**
                 * @return Returns if the StageVideo is in use.
                 */
                public function get stageVideoInUse():Boolean
                {
                        return _stageVideoInUse;
                }

                /**
                 * @return Returns if the (classic) Video is in use.
                 */
                public function get classicVideoInUse():Boolean
                {
                        return _classicVideoInUse;
                }
               
                /**
                 *
                 * sets the ratio (width / height)
                 *
                 */
                public function set whRatio(value:Number):void
                {
                        if (value < 0.0)
                                throw new ArgumentError();

                        _whRatio = value;
                        resize();
                }

                /**
                 *
                 *
                 */               
                private function init():void
                {
                        addChild(_video = new Video());
                        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                        addEventListener(Event.ADDED_TO_STAGE, onAddedToStageView);
                        addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onAddedToStage(event:Event):void
                {       
                        removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                        stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoAvailable);
                        _video.addEventListener(VideoEvent.RENDER_STATE, onRenderState);
                }
               
                /**
                 *
                 * @param event
                 *
                 */               
                private function onAddedToStageView(event:Event):void
                {       
                        if (_classicVideoInUse)
                                stage.addChildAt(_video, 0);
                        else if (_stageVideoInUse)
                                _sv.viewPort = _videoRect;
                }
               
                /**
                 *
                 * @param event
                 *
                 */               
                private function onRemovedFromStage(event:Event):void
                {
                        if (!contains(_video))
                                addChild(_video);
                        if ( _sv != null)
                                _sv.viewPort = _reset;
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onStageVideoAvailable(event:StageVideoAvailabilityEvent):void
                {
                        _available = event.availability == StageVideoAvailability.AVAILABLE && stage.stageVideos.length > 0;
                        toggle(_on);
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onRenderState(event:Event):void
                {
                        var hwDecoding:Boolean;
                       
                        if (event is VideoEvent)
                        {
                                hwDecoding = (event as VideoEvent).status == VideoStatus.ACCELERATED;
                                dispatchEvent(new SimpleStageVideoEvent(SimpleStageVideoEvent.STATUS, hwDecoding, false, false));
                        }
                        else
                        {
                                hwDecoding = (event as StageVideoEvent).status == VideoStatus.ACCELERATED;
                                dispatchEvent(new SimpleStageVideoEvent(SimpleStageVideoEvent.STATUS, hwDecoding, true, hwDecoding));
                        }

                        resize();
                }

                /**
                 *
                 * @param width
                 * @param height
                 * @return
                 *
                 */               
                private function getVideoRect():Rectangle
                {
                        var videoWidth:uint = Math.min(_displayArea.width, _whRatio * _displayArea.height);
                        var videoHeight:uint = videoWidth / _whRatio;

                        var posX:Number = _displayArea.x + ((_displayArea.width - videoWidth) / 2);
                        var posY:Number = _displayArea.y + ((_displayArea.height - videoHeight) / 2);

                        _videoRect.x = posX;
                        _videoRect.y = posY;
                        _videoRect.width = videoWidth;
                        _videoRect.height = videoHeight;

                        return _videoRect;
                }
        }
}

TOPICS
Performance issues

Views

160

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

No audio after switching between StageVideo and Video rapidly

New Here ,
Oct 26, 2014

Copy link to clipboard

Copied

I am using a slightly modified version of SimpleStageVideo to play videos.

When the SWF runs on IE or the standalone flash player, fullscreen switching does not cause any problem.

However, when the SWF runs on Firefox, clicking the full screen switch button causes the SWF to freeze for a few seconds. If I escape full screen at this moment, both audio and video stop playing and the video time (NetStream.time) doesn't advance anymore.

If I seek the video (by dragging the custom time indicator), video plays but no audio comes out.

This happens with both NetStream.play("Video URL") and NetStream.appendBytes().

This is how I use SimpleStageVideo:

// onAddedToStage

this.nc = new NetConnection(null);

this.nc.connect(null);

this.ns = new NetStream(this.nc);

this.ns.client = this;

this.ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);

this.ns.bufferTime = 0;

this.video = new SimpleStageVideo();

this.video.video.smoothing = true;

this.video.attachNetStream(this.ns);

this.addChild(video);

// when the app receives data from server

this.ns.appendBytes(receivedData);

And this is the code of SimpleStageVideo:

package playercore.hwacceleration
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.StageVideoAvailabilityEvent;
        import flash.events.StageVideoEvent;
        import flash.events.VideoEvent;
        import flash.geom.Rectangle;
        import flash.media.StageVideo;
        import flash.media.StageVideoAvailability;
        import flash.media.Video;
        import flash.media.VideoStatus;
        import flash.net.NetStream;

        /**
         * @author Thibault Imbert (bytearray.org)
         */
        public class SimpleStageVideo extends Sprite
        {               
                private var _available:Boolean;
                private var _stageVideoInUse:Boolean = false;
                private var _classicVideoInUse:Boolean = false;
                private var _played:Boolean;
                private var _rc:Rectangle;
               
                private var _videoRect:Rectangle = new Rectangle(0, 0, 0, 0);
                private var _reset:Rectangle = new Rectangle(0, 0, 0, 0);
               
                private var _on:Boolean;
                private var _initEvent:Event = new Event(Event.INIT);
               
                private var _ns:NetStream;
                private var _video:Video;
                private var _sv:StageVideo;
               
                private var _whRatio:Number; // _whRatio = width / height
                private var _displayArea:Rectangle;
               
                /**
                 * @param whRatio specify the ratio (width / height)
                 */               
                public function SimpleStageVideo(whRatio:Number = 1.0)
                {
                        _on = true;
                        _whRatio = whRatio;
                        _displayArea = new Rectangle(0, 0, whRatio * 100, 100);
                        init();
                }
               
                /**
                 * Forces the switch from Video to StageVideo and vice versa.
                 * You should not have to use this API but can be useful for debugging purposes.
                 * @param on
                 *
                 */               
                public function toggle(on:Boolean):void
                {
                        _on = on;
                       
                        if (!stage)
                                return;

                        if (_on && _available)
                        {
                                if (_classicVideoInUse)
                                {
                                        stage.removeChild(_video);
                                        _classicVideoInUse = false;
                                        _video.attachNetStream(null);
                                }
                                _stageVideoInUse = true;

                                _sv = stage.stageVideos[0];
                                _sv.addEventListener(StageVideoEvent.RENDER_STATE, onRenderState);
                                _sv.viewPort = getVideoRect();
                                _sv.attachNetStream(_ns);
                                dispatchEvent(new SimpleStageVideoToggleEvent(SimpleStageVideoToggleEvent.TOGGLE, SimpleStageVideoToggleEvent.STAGEVIDEO));
                        }
                        else
                        {
                                if (_stageVideoInUse)
                                {
                                        _stageVideoInUse = false;
                                        if (_sv)
                                                _sv.attachNetStream(null);
                                }
                                _classicVideoInUse = true;
                                _video.attachNetStream(_ns);
                                dispatchEvent(new SimpleStageVideoToggleEvent(SimpleStageVideoToggleEvent.TOGGLE, SimpleStageVideoToggleEvent.VIDEO));
                                stage.addChildAt(_video, 0);
                        }
                       
                        if (!_played)
                        {
                                _played = true;
                                dispatchEvent(_initEvent);
                        }
                       
                        resize();
                }
               
                /**
                 * sets video display area. ratio is preserved. (width / height = _whRatio)
                 */
                public function setDisplayArea(x:Number, y:Number, width:Number, height:Number):void
                {
                        _displayArea.x = x;
                        _displayArea.y = y;
                        _displayArea.width = width;
                        _displayArea.height = height;
                        resize();
                }
               
                /**
                 * Resizes the video surfaces while always preserving the image ratio.
                 */               
                private function resize():void
                {
                        var viewPort:Rectangle = getVideoRect();
                        if (_stageVideoInUse)       
                        {
                                _sv.viewPort = viewPort;
                        }
                        else
                        {
                                _rc = viewPort;
                                _video.width = _rc.width;
                                _video.height = _rc.height;
                                _video.x = _rc.x;
                                _video.y = _rc.y;
                        }
                }
               
                /**
                 *
                 * @param stream The NetStream to use for the video.
                 *
                 */               
                public function attachNetStream(stream:NetStream):void
                {
                        _ns = stream;
                        if (_classicVideoInUse)
                        {
                                _video.attachNetStream(_ns);
                        }
                        if (_stageVideoInUse)
                        {
                                _sv.attachNetStream(_ns);
                        }
                }
               
                /**
                 * Clears the image currently displayed in the Video object (not the video stream).
                 * This method is useful for handling the current image.
                 * For example, you can clear the last image or display standby information
                 * without hiding the Video object.
                 * <p> Only works with Video (not StageVideo)
                 */
                public function clear():void
                {
                        if (this._classicVideoInUse)
                                _video.clear();
                }
               
                /**
                 *
                 * @return Returns the internal StageVideo object used if available.
                 *
                 */               
                public function get stageVideo():StageVideo
                {
                        return _sv;
                }
               
                /**
                 *
                 * @return Returns the internal Video object used as a fallback.
                 *
                 */               
                public function get video():Video
                {
                        return _video;
                }
       
                /**
                 *
                 * @return Returns the StageVideo availability.
                 *
                 */               
                public function get available():Boolean
                {
                        return _available;
                }
               
                /**
                 * @return Returns if the StageVideo is in use.
                 */
                public function get stageVideoInUse():Boolean
                {
                        return _stageVideoInUse;
                }

                /**
                 * @return Returns if the (classic) Video is in use.
                 */
                public function get classicVideoInUse():Boolean
                {
                        return _classicVideoInUse;
                }
               
                /**
                 *
                 * sets the ratio (width / height)
                 *
                 */
                public function set whRatio(value:Number):void
                {
                        if (value < 0.0)
                                throw new ArgumentError();

                        _whRatio = value;
                        resize();
                }

                /**
                 *
                 *
                 */               
                private function init():void
                {
                        addChild(_video = new Video());
                        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                        addEventListener(Event.ADDED_TO_STAGE, onAddedToStageView);
                        addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onAddedToStage(event:Event):void
                {       
                        removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                        stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoAvailable);
                        _video.addEventListener(VideoEvent.RENDER_STATE, onRenderState);
                }
               
                /**
                 *
                 * @param event
                 *
                 */               
                private function onAddedToStageView(event:Event):void
                {       
                        if (_classicVideoInUse)
                                stage.addChildAt(_video, 0);
                        else if (_stageVideoInUse)
                                _sv.viewPort = _videoRect;
                }
               
                /**
                 *
                 * @param event
                 *
                 */               
                private function onRemovedFromStage(event:Event):void
                {
                        if (!contains(_video))
                                addChild(_video);
                        if ( _sv != null)
                                _sv.viewPort = _reset;
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onStageVideoAvailable(event:StageVideoAvailabilityEvent):void
                {
                        _available = event.availability == StageVideoAvailability.AVAILABLE && stage.stageVideos.length > 0;
                        toggle(_on);
                }

                /**
                 *
                 * @param event
                 *
                 */               
                private function onRenderState(event:Event):void
                {
                        var hwDecoding:Boolean;
                       
                        if (event is VideoEvent)
                        {
                                hwDecoding = (event as VideoEvent).status == VideoStatus.ACCELERATED;
                                dispatchEvent(new SimpleStageVideoEvent(SimpleStageVideoEvent.STATUS, hwDecoding, false, false));
                        }
                        else
                        {
                                hwDecoding = (event as StageVideoEvent).status == VideoStatus.ACCELERATED;
                                dispatchEvent(new SimpleStageVideoEvent(SimpleStageVideoEvent.STATUS, hwDecoding, true, hwDecoding));
                        }

                        resize();
                }

                /**
                 *
                 * @param width
                 * @param height
                 * @return
                 *
                 */               
                private function getVideoRect():Rectangle
                {
                        var videoWidth:uint = Math.min(_displayArea.width, _whRatio * _displayArea.height);
                        var videoHeight:uint = videoWidth / _whRatio;

                        var posX:Number = _displayArea.x + ((_displayArea.width - videoWidth) / 2);
                        var posY:Number = _displayArea.y + ((_displayArea.height - videoHeight) / 2);

                        _videoRect.x = posX;
                        _videoRect.y = posY;
                        _videoRect.width = videoWidth;
                        _videoRect.height = videoHeight;

                        return _videoRect;
                }
        }
}

TOPICS
Performance issues

Views

161

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Oct 26, 2014 0
Adobe Employee ,
Oct 27, 2014

Copy link to clipboard

Copied

Thanks for the heads up.  Could you add this over at https://bugbase.adobe.com and let me know the bug number.  I'll ask someone to follow up.

Thanks,

Chris

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Oct 27, 2014 0