音視頻的錄制音視頻的分為服務端錄制和客戶端錄制,下面主要講的是利用webrtc進行客戶端錄制的方式,
因為WebRTC 錄制音視頻流之后,最終是通過 Blob 物件將資料保存成多媒體檔案的,
-
Blob物件表示一個不可變、原始資料的類檔案物件,它的資料可以按文本或二進制的格式進行讀取,也可以轉換成ReadableStream來用于資料操作, -
Blob 表示的不一定是JavaScript原生格式的資料,
File介面基于Blob,繼承了 blob 的功能并將其擴展使其支持用戶系統上的檔案, -
要從其他非blob物件和資料構造一個
Blob,請使用Blob()建構式,要創建一個 blob 資料的子集 blob,請使用slice()方法,要獲取用戶檔案系統上的檔案對應的Blob物件, -
接受
Blob物件的API也被列在File檔案中,
了解完Blob的特性之后呢, 我們進入正題,
獲取元素宣告變數
let mediaRecorder;
let recordedBlobs;
const recordedVideo = document.querySelector('video#recorded');
const recordButton = document.querySelector('button#record');
const playButton = document.querySelector('button#play');
const downloadButton = document.querySelector('button#download');
系結點擊事件
-
URL.createObjectURL()靜態方法會創建一個DOMString,其中包含一個表示引數中給出的物件的URL,這個 URL 的生命周期和創建它的視窗中的document系結,這個新的URL 物件表示指定的File物件或Blob物件, -
URL.revokeObjectURL()靜態方法用來釋放一個之前已經存在的、通過呼叫URL.createObjectURL()創建的 URL 物件,當你結束使用某個 URL 物件之后,應該通過呼叫這個方法來讓瀏覽器知道不用在記憶體中繼續保留對這個檔案的參考了,你可以在sourceopen被處理之后的任何時候呼叫revokeObjectURL(),這是因為createObjectURL()僅僅意味著將一個媒體元素的src屬性關聯到一個MediaSource物件上去,呼叫revokeObjectURL()使這個潛在的物件回到原來的地方,允許平臺在合適的時機進行垃圾收集,
recordButton.addEventListener('click', () => {
if (recordButton.textContent === 'Start Recording') {
startRecording();
} else {
stopRecording();
recordButton.textContent = 'Start Recording';
playButton.disabled = false;
downloadButton.disabled = false;
}
});
playButton.addEventListener('click', () => {
const superBuffer = new Blob(recordedBlobs);
recordedVideo.src = null;
recordedVideo.srcObject = null;
recordedVideo.src = window.URL.createObjectURL(superBuffer);
recordedVideo.controls = true;
recordedVideo.play();
});
downloadButton.addEventListener('click', () => {
const blob = new Blob(recordedBlobs, {
type: 'video/webm'
});
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'test.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
});
document.querySelector('button#start').addEventListener('click', async () => {
const constraints = {
audio: {},
video: {
width: 1280,
height: 720
}
};
console.log('Using media constraints:', constraints);
await init(constraints);
});
點擊開始初始化
-
MediaDevices.getUserMedia()會提示用戶給予使用媒體輸入的許可,媒體輸入會產生一個MediaStream,里面包含了請求的媒體型別的軌道,此流可以包含一個視頻軌道(來自硬體或者虛擬視頻源,比如相機、視頻采集設備和螢屏共享服務等等)、一個音頻軌道(同樣來自硬體或虛擬音頻源,比如麥克風、A/D轉換器等等),也可能是其它軌道型別, -
它回傳一個
Promise物件,成功后會resolve回呼一個MediaStream物件,若用戶拒絕了使用權限,或者需要的媒體源不可用,promise會reject回呼一個PermissionDeniedError或者NotFoundError,
async function init(constraints) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
handleSuccess(stream);
} catch (e) {
console.error('navigator.getUserMedia error:', e);
}
}
function handleSuccess(stream) {
recordButton.disabled = false;
console.log('getUserMedia() got stream:', stream);
window.stream = stream;
const gumVideo = document.querySelector('video#gum');
gumVideo.srcObject = stream;
}
開始記錄方法
function startRecording() {
recordedBlobs = [];
try {
mediaRecorder = new MediaRecorder(window.stream);
} catch (e) {
console.error('Exception while creating MediaRecorder:', e);
return;
}
recordButton.textContent = 'Stop Recording';
playButton.disabled = true;
downloadButton.disabled = true;
mediaRecorder.onstop = (event) => {
console.log('Recorder stopped: ', event);
console.log('Recorded Blobs: ', recordedBlobs);
};
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
}
function handleDataAvailable(event) {
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta id="theme-color" name="theme-color" content="#ffffff">
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div id="container">
<video id="gum" playsinline autoplay muted></video>
<video id="recorded" playsinline loop></video>
<div>
<button id="start">Start camera</button>
<button id="record" disabled>Start Recording</button>
<button id="play" disabled>Play</button>
<button id="download" disabled>Download</button>
</div>
</div>
<script src="./main.js" async></script>
</body>
</html>
CSS
button {
background-color: #d84a38;
border: none;
border-radius: 2px;
color: white;
font-family: 'Roboto', sans-serif;
font-size: 0.8em;
margin: 0 0 1em 0;
padding: 0.5em 0.7em 0.6em 0.7em;
}
button:active {
background-color: #cf402f;
}
button:hover {
background-color: #cf402f;
}
button[disabled] {
color: #ccc;
}
button[disabled]:hover {
background-color: #d84a38;
}
div#container {
margin: 0 auto 0 auto;
max-width: 60em;
padding: 1em 1.5em 1.3em 1.5em;
}
video {
background: #222;
margin: 0 0 20px 0;
--width: 100%;
width: var(--width);
height: calc(var(--width) * 0.75);
}
webRTC功能是非常強大的,關于webrtc和直播還有很多技術需要我們去研究,上續呢是DEMO的示例代碼,感興趣的小伙伴可以親自試一試,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299048.html
標籤:其他
上一篇:opencv中的cvSRC1和convertto函式的區別
下一篇:HDMI介紹
