一、錄製分類
-
在音視訊會議、線上教育等系統中,錄製是一個特別重要的功能
-
錄製一般分為服務端錄製和客戶端錄製
-
服務端錄製:優點是不用擔心客戶因自身電腦問題造成錄製失敗(如磁碟空間不足),也不會因錄製時搶佔資源(CPU 佔用率過高)而導致其他應用出現問題等;缺點是實現的複雜度很高。
-
客戶端錄製:優點是方便錄製方(如老師)操控,並且所錄製的視訊清晰度高,實現相對簡單。但是它對記憶體、硬碟的要求 比較高
-
它們各有優劣,因此大系統一般會同時支援客戶端錄製與服務端錄製。
二、錄製思考
-
第一:錄製後音視訊流的儲存格式是什麼呢?是直接錄製原始資料,還是錄製成某種多媒體格式(如 MP4 )
-
第二:錄製下來的音視訊流如何播放?是使用普通的播放器播放,還是使用私有播放器,如果你的業務是多人互動型別,且回放時也要和直播時一樣,那麼你就必須使用私有播放器,因為普通播放器是不支援同時播放多路視訊的
-
第三:啟動錄製後多久可以回放呢?錄製完立即回放?邊錄邊看?錄完後過一段時間可觀看?
-
錄製完立即回放當然體驗性最好,但是清晰度卻不行,在平時的直播中應該有所體驗;錄完一段時間再觀看,可以對視訊進行轉碼獲得更好的清晰度,但是對使用者的體驗卻不好,不能實時觀看。
三、錄製音視訊
-
WebRTC 錄製音視訊流之後,最終是通過 Blob 物件將資料儲存成多媒體檔案的
-
Blob(Binary Large Object)是 JavaScript 的大型二進位制物件型別
var aBlob = new Blob(array, options);
-
WebRTC 中提供了
MediaRecorder
類去錄製本地音視訊var mediaRecorder = new MediaRecorder(stream[, options]);
-
stream:通過 getUserMedia 獲取的本地視訊流或通過
RTCPeerConnection
獲取的遠端視訊流 -
options:可選項,指定視訊格式、編解碼器、位元速率等相關資訊,如
mimeType: 'video/webm;codecs=vp8'
-
MediaRecorder 物件還有一個特別重要的事件,即 ondataavailable 事件。當 MediaRecoder 捕獲到資料時就會觸發該事件。通過它,我們才能將音視訊資料錄製下來
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>video of WebRTC</title>
</head>
<body>
<button onclick="startRecord()">Start Record</button>
</body>
<script>
var buffer;
function startRecord() {
buffer = [];
// 設定錄製下來的多媒體格式
var options = {
mimeType: 'video/webm;codecs=vp8'
}
// 判斷瀏覽器是否支援錄製
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error(`${options.mimeType} is not supported!`);
return;
}
try {
// 建立錄製物件
mediaRecorder = new MediaRecorder(window.stream, options);
} catch (e) {
console.error('Failed to create MediaRecorder:', e);
return;
}
// 當有音視訊資料來了之後觸發該事件
mediaRecorder.ondataavailable = handleDataAvailable;
// 開始錄製
// 在開啟錄製時,可以設定一個毫秒級的時間片,這樣錄製的媒體資料會按照你設定的
// 值分割成一個個單獨的區塊,否則預設的方式是錄製一個非常大的整塊內容。
// 分成一塊一塊的區塊會提高效率和可靠性,如果是一整塊資料,隨著時間的推移,資料塊越來越大
// 讀寫效率就會變差,而且增加了寫入檔案的失敗率
mediaRecorder.start(10);
}
// 當該函式被觸發後,將資料壓入到 blob 中
function handleDataAvailable(e) {
if (e && e.data && e.data.size > 0) {
buffer.push(e.data);
}
}
</script>
</html>
四、回放錄製視訊
-
通過上面的方法錄製好內容 壓入到 blob 以後
-
首先根據 buffer 生成 Blob 物件
-
然後,根據 Blob 物件生成 URL,並通過 <video> 標籤將錄製的內容播放出來了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>video of WebRTC</title>
</head>
<body>
<video id="recvideo"></video>
<button onclick="recplay()" disabled>Play</button>
</body>
<script>
var buffer;
function recplay() {
var blob = new Blob(buffer, {type: 'video/webm'});
recvideo.src = window.URL.createObjectURL(blob);
recvideo.srcObject = null;
recvideo.controls = true;
recvideo.play();
}
</script>
</html>
五、下載錄製視訊
-
也是先建立一個 Blob 物件,並根據 Blob 物件建立 URL;
-
然後再建立一個 <a> 標籤,設定 a 標籤的 href 和 download 屬性
-
這樣當使用者點選該標籤之後,錄製好的檔案就下載下來了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>video of WebRTC</title>
</head>
<body>
<button onclick="download()" disabled>Download</button>
</body>
<script>
var buffer;
function download() {
var blob = new Blob(buffer, {type: 'video/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.style.display = 'none';
a.download = '下載的視訊.webm';
a.click();
}
</script>
</html>