Hello everyone,
A major concern arises for me, and after several days of testing I can not find a solution.
I am currently developing a mobile application on Android to play a video locally.
For this I use the Adobe SimpleStageVideo class available on the website : http://www.adobe.com/devnet/flashplayer/articles/stage_video.html
At the launch all goes well , however when I switch to another application in full reading and then I go back to my video .
That passes over other elements of my interface (ie the navigation menu ) and especially it grows.
I tried to do a resize an event type activate ( to intercept the return on applicaiton )
I also tried to remove the container, and then reinject the video in my interface ( although this is costly in resources ... ) .
It did not work .
I think during my event "activate " the UIComponent has not yet been fully rebuilt, and thereby resize does not work on a good screen size used (since it does not blow conscidère menus ) .
To test my theory , I tested passing in debug mode. By running my code slower, the video goes back to the right size ...
So I tried to put timers, but again it was a futile attempt .
How is it possible when returning to my application that my video remains the right size , and not overlooking the rest of the menus?
Here follows the code in question :
// La Vue Permettant de Visionner la Vidéo
<?xml version="1.0" encoding="utf-8"?><s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:components="bouton.components.*" xmlns:s="library://ns.adobe.com/flex/spark" title="viewVideo" activate="view1_activateHandler(event)" creationComplete="view1_creationCompleteHandler(event)" backgroundAlpha="0" actionBarVisible="false" tabBarVisible="false"> <fx:Script> <![CDATA[ import flash.events.MouseEvent; import mx.core.UIComponent; import mx.events.FlexEvent; import valueObjects.SimpleStageVideo; private var conn:SQLConnection; private var createStmt:SQLStatement; public var dbFile:File; public var fichierCharge:File; public var numeroBouton:int = 0; private var test:SimpleStageVideo = new SimpleStageVideo(); private var container:UIComponent = new UIComponent(); protected function view1_creationCompleteHandler(event:FlexEvent):void { var chemin:File = new File(data.url); test.setData(chemin); //container.stage = this.stage; container.height = stage.height; container.width = stage.width; container.addChildAt(test, 0); addElementAt(container, 0); trace(""+container.width+" : "+container.height+" : "+container.x+" : "+container.y); } protected function view1_activateHandler(event:Event):void { test.resize(); } private function resizeF(event:Event):void { test.resize(); } ]]> </fx:Script> <s:HGroup id="barremenu" gap="0" horizontalAlign="left" styleName="header_style" verticalAlign="top" width="100%" contentBackgroundColor="#FFFFFF" contentBackgroundAlpha="1" paddingBottom="50" > <s:Image scaleMode="letterbox" smooth="true" smoothingQuality="high" source="assets/header_droi.jpg" /> <components:Boutton_Retour click="boutton_retour1_clickHandler(event)" enabled="true" height="100%" contentBackgroundColor="#FFFFFF" contentBackgroundAlpha="1"/> <components:Boutton_Accueil_Retour click="boutton_accueil1_clickHandler(event)" enabled="true" height="100%" contentBackgroundColor="#FFFFFF" contentBackgroundAlpha="1" /> <s:Image scaleMode="stretch" smooth="true" smoothingQuality="high" source="assets/header_milieu.jpg" fillMode="repeat" width="60%" height="99%" /> <s:Image scaleMode="stretch" smooth="true" smoothingQuality="high" source="assets/ipad.jpg" /> </s:HGroup></s:View>
// Ma Classe SimpleStageVideo
package valueObjects { import flash.display.Loader; import flash.display.Shape; import flash.display.Sprite; import flash.display.Stage; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.events.StageVideoAvailabilityEvent; import flash.events.StageVideoEvent; import flash.events.VideoEvent; import flash.filesystem.File; import flash.geom.Rectangle; import flash.media.StageVideo; import flash.media.StageVideoAvailability; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.net.URLRequest; import flash.text.TextField; import flash.text.TextFieldAutoSize; import mx.core.UIComponent; import spark.components.Image; import spark.components.NavigatorContent; [SWF(frameRate="1", backgroundColor="#000000")] public class SimpleStageVideo extends Sprite { public var chemin:File; private var FILE_NAME:String = ""; private static const INTERVAL:Number = 500; private static const BORDER:Number = 20; private var legend:TextField = new TextField(); private var sv:StageVideo; private var nc:NetConnection; private var ns:NetStream; private var rc:Rectangle; private var video:Video; private var thumb:Shape; private var interactiveThumb:Sprite; private var totalTime:Number; private var videoWidth:int; private var videoHeight:int; private var outputBuffer:String = new String(); private var rect:Rectangle = new Rectangle(0, 0, 0, BORDER); private var videoRect:Rectangle = new Rectangle(0, 0, 0, 0); private var gotStage:Boolean; private var stageVideoInUse:Boolean; private var classicVideoInUse:Boolean; private var accelerationType:String; private var infos:String = new String(); private var available:Boolean; private var inited:Boolean; private var played:Boolean; private var container:Sprite; private var displayButtonPause:Boolean; public var imagePause:UIComponent; public var pLoad:Loader; private var testResize:Boolean = false; private var widthStage:int = 0; /** * * */ public function SimpleStageVideo() { // Make sure the app is visible and stage available addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); //addEventListener(Event.ACTIVATE, onActivate); } private function onActivate(event:Event):void { video.addEventListener(Event.RENDER, functionResize); } private function functionResize(event:Event):void { resize(); } /** * * @param event * */ private function onAddedToStage(event:Event):void { // Scaling stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; widthStage = stage.width; // Thumb seek Bar thumb = new Shape(); interactiveThumb = new Sprite(); interactiveThumb.addChild(thumb); addChild(interactiveThumb); // Connections nc = new NetConnection(); nc.connect(null); ns = new NetStream(nc); ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus); ns.client = this; // Screen video = new Video(); video.smoothing = true; // Video Events // the StageVideoEvent.STAGE_VIDEO_STATE informs you if StageVideo is available or not stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoState); // 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); // Input Events stage.addEventListener(MouseEvent.DOUBLE_CLICK, onKeyDown); stage.addEventListener(Event.RESIZE, onResize); stage.addEventListener(MouseEvent.CLICK, onClick); } /** * * @param event * */ private function onNetStatus(event:NetStatusEvent):void { if ( event.info == "NetStream.Play.StreamNotFound" ) legend.text = "Video file passed, not available!"; } public function setData(chem:File):void { chemin = chem; FILE_NAME = chemin.url; } /** * * @param event * */ private function onFrame(event:Event):void { var ratio:Number = (ns.time / totalTime) * (widthStage+470); rect.width = ratio; thumb.graphics.clear(); thumb.graphics.beginFill(0xFF0000); thumb.graphics.drawRect(rect.x, rect.y+350, rect.width+120, rect.height); //thumb.graphics.drawRect(rect.x, rect.y, rect.width, rect.height); //testResize = true; } /** * * @param event * */ private function onClick(event:MouseEvent):void { //ns.pause(); if ( event.stageY >= interactiveThumb.y - BORDER && event.stageX <= stage.stageWidth - BORDER ) { var seekTime:Number = (stage.mouseX - BORDER) * ( totalTime / (stage.stageWidth - (BORDER << 1) ) ); ns.seek( seekTime ); } } /** * * @param event * */ private function onKeyDown(event:MouseEvent):void { ns.togglePause(); // Affichage du bouton d'affichage de la mise en pause de la video if(displayButtonPause == false) { pLoad = new Loader(); pLoad.load(new URLRequest("assets/pause.png")); //imagePause = new UIComponent(); //imagePause.addChild(pLoad); //imagePause.x = 200; //imagePause.y = 200; pLoad.x = (stage.width - (stage.width/3.5)); pLoad.y = (stage.height - (stage.height/3.5)); addChild(pLoad); displayButtonPause = true; pLoad.visible = true; } else { displayButtonPause = false; pLoad.visible = false; removeChild(pLoad); } } /** * Permet l'arret de la video avant la supression de la vue */ public function arretVideo():void { //video.clear(); //sv.attachNetStream(null); ns.close(); //video.attachNetStream(null); /*var nce:NetConnection = new NetConnection(); nce.connect(null); sv.attachNetStream(new NetStream(nce)); //sv.attachNetStream();*/ } /** * * @param width * @param height * @return * */ private function getVideoRect(width:uint, height:uint):Rectangle { trace("Width" + width); trace("Stage Width" + stage.stageWidth); trace("Height" + height); trace("Stage height" + stage.stageHeight); 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; videoRect.x = posX; videoRect.y = posY; videoRect.width = videoWidth; videoRect.height = videoHeight; trace("Objet video width" + video.width); trace("Objet video height" + video.height); trace("Objet video rect width" + videoRect.width); trace("Objet video rect height" + videoRect.height); return videoRect; } /** * * */ public function resize ():void { if ( stageVideoInUse ) { // Get the Viewport viewable rectangle rc = getVideoRect(sv.videoWidth, sv.videoHeight); // set the StageVideo size using the viewPort property sv.viewPort = rc; } else { // 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; //trace(""+rc.width+" : "+rc.height+" : "+rc.x+" : "+rc.y); testResize = true; } interactiveThumb.x = BORDER, interactiveThumb.y = stage.stageHeight - (BORDER << 1); legend.text = infos; } /** * * @param evt * */ public function onMetaData ( evt:Object ):void { totalTime = evt.duration; stage.addEventListener(Event.ENTER_FRAME, onFrame); } /** * * @param event * */ private function onStageVideoState(event:StageVideoAvailabilityEvent):void { // Detect if StageVideo is available and decide what to do in toggleStageVideo toggleStageVideo(available = inited = (event.availability == StageVideoAvailability.AVAILABLE)); } /** * * @param on * */ private function toggleStageVideo(on:Boolean):void { infos = "StageVideo Running (Direct path) : " + on + "\n"; // If we choose StageVideo we attach the NetStream to StageVideo if (on) { stageVideoInUse = true; if ( sv == null ) { sv = stage.stageVideos[0]; sv.addEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange); } sv.attachNetStream(ns); if (classicVideoInUse) { // If we use StageVideo, we just remove from the display list the Video object to avoid covering the StageVideo object (always in the background) stage.removeChild ( video ); classicVideoInUse = false; } } else { // Otherwise we attach it to a Video object if (stageVideoInUse) stageVideoInUse = false; classicVideoInUse = true; video.attachNetStream(ns); stage.addChildAt(video, 0); } if ( !played ) { played = true; ns.play(FILE_NAME); } } /** * * @param event * */ private function onResize(event:Event):void { resize(); } /** * * @param event * */ private function stageVideoStateChange(event:StageVideoEvent):void { infos += "StageVideoEvent received\n"; infos += "Render State : " + event.status + "\n"; trace(infos); resize(); } /** * * @param event * */ private function videoStateChange(event:VideoEvent):void { infos += "VideoEvent received\n"; infos += "Render State : " + event.status + "\n"; trace(infos); resize(); } } }