Video playback on Android 4.1.1 (Nexus 7)
Hi,
I've seen a few threads about video playback, but I thought this issue was a tad bit different.
I need video in a somewhat larger AIR on Android project. For video playback I'm using an altered version of Thibault Imbert's stageVideo example script from devnet (which works flawless on iOS).
(see code below)
On Android however I experience these issues:
* In the larger project loading of the video takes about 10 seconds. In a barebones project loading takes about 1, max 2 seconds.
* Trying to see what loadtimes would be without GPU rendering I stripped the class of all it's stageVideo stuff. However, on the device it still states the VideoEvent.RENDER_STATE's status is 'accelerated'. No matter what I set the app-descriptor's rendemode to. On the desktop it states 'software' as status.
Questions:
* Would it be a memory thing and how can I see what the memory usage is on the Nexus?
* How come the Nexus uses accelerated as rendermode no matter what the descriptor's rendemode is and the lack of code referring to stageVideo?
Thanks in advance
Manno
package { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.system.Capabilities; public class AndroidVideoTest extends Sprite { private var v:Video; public function AndroidVideoTest() { super(); // support autoOrients stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; var vpb:VideoPlayback = new VideoPlayback( "Movie001.mp4" ); addChild( vpb ); vpb.playVideo(); } } }
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.events.VideoEvent; import flash.geom.Rectangle; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.text.TextField; import flash.text.TextFieldAutoSize; /** * * @author Thibault Imbert * */ public class VideoPlayback extends Sprite { private var fileName:String = ""; private var legend:TextField = new TextField(); private var nc:NetConnection; private var ns:NetStream; private var rc:Rectangle; private var video:Video; private var infos:String = new String(); private var played:Boolean; /** * Constructor, feed it file to play */ public function VideoPlayback( fname:String = null ) { if ( fname != null ) fileName = fname; } /** * Have it play * */ public function playVideo():void { if( stage ) init( null ); else addEventListener( Event.ADDED_TO_STAGE, init, false, 0, true ); } /** * * @param event * */ private function init( event:Event ):void { if( event ) removeEventListener( Event.ADDED_TO_STAGE, init ); addEventListener( Event.REMOVED_FROM_STAGE, cleanUp ); // Debug infos legend.autoSize = TextFieldAutoSize.LEFT; legend.multiline = true; legend.background = true; legend.backgroundColor = 0xCCCCCC; addChild(legend); // Connections nc = new NetConnection(); nc.connect( null ); ns = new NetStream( nc ); ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus, false, 0, true ); ns.client = this; // Screen video = new Video(); video.smoothing = true; // Video Events // in case of fallback to Video, we listen to the VideoEvent.RENDER_STATE event to handle resize properly and know about the acceleration mode running video.addEventListener( VideoEvent.RENDER_STATE, videoStateChange, false, 0, true ); playStandardVideo(); } /** * Housekeeping tasks * * @param event * */ protected function cleanUp(event:Event):void { removeEventListener( Event.REMOVED_FROM_STAGE, cleanUp ); video.removeEventListener( VideoEvent.RENDER_STATE, videoStateChange ); ns.close(); ns.removeEventListener( NetStatusEvent.NET_STATUS, onNetStatus ); nc.close(); } /** * * @param event * */ private function onNetStatus(event:NetStatusEvent):void { if ( event.info == "NetStream.Play.StreamNotFound" ) trace( "Video file passed, not available!" ); } /** * Calculate largest rect fitting the screen * @param width * @param height * @return Rectangle * */ private function getVideoRect( width:uint, height:uint ):Rectangle { var videoWidth:uint = width; var videoHeight:uint = height; var scaling:Number = Math.min ( stage.stageWidth / videoWidth, stage.stageHeight / videoHeight ); videoWidth *= scaling, videoHeight *= scaling; var posX:uint = stage.stageWidth - videoWidth >> 1; var posY:uint = stage.stageHeight - videoHeight >> 1; var videoRect:Rectangle = new Rectangle(0, 0, 0, 0); videoRect.x = posX; videoRect.y = posY; videoRect.width = videoWidth; videoRect.height = videoHeight; return videoRect; } /** * * */ private function resize ():void { // Get the Viewport viewable rectangle rc = getVideoRect(video.videoWidth, video.videoHeight); // Set the Video object size video.width = rc.width; video.height = rc.height; video.x = rc.x, video.y = rc.y; legend.text = infos; } /** * start video playback with 'classic' video */ private function playStandardVideo( ):void { infos = "Starting playback\n"; // We attach it to a Video object video.attachNetStream(ns); stage.addChildAt(video, 0); if ( !played && fileName.length ) { played = true; ns.play( fileName ); } } /** * * @param event * */ private function videoStateChange( event:VideoEvent ):void { infos += "VideoEvent received\n"; infos += "Render State : " + event.status + "\n"; resize(); } /**************************** * * Video eventhandlers * ****************************/ public function onMetaData ( evt:Object ):void{} public function onXMPData( info:* ):void{} } }
