跳到主要內容

FlashPlayer10.1麥克風錄音

來介紹一下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,把檔案存出來。
Thumbnail - Click me


/**
* @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

留言

匿名表示…
有沒有可能存檔的時候,就指定位置跟檔名,按下去後就直接存檔而且不會跑出對話視窗呢~?
milkmidi寫道…
不能喔,因為FlashPlayer安全性考量
除非用 AIR 寫就可以做到
匿名表示…
我把bit101作者裡面Label,PushButton的AS檔都丟到指定的資料夾裡面,在搭配老師給的程式碼,顯示出,Lable顯是1020:標示為 override 的方法必須覆寫另一個方法。1017: 找不到基底類別 Component 的定義。是我的方法錯誤了嗎
milkmidi寫道…
你需要把整包的類別都放過去,而不是只有那二個.as檔喔
匿名表示…
e.data.writeFloat(_length);
e.data.writeFloat(_length);
我用老師給的程式碼做一個,然後沒有用bit101給的按鈕,自己做實體的按鈕,但跑出來都顯示"1120: 存取未定義的屬性 e。"老師可以解釋嗎
匿名表示…
老師您好~
我有個疑問,雖然這個錄音功能能夠使用
且能夠錄製20秒的時間,但是存成WAV檔之後,為何只能夠播出7秒多的內容呢?
後半部錄的聲音都無法存下來,想請問老師究竟該怎麼解決這個問題?
milkmidi寫道…
試試改看這篇
http://active.tutsplus.com/tutorials/actionscript/create-a-useful-audio-recorder-app-in-actionscript-3/
我猜可能是WAVEncoder的問題
匿名表示…
謝謝老師~我照了老師提供的網址去改了,
順利的存取了wav檔案。

可是用了他的recorder套件錄音後,
我該怎麼改寫_playRecordHandler呢?
他的recorder.output雖然也是ByteArray型別,但是無法套用到老師寫的_playRecordHandler裡面。
milkmidi寫道…
你要改一下他提供的原始碼
因為他的 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愈來愈模糊的問題。
milkmidi寫道…
試試錄音前,重新把 buffer = new ByteArray
匿名表示…
老師您好,請問AS3.0也可以使用這種介面來錄影嗎?
milkmidi寫道…
是呀,我是用 AS3 寫的
匿名表示…
老師您好,我是說「錄影」唷@@
milkmidi寫道…
不好意思,看錯
錄影的話,就沒那麼簡單了
需要有一台 FMS
匿名表示…
請問奶老師: 如何使用AS3作聲音的Equalizer效果呢 ? 就是可以調節任一聲音檔的高、中、低音?
匿名表示…
不好意思 我是剛剛發問的 在網路上找到這篇教學:http://www.blixtsystems.com/2008/05/simple-3-band-eq-with-flash-player-10/comment-page-1/#comment-57999 但是執行起來畫面卻一片空白 也沒有聲音

這個網誌中的熱門文章

超好用的無限免費網頁空間,無廣告,無流量限制

大家好,我是奶綠茶 今天來教大家如何申請一個無限免費速度又快的網頁空間 1 首先到  https://github.com/ 申請帳號(一直下一步,下一步,下一步) 2 到你的個人頁,切換上方的 tab 到 Repositories, 按下右鍵的 new 3 Repository name 一定要是這樣的格式 username.github.io 我的 github 網址是 github.com/milkmidi 那就要輸入 milkmidi.github.io 選擇 public, 這樣別人才看的到 private 有其他用途, 而且要付費才能使用 完成後按下 Create repository 5 安裝 SourceTree github 並不支援 FTP 或是網頁上傳,一定要透過指令碼 在這我們選用有圖型介面的軟體,方便大家學習 https://www.sourcetreeapp.com/ 下載並安裝 啟動後登入你的 github 帳號 6 clone 你的 github io 專案 右上角有個 Clone or download 點選後 複製 https 連結(不要選到 ssh ) 7 將 https 的連結貼到 SourceTree 8 上傳 html 到本機 github.io 資料夾,放一個 index.html 切換到 SourceTree, 這時會看到 Unstaged files 的欄位 選擇 Stage All 9 git 要求每次的 Commit, 都一定要打說明文字(好習慣) 輸入完成後,按下右邊的 Commit 10 發佈(Push),這樣就完成啦 可以到你的 http://milkmidi.github.io/ 去查看檔案有沒有出來 其他 Commit 可以想像是做一個記錄,你可以很多的 Commit 最後再一次 Push 上去 github 原本是給程式設計師用的版本控管服務 免費版提供無限空間讓你放檔案,但一定要是 public 想要有私有的 Project ,就只能付費 github.io 只能放靜態檔案,php, aspx 服務並不支援。 祝大家學習愉快 轉載請註明出處 奶綠的 gi...

奶綠茶新書上市_密技公怖_程式碼下載

奶綠茶第一本 Flash 書籍上市啦 博客來書籍館 Flash 3D 特效宅急便 - 商業範例隨學隨 把我對 Flash 的研究與熱愛, 全寫在其中 本書的前幾章, 特別安排 ActionScript3.0 的許多範例 好讓你一步步瞭解 as2 和 as3 的差別 再安排製作動畫不可缺少的 Tweener 類別和一些常用的數學動畫公式 最後當然就來到本書的重點 PV3D 啦 從 PV3D 的原理, 基本架構一點一點的介紹 再透過許多實用的範例, 從中瞭解 PV3D 製作的小技巧 有任何書籍相關的問題, 也請不吝指教 感謝一路走來, 幫助過我的前輩們, 邦邦、Ticore、神魂、Maso、Erin 旗標出版社 小編 Bready 米蘭數位所有夥伴 米蘭數位ActionScript Team:Jason,Ash,Mark 本書大鋼: 1.ActionScript3.0概論 分析AS3的概念與語法, 從基本的滑鼠事件、外部載入、氣泡事件介紹起 適合熟悉AS2, 想轉戰AS3的人員。 2.程式碼製作動畫 使用簡單的數學公式, 套用到程式裡, 脫離死版的影格動畫。 3.製作動畫的好夥伴:Tweener 除了套用數學公式外, Tweener類別也能加速我們開發出更多的動畫效果, 不需辛辛苦苦的找公式。 4.自定類別 AS3的精神, 是在於強大的物件導向, 當然也要熟悉類別的寫法與使用。 5.Flash3D - Papervison3D 如果在Flash玩轉3D效果, PV3D是最好學, 最快上手的3D Flash Engine, 從簡單的3D概念, PV3D類別, 事件等。 6 漫天飛舞的Paper3DWorld效果 7 迷你旋轉木馬式秀圖效果 8 最經典! CoverFlow 圖像展示效果 9 天旋地轉 TiltViewer效果 10 FlatWall3D電視牆效果 11 經典旋轉木馬 Carousel3D 秀圖效果 12 光源材質展示與簡易型的方塊彈跳效果 13 載入外部3D模型與動畫 14 超立體旋轉九宮格 Box3DWorld 15 空間感與透明感兼具的 SpaceGallery 16 螺旋式 SpiralCarouse 影像展示 17 Flash10 3D功能 18 Flash效...

奶綠茶photoGalleryV3.5

奶小茶的photoGalleryV3.5原始檔 2007/12/30 更新小Bug,請重新下載 線上Demo: http://milkmidi.com/photogallery/galleryv3.html 1.支援SWFAddress,讓FLASH可以有上一頁下一頁和每張獨立網址的功能 2.圖片路徑圖說經由XML來設定 3.背景依據顯示圖片,自動變化成最接近的顏色 4.非商業用途,歡迎使用並修改(如果覺得我製作的好,也煩請加入我的logo) 5.可結合後端伺服器 00.art 相本集資料夾 com 奶綠茶的Class檔 swfaddress SWFAddress資料夾 swfobject swfobject資料夾 XML galleryV3.fla 原始檔 index.html 主檔html SWFAddress.as SWFaddressEvent.as Source Code Download 解壓密碼:回覆文章,即可看見Password