來介紹一下FP10.1的新功能:麥克風錄音
以前在FP10時,麥克風錄音功能需要透過FMS之類的主機, 才能錄音
現在不需要了喔,單swf即可
再透過adobe所提供的 WAVWriter 類別, 即可把聲音資訊存成.wav格式。
1.先安裝FlashPlayer10.1
http://labs.adobe.com/downloads/flashplayer10.html
2.準備一個麥克風(不然到這就結束了)。
3.了解一下原理:
FP10.1, Microphone類別一樣可以偵聽 SampleDataEvent.SAMPLE_DATA 事件
然後透過另一個新的ByteArray物件, 把SampleData裡的ByteArray資訊寫入。
要預聽的話,只要new一個Sound物件, 同時也偵聽SampleDataEvent
把剛剛錄好的ByteArray讀入即可
要成.wav的話
也只需透過WAVWriter物件, 將錄好的ByteArray編碼成 WAV 格式
透過FileReference物件.save,把檔案存出來。
以前在FP10時,麥克風錄音功能需要透過FMS之類的主機, 才能錄音
現在不需要了喔,單swf即可
再透過adobe所提供的 WAVWriter 類別, 即可把聲音資訊存成.wav格式。
1.先安裝FlashPlayer10.1
http://labs.adobe.com/downloads/flashplayer10.html
2.準備一個麥克風(不然到這就結束了)。
3.了解一下原理:
FP10.1, Microphone類別一樣可以偵聽 SampleDataEvent.SAMPLE_DATA 事件
然後透過另一個新的ByteArray物件, 把SampleData裡的ByteArray資訊寫入。
要預聽的話,只要new一個Sound物件, 同時也偵聽SampleDataEvent
把剛剛錄好的ByteArray讀入即可
要成.wav的話
也只需透過WAVWriter物件, 將錄好的ByteArray編碼成 WAV 格式
透過FileReference物件.save,把檔案存出來。
/** * @author milkmidi * @see http://milkmidi.blogspot * @version 1.0.1 * @date created 2010/02/12/ */ package { import com.adobe.audio.format.WAVWriter; import com.bit101.components.Label; import com.bit101.components.PushButton; import flash.display.*; import flash.events.*; import flash.media.Microphone; import flash.media.Sound; import flash.net.FileReference; import flash.utils.ByteArray; import flash.utils.Timer; import milkmidi.display.MilkmidiCopyrightClip; import mx.binding.utils.BindingUtils; [SWF(width = "300", height = "300", frameRate = "30", backgroundColor = "#ffffff")] public class MicrophoneRecordExample extends Sprite { [Bindable] public var isRecording :Boolean = false; private var _microphone :Microphone; private var _label :Label; private var _recordByte :ByteArray; private var _timer :Timer = new Timer(1000, 20); private var _startRecBtn :MyButton; private var _stopRecBtn :MyButton; private var _playRecBtn :MyButton; private var _saveBtn :MyButton; private var _container :Sprite = new Sprite(); public function MicrophoneRecordExample() { new MilkmidiCopyrightClip(true, this, false).onEffectComplete = init; stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; } private function init():void { _label = new Label(_container, 0, 0); _microphone = Microphone.getMicrophone(); if (_microphone==null) { _label.text = "microphone is null"; return; } _timer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void { _label.text = "second:" + _timer.currentCount; }); _timer.addEventListener(TimerEvent.TIMER_COMPLETE, _stopRecordHandler); _microphone.rate = 44; createChildren(); _label.text = "microphone is ready"; BindingUtils.bindSetter( _isRecordingChange, this, "isRecording" ); } private function _isRecordingChange(pIsRecording:Boolean):void { _stopRecBtn.enabled = isRecording; _startRecBtn.enabled = !isRecording; _saveBtn.enabled = !isRecording; _playRecBtn.enabled = !isRecording; } private function createChildren():void { _container.y = 50; addChild(_container); _startRecBtn = new MyButton(_container, 0, 20, "START REC", _startRecHandler); _stopRecBtn = new MyButton(_container, 0, 40, "STOP REC", _stopRecordHandler,false); _playRecBtn = new MyButton(_container, 0, 60, "PLAY REC", _playRecordHandler,false); _saveBtn = new MyButton(_container, 0, 80, "SAVE", _saveWavHandler,false); } private function _playRecordHandler(e:MouseEvent):void{ _recordByte.position = 0; var soundOutput:Sound = new Sound(); soundOutput.addEventListener(SampleDataEvent.SAMPLE_DATA, _playSoundSampleDataHandler); soundOutput.play(); } private function _playSoundSampleDataHandler(e:SampleDataEvent) : void { if (!_recordByte.bytesAvailable > 0) { return; } var i:int = 0; var _length:Number; while (i < 8192) { _length = 0; if (_recordByte.bytesAvailable > 0) { _length = _recordByte.readFloat(); } e.data.writeFloat(_length); e.data.writeFloat(_length); i++; } } private function _startRecHandler(e:MouseEvent):void { isRecording = true; _recordByte = new ByteArray(); _microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, _microphoneSampleDataHandler); _timer.reset(); _timer.start(); } public function _stopRecordHandler(e:Event = null) : void { _label.text = "STOP REC"; _timer.stop(); isRecording = false; _microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, _microphoneSampleDataHandler); } private function _microphoneSampleDataHandler(e:SampleDataEvent):void { _recordByte.writeBytes(e.data); } private function _saveWavHandler(e:Event = null) : void { var _file :FileReference = new FileReference(); var _wavWriter :WAVWriter = new WAVWriter(); _recordByte.position = 0; var _resultSamples:ByteArray = new ByteArray(); _wavWriter.processSamples(_resultSamples,_recordByte, _wavWriter.samplingRate, 1); _file.save(_resultSamples, "FP10MicphoneRecord.wav"); } } } import com.bit101.components.PushButton import flash.display.DisplayObjectContainer; class MyButton extends PushButton { private var _enabled:Boolean = true; public function MyButton(pParent:DisplayObjectContainer,pX:int , pY:int , pLabel:String , pHandler:Function,pEnabled:Boolean = true):void { super(pParent, pX, pY, pLabel, pHandler); mouseChildren = false; enabled = pEnabled; } public function get enabled():Boolean { return _enabled; } public function set enabled(value:Boolean):void { _enabled = value; mouseEnabled = _enabled; alpha = _enabled ? 1 : .4; } }SourceCodeDownload
留言
除非用 AIR 寫就可以做到
e.data.writeFloat(_length);
我用老師給的程式碼做一個,然後沒有用bit101給的按鈕,自己做實體的按鈕,但跑出來都顯示"1120: 存取未定義的屬性 e。"老師可以解釋嗎
我有個疑問,雖然這個錄音功能能夠使用
且能夠錄製20秒的時間,但是存成WAV檔之後,為何只能夠播出7秒多的內容呢?
後半部錄的聲音都無法存下來,想請問老師究竟該怎麼解決這個問題?
http://active.tutsplus.com/tutorials/actionscript/create-a-useful-audio-recorder-app-in-actionscript-3/
我猜可能是WAVEncoder的問題
順利的存取了wav檔案。
可是用了他的recorder套件錄音後,
我該怎麼改寫_playRecordHandler呢?
他的recorder.output雖然也是ByteArray型別,但是無法套用到老師寫的_playRecordHandler裡面。
因為他的 recorder.output 已經是被 WAVEncoder 編碼過了
打開org.bytearray.micrecorder.MicRecorder.as
加入一段:
public function get buffer():ByteArray {return _butter;}
然後再你要播放的程式碼寫成這樣
recorder.buffer.position = 0;
var soundOutput:Sound = new Sound();
soundOutput.addEventListener(SampleDataEvent.SAMPLE_DATA, _playSoundSampleDataHandler);
soundOutput.play();
private function _playSoundSampleDataHandler(e:SampleDataEvent) : void {
var i:int = 0;
var _length:Number;
while (i < 8192) {
_length = 0;
if (recorder.buffer.position.bytesAvailable > 0) {
_length = recorder.buffer.position.readFloat();
}
e.data.writeFloat(_length);
e.data.writeFloat(_length);
i++;
}
}
,但我尚有一個疑問,在第一次錄音過後,_playRecordHandler能夠確實播出我錄的聲音,但是錄了第二次第三次之後,播出的聲音卻愈來愈模糊。
但是,存檔後的檔案聲音卻又都是沒有問題的。
不知道是否在_playRecordHandler仍要對buffer作一些處理才行?
我有試圖在每一次錄音前先把recorder.buffer.length=0
但是依然無法解決讀取buffer愈來愈模糊的問題。
錄影的話,就沒那麼簡單了
需要有一台 FMS