package { import flash.display.*; import flash.media.Video; import flash.net.*; import flash.geom.*; import flash.utils.*; import flash.events.*; //import org.flashdevelop.utils.*; //encapsulates functionality of playing a video //without exposing the complexities of the NetStream object //and the transition to higher level classes //users of this code may consider matching the audio volume level //to be in sync with the video fade public class actionscript_video_10_transition_VideoPlayer extends Sprite { private var ns:NetStream; private var nc:NetConnection; private var url:String; private var myVid:Video; private var bitmap:Bitmap; private var bitmapData:BitmapData private var timer:Timer; private var dissolveSeed:int=0; //transitions will be updated every 50ms private const TIMER_INTERVAL:int=50; //video is resized to dimensions below private const VIDEO_WIDTH:int=360; private const VIDEO_HEIGHT:int=240; public function actionscript_video_10_transition_VideoPlayer() { init(); } private function init():void { //create the NetConnection nc=new NetConnection(); //standard procedure for non-streaming content nc.connect(null); //create the NetStream ns=new NetStream(nc); ns.bufferTime=6; //create the Video at the specified size myVid = new Video(VIDEO_WIDTH, VIDEO_HEIGHT); //create a bitmap of the same size as the Video //Note: The bitmap we made is solid black. bitmapData=new BitmapData(VIDEO_WIDTH,VIDEO_HEIGHT,true,0xFF000000); bitmap=new Bitmap(bitmapData); //any metadata found in the video will be redirected to the client below //the client must implement the methods implicit in the metadata, otherwise a runtime error will occur when //the metadata is processed by the NetStream object //Generally, this means implementing the methods onMetaData and onCuePoint within the client object //In this class, they are defined below ns.client=this; //connect the Video to the NetStream myVid.attachNetStream(ns); //layer the bitmap over the video this.addChild(myVid); this.addChild(bitmap); //set the bitmap's BlendMode to ALPHA //this means that if the bitmap is opaque (i.e. 100% alpha, or 1.0 in AS3) //then the video below will be opaque //if the bitmap is transparent (i.e. alpha 0) //then the video below will be transparent bitmap.blendMode=BlendMode.ALPHA; //the parent DisplayObject of a child using BlendMode.ALPHA must be set to BlendMode.LAYER this.blendMode=BlendMode.LAYER; //create a Timer and add listeners, but do not start it yet. //The parameters 100 and 0 are placeholder values, and will be changed before the timer is started //in the method fadeOut below timer=new Timer(100,0); timer.addEventListener(TimerEvent.TIMER,timerHandler,false,0,true); timer.addEventListener(TimerEvent.TIMER_COMPLETE,timerCompleteHandler,false,0,true); } public function play():void { //fill the bitmap with solid black //to make the video below opaque bitmapData.fillRect(bitmapData.rect,0xFF000000); //begin playing from the start ns.seek(0); ns.resume(); } //starts a fade from fully opaque to fully transparent //when placed above another playing video, this will //give the effect of a transition between the 2 videos public function fadeOut(duration:int):void { //reset the timer timer.reset(); timer.delay=TIMER_INTERVAL; //timer will fire this many times over the specified duration timer.repeatCount=Math.floor(duration/TIMER_INTERVAL); //start the timer timer.start(); } private function timerCompleteHandler(e:TimerEvent):void { //make sure the bitmap is completely transparent //as the integer maths may leave a few pixels that are opaque bitmapData.fillRect(bitmapData.rect,0x00000000); //pause and rewind the video ns.pause(); ns.seek(0); //notify our listeners (in App.as) that the fade is complete var ev:Event=new Event(Event.COMPLETE); this.dispatchEvent(ev); } private function timerHandler( e:TimerEvent):void { //pixel dissolve the bitmap to alpha 0 (from alpha 100% or 1.0 in AS3) //the number of pixels we will turn transparent every time this function is called. //it is the total number of pixels divided by the number of times this function is called (by the timer) var pixelsToDissolve:int=VIDEO_WIDTH*VIDEO_HEIGHT/timer.repeatCount; //store the return value, as this acts as a seed for the next call //in this way only undissolved pixels will be dissolved on subsequent calls dissolveSeed=bitmapData.pixelDissolve(bitmapData,bitmapData.rect,new Point(),dissolveSeed,pixelsToDissolve,0x00000000); } public function load(url:String):void { //start loading the video but place it in a paused state this.url=url; ns.play(url); ns.pause(); } //this class is a NetStream client //so the following 2 methods are required //see comments in the init method for more information public function onMetaData(info:Object):void { } public function onCuePoint(info:Object):void { } //clean-up code, should this instance no longer be required public function destroy():void { this.removeChild(bitmap); bitmapData.dispose(); } }}