Working with video in actionscript -
i have small movie clips needs played, throughout game making. making them in aftereffets , exporting them flv files , embedding them timeline, making moviclip symbol play them.
but disaster. way small movie clips don't garbage collect @ all. keeps getting stored in memory. if turn them swf, files become 10 times bigger, going high 24 mb 2.4 mb flv file. it's frustrating work way.
can please suggest way work videos/clips in actionscript 3? don't need controls these movie clips, serve cut scenes.
adobe introduced stagevideo, leveraging hardware acceleration high performance video playback.
to mitigate performance impact of rendering video in video object, adobe has introduced stage video new way render video. approach takes full advantage of underlying video hardware. result lower load on cpu, translates higher frame rates on less powerful devices , less memory usage.
example implementation thibault imbert:
package { import flash.display.bitmap; import flash.display.bitmapdata; import flash.display.displayobject; import flash.display.loader; import flash.display.shape; import flash.display.sprite; import flash.display.stagealign; import flash.display.stagedisplaystate; import flash.display.stagescalemode; import flash.events.event; import flash.events.fullscreenevent; import flash.events.keyboardevent; import flash.events.mouseevent; import flash.events.netstatusevent; import flash.events.stagevideoavailabilityevent; import flash.events.stagevideoevent; import flash.events.timerevent; import flash.events.videoevent; import flash.geom.rectangle; import flash.media.soundtransform; import flash.media.stagevideo; import flash.media.stagevideoavailability; import flash.media.video; import flash.net.netconnection; import flash.net.netstream; import flash.system.loadercontext; import flash.text.textfield; import flash.text.textfieldautosize; import flash.text.textformat; import flash.ui.keyboard; /** * * @author thibault imbert * */ [swf(framerate="1", backgroundcolor="#000000")] public class simplestagevideo extends sprite { private static const file_name:string = "video-file.mov"; 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; /** * * */ public function simplestagevideo() { // make sure app visible , stage available addeventlistener(event.added_to_stage, onaddedtostage); } /** * * @param event * */ private function onaddedtostage(event:event):void { // scaling stage.scalemode = stagescalemode.no_scale; stage.align = stagealign.top_left; legend.autosize = textfieldautosize.left; // debug infos legend.multiline = true; legend.background = true; legend.backgroundcolor = 0xffffffff; addchild(legend); // 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 // stagevideoevent.stage_video_state informs if stagevideo available or not stage.addeventlistener(stagevideoavailabilityevent.stage_video_availability, onstagevideostate); // in case of fallback video, listen videoevent.render_state event handle resize , know acceleration mode running video.addeventlistener(videoevent.render_state, videostatechange); // input events stage.addeventlistener(keyboardevent.key_down, 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!"; } /** * * @param event * */ private function onframe(event:event):void { var ratio:number = (ns.time / totaltime) * (stage.stagewidth - (border << 1)); rect.width = ratio; thumb.graphics.clear(); thumb.graphics.beginfill(0xffffff); thumb.graphics.drawrect(rect.x, rect.y, rect.width, rect.height); } /** * * @param event * */ private function onclick(event:mouseevent):void { 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:keyboardevent):void { if ( event.keycode == keyboard.o ) { if ( available ) // toggle stagevideo on , off (fallback video , stagevideo) togglestagevideo(inited=!inited); } else if ( event.keycode == keyboard.f ) { stage.displaystate = stagedisplaystate.full_screen; } else if ( event.keycode == keyboard.space ) { ns.togglepause(); } } /** * * @param width * @param height * @return * */ 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; videorect.x = posx; videorect.y = posy; videorect.width = videowidth; videorect.height = videoheight; return videorect; } /** * * */ private function resize ():void { if ( stagevideoinuse ) { // viewport viewable rectangle rc = getvideorect(sv.videowidth, sv.videoheight); // set stagevideo size using viewport property sv.viewport = rc; } else { // viewport viewable rectangle rc = getvideorect(video.videowidth, video.videoheight); // set video object size video.width = rc.width; video.height = rc.height; video.x = rc.x, video.y = rc.y; } 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 available , decide 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 choose stagevideo attach netstream stagevideo if (on) { stagevideoinuse = true; if ( sv == null ) { sv = stage.stagevideos[0]; sv.addeventlistener(stagevideoevent.render_state, stagevideostatechange); } sv.attachnetstream(ns); if (classicvideoinuse) { // if use stagevideo, remove display list video object avoid covering stagevideo object (always in background) stage.removechild ( video ); classicvideoinuse = false; } } else { // otherwise attach 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"; resize(); } /** * * @param event * */ private function videostatechange(event:videoevent):void { infos += "videoevent received\n"; infos += "render state : " + event.status + "\n"; resize(); } } }
Comments
Post a Comment