moztw.org

標準化的錄影API

當 HTML5 發展日漸成熟之際,在多媒體的輸出原生支援方面,目前已經支援了大多數網路常見的格式,所以開發者可以使用 
audio  或是 
video  tag 來進行影音播放控制。但輸入方面,目前各家瀏覽器並無統一的 API 實作,為解決此問題,W3C 委員會在 2013 年開始制定了MediaRecorder API[3],讓開發者可以有統一個的介面處理來自使用者端的照像機影像資料語麥克風的音訊資料,並加以壓縮成可以在網路傳遞的格式。

如果有常在關注謀智台客文章的,相信已經知道 
GetUserMedia  可以用來打電話,拍照,作語音辨識等等應用[2][4][5][6],但是直接利用此 API 取得的影音資料是未壓縮過的,將此種資料在網路上傳遞是當沒效率的。雖然 JavaScript 可以實作相對應的壓縮演算法來處理上述資料,但一般而言如果沒有使用平台提供最佳化的程式庫來加速並降低 CPU 使用率,將會面臨到嚴重的效率問題,更別提即時壓縮處理了。為了能達到支援即時錄制的效果,Mozilla 領先業界依據 W3C MediaStream Recording 規格書實作了 MediaRecorder API,至今此 API 目前已經可以在各個以Gecko 開發的平台使用囉。所以開發者可以使用此 API 進行開發,無論使用者使用了桌面版的 Firefox,移動版的 Firefox,甚至最夯的 Firefox OS 系統,皆可順利執行。因此 API 仍再更新,為避免不相容因素,建譯下載安裝 nightly 的版本來進行開發使用。

此 API 使用上相當簡單,首先要藉由 
navigator.getUserMedia  先取得 MediaStream 物件

navigator.getUserMedia = (navigator.getUserMedia || navigator.mozGetUserMedia);
if (navigator.getUserMedia) {
navigator.getUserMedia(
{
video:true,
audio:true
},
function(stream) { / do recording / }
function(error) { / do something / }
);
} else {
alert("Sorry, the browser you are using doesn\"t support getUserMedia");
return;
}

1234567891011121314

navigator.getUserMedia = (navigator.getUserMedia || navigator.mozGetUserMedia);if (navigator.getUserMedia) { navigator.getUserMedia( { video:true, audio:true }, function(stream) { / do recording / } function(error) { / do something / } );} else { alert("Sorry, the browser you are using doesn\"t support getUserMedia"); return;}

接下來,在 do recording 函式區塊中,加入處理 stream 的程式碼,並對已宣告的 
mediaRecorder  作初始化

mediaRecorder = new MediaRecorder(stream);

1

mediaRecorder = new MediaRecorder(stream);

那壓製過的影音資料跑那去了呢? 我們可以在呼叫 start 函式之前,宣告處理 
MediaRecorder  的 
ondataavailable  事件函式回傳的 callback blob object。此範利為將底層壓好的資料存入 
mBlob  物件。

mediaRecorder.ondataavailable = function(e) {
if (mBlob) {
mBlob = new Blob([mBlob, aData.data], {type: aData.data.type});
} else {
mBlob = new Blob([aData.data], {type: aData.data.type});
}
}

1234567

mediaRecorder.ondataavailable = function(e) { if (mBlob) { mBlob = new Blob([mBlob, aData.data], {type: aData.data.type}); } else { mBlob = new Blob([aData.data], {type: aData.data.type}); }}

加入開始按鈕在 
click  事件讓使用者開始錄影:

start.onclick = function() {
mediaRecorder.start();
}

123

start.onclick = function() { mediaRecorder.start();}

如果使用者想停止的話,則有按紐在 <span class="lang:js decode:true オンライン カジノ crayon-inline “>click  事件讓使用者停止錄影

stop.onclick = function() {
mediaRecorder.stop();
}

123

stop.onclick = function() { mediaRecorder.stop();}

如果要進行播放則可以使用 
video  tag 播放剛剛存在 
mBlob  的資料

play.onclick = function() {
_FReader = new FileReader();
_FReader.readAsDataURL(mBlob);
_FReader.onload = function (_FREvent) {
document.getElementById("videoelem").src = _FREvent.target.result;
document.getElementById("videoelem").play();
};
}

12345678

play.onclick = function() { _FReader = new FileReader(); _FReader.readAsDataURL(mBlob); _FReader.onload = function (_FREvent) { document.getElementById("videoelem").src = _FREvent.target.result; document.getElementById("videoelem").play(); };}

目前 mediaRecorder API 會直接錄製 MediaStream 包含的影音資料,

在呼叫 
getUserMedia  所傳進去的 
audio  或是 
video  布林值就需要決定產出的內容,因此我們可獲得有三種不同的產出。

*Audio Only

*Video Only

*Video Audio


mediaRecorder 在實作時為了達到最佳化,則產出的影音格式有些許不同,表列如下

平台
Video
Audio
Audio Video

Firefox on Desktop
WebM opus
opus
WebM

Firefox on Android
N/A[1]
opus
N/A
[1]

Firefox OS
mp4
opus
mp4

[1] 尚未實作

以上範例大家可以參考下列網址相關的程式碼:

MediaStream Recording Test Landing Page

參考資料:

[2]過年不忘長知識!啥?瀏覽器也可以開視訊會議

[3]MediaStream Recording

[4]Using the MediaRecorder API

[5]Capturing Audio & Video in HTML5

[6]Speech Recognition in JavaScript