package away3d.materials { import away3d.arcane; import away3d.core.base.*; import away3d.core.draw.*; import away3d.core.math.*; import away3d.core.render.*; import away3d.core.utils.*; import away3d.events.*; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.AsyncErrorEvent; import flash.events.IOErrorEvent; import flash.events.NetStatusEvent; import flash.events.SecurityErrorEvent; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.text.StyleSheet; import flash.text.TextField; use namespace arcane; /** * Animated movie material. */ public class VideoMaterial extends MovieMaterial { /** * Defines the path to the rtmp stream used for rendering the material */ public var rtmp:String; /** * Defines the FLV used for rendering the material */ private var _file:String; public function get file():String { return _file; } public function set file(file:String):void { _file = file; startPlaying(); } /** * Defines if the FLV will be looping playback */ public var loop:Boolean; /** * Defines the NetStream we'll use */ public var netStream:NetStream; /** * Defines the NetConnection we'll use */ public var nc:NetConnection; /** * Holds the video Object */ public var video:Video; /** * A Sprite we can return to the MovieMaterial */ public var sprite:Sprite; private var _lockW:Number; private var _lockH:Number; /** * Creates a new VideoMaterial object. * Pass file:"somevideo.flv" in the initobject or set the file to start playing a video. * Be aware that FLV files must be located in the same domain as the SWF or you will get security errors. * NOTE: rtmp is not yet supported * * @param file The url to the FLV file. * @param init [optional] An initialisation object for specifying default instance properties. */ public function VideoMaterial(init:Object = null) { ini = Init.parse(init); loop = ini.getBoolean("loop", false); file = ini.getString("file", ""); rtmp = ini.getString("rtmp", ""); sprite = new Sprite(); this._file = file; super(sprite,ini); // Attach sprite to MovieMaterial // Play the video if we have one if(file != ""){ startPlaying(); } } private function startPlaying():void { if(rtmp == ""){ try { // Use null connection for progressive files nc = new NetConnection(); nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler,false,0,true); nc.connect(null); netStream = new NetStream(nc); this.netStream = netStream; // Setup stream. Remember that the FLV must be in the same security sandbox as the SWF. netStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler,false,0,true); netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, ayncErrorHandler,false,0,true); netStream.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler,false,0,true); netStream.play(file); // ignore metadata var anyObject:Object = new Object(); anyObject.onCuePoint = metaDataHandler; anyObject.onMetaData = metaDataHandler; netStream.client = anyObject; // Setup video object video = new Video(); video.smoothing = true; video.attachNetStream(netStream); sprite.addChild(video); // update the material dimensions this.movie = sprite; updateDimensions(); } catch (e:Error) { showError("an error has occured with the flv stream:" + e.message); } } else { // rtmp is not currently implemented due to Flash Player security restrictions /* try { nc = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler); nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler,false,0,true); nc.connect(rtmp); } catch (e:Error) { trace("an error has occured with the flv stream:" + e.message); } */ } } /** * Plays rtmp streams when they've connected to the server */ private function playStream():void { netStream = new NetStream(nc); this.netStream = netStream; netStream.checkPolicyFile = true; netStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler,false,0,true); netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, ayncErrorHandler,false,0,true); netStream.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler,false,0,true); netStream.play(file); // ignore metadata var anyObject:Object = new Object(); anyObject.onMetaData = metaDataHandler; netStream.client = anyObject; // Setup video object video = new Video(); video.smoothing = true; video.attachNetStream(netStream); sprite.addChild(video); } /** * We must update the material */ private function updateDimensions():void { _lockW = ini.getNumber("lockW", movie.width); _lockH = ini.getNumber("lockH", movie.height); _bitmap = new BitmapData(Math.max(1,_lockW), Math.max(1,_lockH), transparent, (transparent) ? 0x00ffffff : 0); } // Event handling private function ayncErrorHandler(event:AsyncErrorEvent): void { // Must be present to prevent errors, but won't do anything } private function metaDataHandler(oData:Object = null):void { // Offers info such as oData.duration, oData.width, oData.height, oData.framerate and more (if encoded into the FLV) this.dispatchEvent( new VideoEvent(VideoEvent.METADATA,netStream,file,oData) ); } private function ioErrorHandler(e:IOErrorEvent):void { showError("An IOerror occured: "+e.text); } private function securityErrorHandler(e:SecurityErrorEvent):void { showError("A security error occured: "+e.text+" Remember that the FLV must be in the same security sandbox as your SWF."); } private function showError(txt:String, e:NetStatusEvent = null):void { sprite.graphics.beginFill(0x333333); sprite.graphics.drawRect(0,0,400,300); sprite.graphics.endFill(); // Error text formatting var style:StyleSheet = new StyleSheet(); var styleObj:Object = new Object(); styleObj.fontSize = 24; styleObj.fontWeight = "bold"; styleObj.color = "#FF0000"; style.setStyle("p", styleObj); // make textfield var text:TextField = new TextField(); text.width = 400; text.multiline = true; text.wordWrap = true; text.styleSheet = style; text.text = "

"+txt+"

"; sprite.addChild(text); // apply updateDimensions() } private function netStatusHandler(e:NetStatusEvent):void { switch (e.info.code) { case "NetStream.Play.Stop": this.dispatchEvent( new VideoEvent(VideoEvent.STOP,netStream,file) ); if(loop){ netStream.play(file) }; break; case "NetStream.Play.Play": this.dispatchEvent( new VideoEvent(VideoEvent.PLAY,netStream,file) ); break; case "NetStream.Play.StreamNotFound": showError("The file "+file+"was not found", e); break; case "NetConnection.Connect.Success": playStream(); break; } } } }