Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement error callback #32

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 76 additions & 45 deletions flash/Recorder.as
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package
package
{
import com.adobe.audio.format.WAVWriter;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.events.ErrorEvent;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.SampleDataEvent;
import flash.external.ExternalInterface;
import flash.media.Microphone;
Expand All @@ -17,19 +21,19 @@ package
import flash.system.SecurityPanel;
import flash.events.StatusEvent;
import flash.utils.getQualifiedClassName;

import mx.collections.ArrayCollection;

import ru.inspirit.net.MultipartURLLoader;


public class Recorder
{
public function Recorder(logger)
{
this.logger = logger;
}

private var logger;
public function addExternalInterfaceCallbacks():void {
ExternalInterface.addCallback("record", this.record);
Expand All @@ -45,7 +49,6 @@ package
logger.log("Recorder initialized");
}


protected var isRecording:Boolean = false;
protected var isPlaying:Boolean = false;
protected var microphoneWasMuted:Boolean;
Expand All @@ -56,10 +59,10 @@ package
protected var channel:SoundChannel;
protected var recordingStartTime = 0;
protected static var sampleRate = 44.1;

protected function record():void
{
if(!microphone){
if(!microphone){
setupMicrophone();
}

Expand All @@ -74,7 +77,7 @@ package
buffer = new ByteArray();
microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, recordSampleDataHandler);
}

protected function recordStop():int
{
logger.log('stopRecording');
Expand All @@ -83,7 +86,7 @@ package
microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, recordSampleDataHandler);
return recordingDuration();
}

protected function play():void
{
logger.log('startPlaying');
Expand All @@ -92,12 +95,12 @@ package
buffer.position = 0;
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playSampleDataHandler);

channel = sound.play();
channel.addEventListener(Event.SOUND_COMPLETE, function(){
playStop();
});
});

if(playingProgressTimer){
playingProgressTimer.reset();
}
Expand All @@ -108,40 +111,68 @@ package
});
playingProgressTimer.start();
}

protected function stop():int
{
playStop();
return recordStop();
}

protected function playStop():void
{
logger.log('stopPlaying');
if(channel){
channel.stop();
playingProgressTimer.reset();

triggerEvent('playingStop', {});
isPlaying = false;
}
}
/* Networking functions */

/* Networking functions */

protected function upload(uri:String, audioParam:String, parameters): void
{
logger.log("upload");
buffer.position = 0;
var wav:ByteArray = prepareWav();
var wav:ByteArray = prepareWav();
var ml:MultipartURLLoader = new MultipartURLLoader();
ml.addEventListener(Event.COMPLETE, onReady);
function onReady(e:Event):void
{
triggerEvent('uploadSuccess', externalInterfaceEncode(e.target.loader.data));
logger.log('uploading done');
}


ml.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatusEvent);
function onHTTPStatusEvent(e:HTTPStatusEvent):void
{
triggerEvent('uploadHttpStatus', externalInterfaceEncode(e.target.loader.data));
logger.log('http status error occured during upload');
}

ml.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorEvent);
function onIOErrorEvent(e:IOErrorEvent):void
{
triggerEvent('uploadIoError', externalInterfaceEncode(e.target.loader.data));
logger.log('io error occured during upload');
}

ml.addEventListener(ProgressEvent.PROGRESS, onProgressEvent);
function onProgressEvent(e:ProgressEvent):void
{
triggerEvent('uploadProgress', externalInterfaceEncode(e.target.loader.data));
logger.log('upload progress');
}

ml.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorEvent);
function onSecurityErrorEvent(e:SecurityErrorEvent):void
{
triggerEvent('uploadSecurityError', externalInterfaceEncode(e.target.loader.data));
logger.log('security Error occured during upload');
}

if(getQualifiedClassName(parameters.constructor) == "Array"){
for(var i=0; i<parameters.length; i++){
ml.addVariable(parameters[i][0], parameters[i][1]);
Expand All @@ -151,16 +182,16 @@ package
ml.addVariable(k, parameters[k]);
}
}

ml.addFile(wav, 'audio.wav', audioParam);
ml.load(uri, false);

}

private function externalInterfaceEncode(data:String){
return data.split("%").join("%25").split("\\").join("%5c").split("\"").join("%22").split("&").join("%26");
}

protected function audioData(newData:String=null):String
{
var delimiter = ";"
Expand All @@ -181,14 +212,14 @@ package
return ret;
}
}

protected function showFlash():void
{
Security.showSettings(SecurityPanel.PRIVACY);
triggerEvent('showFlash','');
triggerEvent('showFlash','');
}
/* Recording Helper */

