# HG changeset patch # User cavaliet # Date 1339496786 -7200 # Node ID 3eac3e741aa65efc98279f836235db442b97a318 # Parent c9c34daf1fe6141e61de521a1da36a229fbab363 enhance filename in recorder. diff -r c9c34daf1fe6 -r 3eac3e741aa6 script/record_mic/GUID.as --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/script/record_mic/GUID.as Tue Jun 12 12:26:26 2012 +0200 @@ -0,0 +1,109 @@ +package { + + import flash.display.Sprite; + import flash.system.Capabilities; + + public class GUID extends Object { + + private static var counter:Number = 0; + + function GUID(){ + + } + + public static function create():String { + var dt:Date = new Date(); + var id1:Number = dt.getTime(); + var id2:Number = Math.random()*Number.MAX_VALUE; + var id3:String = Capabilities.serverString; + var rawID:String = calculate(id1+id3+id2+counter++).toUpperCase(); + var finalString:String = rawID.substring(0, 8) + "-" + rawID.substring(8, 12) + "-" + rawID.substring(12, 16) + "-" + rawID.substring(16, 20) + "-" + rawID.substring(20, 32); + return finalString; + } + + private static function calculate(src:String):String { + return hex_sha1(src); + } + + private static function hex_sha1(src:String):String { + return binb2hex(core_sha1(str2binb(src), src.length*8)); + } + + private static function core_sha1(x:Array, len:Number):Array { + x[len >> 5] |= 0x80 << (24-len%32); + x[((len+64 >> 9) << 4)+15] = len; + var w:Array = new Array(80), a:Number = 1732584193; + var b:Number = -271733879, c:Number = -1732584194; + var d:Number = 271733878, e:Number = -1009589776; + for (var i:Number = 0; i> 16)+(y >> 16)+(lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + private static function rol(num:Number, cnt:Number):Number { + return (num << cnt) | (num >>> (32-cnt)); + } + + private static function str2binb(str:String):Array { + var bin:Array = new Array(); + var mask:Number = (1 << 8)-1; + for (var i:Number = 0; i> 5] |= (str.charCodeAt(i/8) & mask) << (24-i%32); + } + return bin; + } + + private static function binb2hex(binarray:Array):String { + var str:String = new String(""); + var tab:String = new String("0123456789abcdef"); + for (var i:Number = 0; i> 2] >> ((3-i%4)*8+4)) & 0xF) + tab.charAt((binarray[i >> 2] >> ((3-i%4)*8)) & 0xF); + } + return str; + } + } +} + + + +// USAGE ///////////////////////////////////////// +/* +var myGUID:String = GUID.create(); +trace("myGUID: "+myGUID); +*/ + +// OUTPUT +// myGUID: 6EF3BDEC-5B51-3CE9-429C-F99A46EC0980 +////////////////////////////////////////////////// \ No newline at end of file diff -r c9c34daf1fe6 -r 3eac3e741aa6 script/record_mic/record_mic.as --- a/script/record_mic/record_mic.as Mon Jun 11 18:55:50 2012 +0200 +++ b/script/record_mic/record_mic.as Tue Jun 12 12:26:26 2012 +0200 @@ -1,1 +1,1 @@ -package { import flash.display.MovieClip; import flash.display.SimpleButton; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.events.AsyncErrorEvent; import flash.events.ErrorEvent; import flash.events.ActivityEvent; import flash.events.Event; import flash.media.Microphone; import flash.net.NetConnection; import flash.net.NetStream; import flash.system.Security; import flash.system.SecurityPanel; import flash.text.TextField; import flash.utils.setInterval; import fl.controls.ProgressBar; import fl.controls.ProgressBarMode; import fl.controls.Slider; import fl.events.SliderEvent; import flash.external.ExternalInterface; import com.eclecticdesignstudio.motion.Actuate; public class record_mic extends MovieClip { private var t:TextField; private var r:SimpleButton; private var p:Sprite; private var playVisible:Boolean = false; private var urlServer:String = "rtmp://media.iri.centrepompidou.fr/ddc_micro_record"; private var nc:NetConnection; private var ns:NetStream; private var ns2:NetStream; private var mic:Microphone; private var filename:String; private var recordRunning:Boolean = false; private var recordStopped:Boolean = false; // Draw mic feedback private var pb:ProgressBar; private var activityCurve:Sprite; private var micGain:Slider; // Variables for the activity curve private var xInc:int = 0; private var xSpeed:int = 2; private var activityWidth:Number; // Intervals used to draw the curve et keep track of the duration of the recording private var drawCurve:Number; private var timecodeInterval:Number; private var timecode:Number = 0; public function record_mic() { // constructor code Security.allowDomain("*"); Security.allowInsecureDomain("*"); //Security.showSettings(SecurityPanel.DEFAULT); //t = _t; r = _recordBtn; p = _playBtn; pb = _pb; activityWidth = _act.width; activityCurve = _act._activityCurve; micGain = _micGain; trace("t = " + t + ", r = " + r + ", p = " + p + ", pb = " + pb); // Fuck CS5 "new feature from built-in preloader" : loaderInfo.parameters is from parent.parent.loaderInfo.parameter var flashVars:Object = new Object(); if(parent!=null){ if (parent.parent!=null) flashVars = parent.parent.loaderInfo.parameters; else flashVars = parent.loaderInfo.parameters; } else flashVars = loaderInfo.parameters; for(var param:Object in flashVars){ trace(" flashVars " + param + " : " + flashVars[param.toString()]); } if(flashVars["playVisible"]=="true"){ playVisible = true; } micGain.visible = p.visible = pb.visible = _act.visible = false; //r.buttonMode = r.useHandCursor = p.buttonMode = p.useHandCursor = true; pb.mode = ProgressBarMode.MANUAL; r.addEventListener(MouseEvent.CLICK, startRecord); p.addEventListener(MouseEvent.CLICK, playRecord); try{ ExternalInterface.addCallback("stopRecord", stopRecord); } catch(e:*){ //t.text = "ExternalInterface error catch e = " + e; } } private function startRecord(e:MouseEvent=null):void{ trace("startRecord nc = " + nc + ", recordRunning = " + recordRunning); if(!recordRunning){ if (nc==null){ trace(" startRecord 2"); nc = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler, false, 0, true); nc.addEventListener(IOErrorEvent.IO_ERROR, errorHandler, false, 0, true); nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler, false, 0, true); nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler, false, 0, true); nc.connect(urlServer); } else{ publish(); } } else{ // If record is running, we stop it stopRecord(); } } private function errorHandler(e:*=null):void { trace("errorHandler"); closeStream(); } private function closeStream():void{ trace("closeStream"); if(ns!=null){ trace(" ns.close()"); ns.close(); ns = null; } } private function netStatusHandler(event:NetStatusEvent):void { trace("netStatusHandler : " + event.info.code); switch (event.info.code) { case 'NetConnection.Connect.Success': publish(); break; case 'NetConnection.Connect.Failed': case 'NetConnection.Connect.Reject': case 'NetConnection.Connect.Closed': //closeStream(); break; } } // send data over rtmp private function publish():void { trace("publish (ns==null && nc!=null && nc.connected) = " + (ns==null && nc!=null && nc.connected)); if(nc!=null && nc.connected) { trace(" publish 2"); ns = new NetStream(nc); ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler, false, 0, true); ns.addEventListener(IOErrorEvent.IO_ERROR, errorHandler, false, 0, true); ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler, false, 0, true); // informs the server to record what it receives // in fact file name is passed as the user name (the server is meant to record everything it has to in a file named from the user name) filename = "r_" + now(); trace("filename = " + filename); recordRunning = true; ns.publish(filename, 'record'); mic = Microphone.getMicrophone(-1); mic.rate = 22; micGain.minimum = 0; micGain.maximum = 100; micGain.value = mic.gain = 50; micGain.addEventListener(SliderEvent.CHANGE, onSliderChange); mic.addEventListener(ActivityEvent.ACTIVITY, runMicActivity); mic.setUseEchoSuppression(true); ns.attachAudio(mic); micGain.visible = pb.visible = _act.visible = true; p.visible = playVisible; // ExternalInterface call to give audio url ExternalInterface.call("setAudioUrl", urlServer + "/" + filename); // We tween the red button tween1to0(); } } // stop the recording of audio to the stream private function stopRecord(e:*=null):void{ trace("stopRecord (ns!=null) = " + (ns!=null)); if(ns!=null){ trace(" stopRecord 2"); recordRunning = false; recordStopped = true; ns.play(false); // flushes the recording buffer ns.close(); } stopTween(); } // plays back the audio that was recorded private function playRecord(e:*=null):void{ trace("playRecord (ns!=null && recordStopped) = " + (ns!=null && recordStopped)); if(recordStopped){ trace(" playRecord 2"); ns2 = new NetStream(nc); ns2.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler2, false, 0, true); ns2.addEventListener(IOErrorEvent.IO_ERROR, errorHandler2, false, 0, true); ns2.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler2, false, 0, true); ns2.play(filename); } } private function netStatusHandler2(event:NetStatusEvent):void { trace("netStatusHandler 2 : " + event.info.code); } private function errorHandler2(e:*=null):void { trace("errorHandler 2"); closeStream2(); } private function closeStream2():void{ trace("closeStream 2"); /*if(ns2!=null){ trace(" ns.close()"); ns2.close(); ns2 = null; }*/ } // Now in string private function now():String{ var d:Date = new Date(); var m:uint = d.month + 1; // because Date.month begins at 0 return d.fullYear + (m<10?("0"+m):m) + (d.date<10?("0"+d.date):d.date) + (d.hours<10?("0"+d.hours):d.hours) + (d.minutes<10?("0"+d.minutes):d.minutes) + (d.seconds<10?("0"+d.seconds):d.seconds) + (d.milliseconds<100?"0":"") + (d.milliseconds<10?"0":"") + d.milliseconds; } // sets the module ready to record mic activity changes private function runMicActivity(e:ActivityEvent):void { trace("runMicActivity"); mic.removeEventListener(ActivityEvent.ACTIVITY, runMicActivity); addEventListener(Event.ENTER_FRAME, showMicActivity); // Start activity curve feedback, every second activityCurve.graphics.clear(); activityCurve.graphics.lineStyle(1, 0xc4c4c4, 1); activityCurve.graphics.moveTo(0, 20); activityCurve.graphics.beginFill(0xc4c4c4, 100); xInc = 0; activityCurve.x = 1; setInterval(drawSoundCurve, 100); } // updates the progress bar relating to mic activity private function showMicActivity(e:Event):void { //trace("showMicActivity res = " + mic.activityLevel); pb.setProgress(mic.activityLevel,100); } // updates the actiity curve relating to mic activity private function drawSoundCurve():void { if(recordRunning){ //trace("drawSoundCurve recordRunning = " + recordRunning + ", mic.activityLevel = " + mic.activityLevel + ", mic.gain = " + mic.gain + ", h = " + (19*mic.activityLevel/100)); activityCurve.graphics.lineTo(xInc, 19 - (19*mic.activityLevel/100)); activityCurve.graphics.lineTo(xInc, 19); if(xInc>activityWidth){ activityCurve.x -= xSpeed; } xInc += xSpeed; } } // Updates mic gain private function onSliderChange(e:SliderEvent):void { trace("onSliderChange"); mic.gain = micGain.value; } // Tween management private function tween0to1():void { Actuate.tween(r, .5, { alpha: 1 } ).onComplete(tween1to0); } private function tween1to0():void { Actuate.tween(r, .5, { alpha: .2 } ).onComplete(tween0to1); } private function stopTween():void { trace("stopTween"); Actuate.reset(); r.alpha = 1; } } } \ No newline at end of file +package { import flash.display.MovieClip; import flash.display.SimpleButton; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.NetStatusEvent; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.events.AsyncErrorEvent; import flash.events.ErrorEvent; import flash.events.ActivityEvent; import flash.events.Event; import flash.media.Microphone; import flash.net.NetConnection; import flash.net.NetStream; import flash.system.Security; import flash.system.SecurityPanel; import flash.text.TextField; import flash.utils.setInterval; import fl.controls.ProgressBar; import fl.controls.ProgressBarMode; import fl.controls.Slider; import fl.events.SliderEvent; import flash.external.ExternalInterface; import com.eclecticdesignstudio.motion.Actuate; public class record_mic extends MovieClip { private var t:TextField; private var r:SimpleButton; private var p:Sprite; private var playVisible:Boolean = false; private var urlServer:String = "rtmp://media.iri.centrepompidou.fr/ddc_micro_record"; private var nc:NetConnection; private var ns:NetStream; private var ns2:NetStream; private var mic:Microphone; private var filename:String; private var recordRunning:Boolean = false; private var recordStopped:Boolean = false; // Draw mic feedback private var pb:ProgressBar; private var activityCurve:Sprite; private var micGain:Slider; // Variables for the activity curve private var xInc:int = 0; private var xSpeed:int = 2; private var activityWidth:Number; // Intervals used to draw the curve et keep track of the duration of the recording private var drawCurve:Number; private var timecodeInterval:Number; private var timecode:Number = 0; public function record_mic() { // constructor code Security.allowDomain("*"); Security.allowInsecureDomain("*"); //Security.showSettings(SecurityPanel.DEFAULT); //t = _t; r = _recordBtn; p = _playBtn; pb = _pb; activityWidth = _act.width; activityCurve = _act._activityCurve; micGain = _micGain; trace("t = " + t + ", r = " + r + ", p = " + p + ", pb = " + pb); // Fuck CS5 "new feature from built-in preloader" : loaderInfo.parameters is from parent.parent.loaderInfo.parameter var flashVars:Object = new Object(); if(parent!=null){ if (parent.parent!=null) flashVars = parent.parent.loaderInfo.parameters; else flashVars = parent.loaderInfo.parameters; } else flashVars = loaderInfo.parameters; for(var param:Object in flashVars){ trace(" flashVars " + param + " : " + flashVars[param.toString()]); } if(flashVars["playVisible"]=="true"){ playVisible = true; } micGain.visible = p.visible = pb.visible = _act.visible = false; p.buttonMode = p.useHandCursor = true; pb.mode = ProgressBarMode.MANUAL; r.addEventListener(MouseEvent.CLICK, startRecord); p.addEventListener(MouseEvent.CLICK, playRecord); try{ ExternalInterface.addCallback("stopRecord", stopRecord); } catch(e:*){ //t.text = "ExternalInterface error catch e = " + e; } } private function startRecord(e:MouseEvent=null):void{ trace("startRecord nc = " + nc + ", recordRunning = " + recordRunning); if(!recordRunning){ if (nc==null){ trace(" startRecord 2"); nc = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler, false, 0, true); nc.addEventListener(IOErrorEvent.IO_ERROR, errorHandler, false, 0, true); nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler, false, 0, true); nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler, false, 0, true); nc.connect(urlServer); } else{ publish(); } } else{ // If record is running, we stop it stopRecord(); } } private function errorHandler(e:*=null):void { trace("errorHandler"); closeStream(); } private function closeStream():void{ trace("closeStream"); if(ns!=null){ trace(" ns.close()"); ns.close(); ns = null; } } private function netStatusHandler(event:NetStatusEvent):void { trace("netStatusHandler : " + event.info.code); switch (event.info.code) { case 'NetConnection.Connect.Success': publish(); break; case 'NetConnection.Connect.Failed': case 'NetConnection.Connect.Reject': case 'NetConnection.Connect.Closed': //closeStream(); break; } } // send data over rtmp private function publish():void { trace("publish (ns==null && nc!=null && nc.connected) = " + (ns==null && nc!=null && nc.connected)); if(nc!=null && nc.connected) { trace(" publish 2"); ns = new NetStream(nc); ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler, false, 0, true); ns.addEventListener(IOErrorEvent.IO_ERROR, errorHandler, false, 0, true); ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler, false, 0, true); // informs the server to record what it receives // in fact file name is passed as the user name (the server is meant to record everything it has to in a file named from the user name) filename = "tralalere/r_" + GUID.create(); trace("filename = " + filename); recordRunning = true; ns.publish(filename, 'record'); mic = Microphone.getMicrophone(-1); mic.rate = 22; micGain.minimum = 0; micGain.maximum = 100; micGain.value = mic.gain = 50; micGain.addEventListener(SliderEvent.CHANGE, onSliderChange); mic.addEventListener(ActivityEvent.ACTIVITY, runMicActivity); mic.setUseEchoSuppression(true); ns.attachAudio(mic); micGain.visible = pb.visible = _act.visible = true; p.visible = playVisible; // ExternalInterface call to give audio url ExternalInterface.call("setAudioUrl", urlServer + "/" + filename); // We tween the red button tween1to0(); } } // stop the recording of audio to the stream private function stopRecord(e:*=null):void{ trace("stopRecord (ns!=null) = " + (ns!=null)); if(ns!=null){ trace(" stopRecord 2"); recordRunning = false; recordStopped = true; ns.play(false); // flushes the recording buffer ns.close(); } stopTween(); } // plays back the audio that was recorded private function playRecord(e:*=null):void{ trace("playRecord (ns!=null && recordStopped) = " + (ns!=null && recordStopped)); if(recordStopped){ trace(" playRecord 2"); ns2 = new NetStream(nc); ns2.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler2, false, 0, true); ns2.addEventListener(IOErrorEvent.IO_ERROR, errorHandler2, false, 0, true); ns2.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler2, false, 0, true); ns2.play(filename); } } private function netStatusHandler2(event:NetStatusEvent):void { trace("netStatusHandler 2 : " + event.info.code); } private function errorHandler2(e:*=null):void { trace("errorHandler 2"); closeStream2(); } private function closeStream2():void{ trace("closeStream 2"); /*if(ns2!=null){ trace(" ns.close()"); ns2.close(); ns2 = null; }*/ } // sets the module ready to record mic activity changes private function runMicActivity(e:ActivityEvent):void { trace("runMicActivity"); mic.removeEventListener(ActivityEvent.ACTIVITY, runMicActivity); addEventListener(Event.ENTER_FRAME, showMicActivity); // Start activity curve feedback, every second activityCurve.graphics.clear(); activityCurve.graphics.lineStyle(1, 0xc4c4c4, 1); activityCurve.graphics.moveTo(0, 20); activityCurve.graphics.beginFill(0xc4c4c4, 100); xInc = 0; activityCurve.x = 1; setInterval(drawSoundCurve, 100); } // updates the progress bar relating to mic activity private function showMicActivity(e:Event):void { //trace("showMicActivity res = " + mic.activityLevel); pb.setProgress(mic.activityLevel,100); } // updates the actiity curve relating to mic activity private function drawSoundCurve():void { if(recordRunning){ //trace("drawSoundCurve recordRunning = " + recordRunning + ", mic.activityLevel = " + mic.activityLevel + ", mic.gain = " + mic.gain + ", h = " + (19*mic.activityLevel/100)); activityCurve.graphics.lineTo(xInc, 19 - (19*mic.activityLevel/100)); activityCurve.graphics.lineTo(xInc, 19); if(xInc>activityWidth){ activityCurve.x -= xSpeed; } xInc += xSpeed; } } // Updates mic gain private function onSliderChange(e:SliderEvent):void { trace("onSliderChange"); mic.gain = micGain.value; } // Tween management private function tween0to1():void { Actuate.tween(r, .5, { alpha: 1 } ).onComplete(tween1to0); } private function tween1to0():void { Actuate.tween(r, .5, { alpha: .2 } ).onComplete(tween0to1); } private function stopTween():void { trace("stopTween"); Actuate.reset(); r.alpha = 1; } } } \ No newline at end of file diff -r c9c34daf1fe6 -r 3eac3e741aa6 script/record_mic/record_mic.swf Binary file script/record_mic/record_mic.swf has changed diff -r c9c34daf1fe6 -r 3eac3e741aa6 web/tralalere/static/tralalere/swf/record_mic.swf Binary file web/tralalere/static/tralalere/swf/record_mic.swf has changed