/* Recording Helper */
protected function setupMicrophone():void
{
logger.log('setupMicrophone');
Expand All @@ -210,7 +241,7 @@ package

logger.log('setupMicrophone done: ' + microphone.name + ' ' + microphone.muted);
}

protected function notifyRecordingStarted():void
{
if(microphoneWasMuted){
Expand All @@ -222,21 +253,21 @@ package
logger.log('startRecording');
isRecording = true;
}

/* Sample related */

protected function prepareWav():ByteArray
{
var wavData:ByteArray = new ByteArray();
var wavWriter:WAVWriter = new WAVWriter();
var wavWriter:WAVWriter = new WAVWriter();
buffer.position = 0;
wavWriter.numOfChannels = 1; // set the inital properties of the Wave Writer
wavWriter.sampleBitRate = 16;
wavWriter.numOfChannels = 1; // set the inital properties of the Wave Writer
wavWriter.sampleBitRate = 16;
wavWriter.samplingRate = sampleRate * 1000;
wavWriter.processSamples(wavData, buffer, sampleRate * 1000, 1);
return wavData;
}

protected function recordingDuration():int
{
var duration = int(getTimer() - recordingStartTime);
Expand All @@ -247,20 +278,20 @@ package
{
return int(channel.position);
}

protected function recordSampleDataHandler(event:SampleDataEvent):void
{
{
while(event.data.bytesAvailable)
{
{
var sample:Number = event.data.readFloat();

buffer.writeFloat(sample);
if(buffer.length % 40000 == 0){
triggerEvent('recordingProgress', recordingDuration(), microphone.activityLevel);
}
}
}
}

protected function playSampleDataHandler(event:SampleDataEvent):void
{
var expectedSampleRate = 44.1;
Expand All @@ -283,11 +314,11 @@ package
}
logger.log("Wrote " + writtenSamples + " samples");
}

/* ExternalInterface Communication */

protected function triggerEvent(eventName:String, arg0, arg1 = null):void
{
{
ExternalInterface.call("Recorder.triggerEvent", eventName, arg0, arg1);
}
}
Expand Down
33 changes: 24 additions & 9 deletions recorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,46 @@ var Recorder = {

this.flashInterface().record();
},

stop: function(){
return this.flashInterface()._stop();
},

play: function(options){
options = options || {};
this.clearBindings("playingProgress");
this.bind('playingProgress', options['progress']);
this.bind('playingStop', options['finished']);

this.flashInterface()._play();
},

upload: function(options){
options.audioParam = options.audioParam || "audio";
options.error = options.error || console.error;
options.params = options.params || {};
options.progress = options.progress || function () {};
options.success = options.success || function () {};
this.clearBindings("uploadSuccess");
this.bind("uploadSuccess", function(responseText){
options.success(Recorder._externalInterfaceDecode(responseText));
});

this.clearBindings("uploadHttpStatus");
this.bind("uploadHttpStatus", function(responseText){
options.error(Recorder._externalInterfaceDecode(responseText || 'upload error'));
});
this.clearBindings("uploadIoError");
this.bind("uploadIoError", function(responseText){
options.error(Recorder._externalInterfaceDecode(responseText || 'upload error'));
});
this.clearBindings("uploadSecurityError");
this.bind("uploadSecurityError", function(responseText){
options.error(Recorder._externalInterfaceDecode(responseText || 'upload error'));
});

this.flashInterface().upload(options.url, options.audioParam, options.params);
},

audioData: function(newData){
var delimiter = ";", newDataSerialized, stringData, data = [], sample;
if(newData){
Expand All @@ -96,7 +111,7 @@ var Recorder = {
var callbackName = this.registerCallback(callback);
this.flashInterface().request(method, uri, contentType, data, callbackName);
},

clearBindings: function(eventName){
Recorder._events[eventName] = [];
},
Expand All @@ -105,7 +120,7 @@ var Recorder = {
if(!Recorder._events[eventName]){ Recorder._events[eventName] = [] }
Recorder._events[eventName].push(fn);
},

triggerEvent: function(eventName, arg0, arg1){
Recorder._executeInWindowContext(function(){
if (!Recorder._events[eventName]) {
Expand Down Expand Up @@ -210,6 +225,6 @@ var Recorder = {


if(swfobject==undefined){
/* SWFObject v2.2 <http://code.google.com/p/swfobject/> is released under the MIT License <http://www.opensource.org/licenses/mit-license.php */
/* SWFObject v2.2 <http://code.google.com/p/swfobject/> is released under the MIT License <http://www.opensource.org/licenses/mit-license.php */
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+encodeURI(O.location).toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
}
}
Binary file modified recorder.swf
Binary file not shown.