WebRTC本地分享螢幕,錄製螢幕
WebRTC有分享螢幕的功能。使用的是getDisplayMedia
方法。用戶同意分享螢幕後,可以拿到影片流。
再結合MediaRecorder和Blob,把影片流數據存下來,就能得到錄製螢幕的影片。
html
照例先來擺放一些元素在介面上
<div id="container">
<h3>WebRTC捕捉螢幕示例 getDisplayMedia</span></h1>
<video id="gum-local" autoplay playsinline muted></video>
<button id="startBtn" disabled>開始預覽</button>
<button id="recordBtn" disabled>開始錄製</button>
<button id="downloadBtn" disabled>下載</button>
<div id="msg"></div>
</div>
<!-- 使用本地的適配器 -->
<script src="../js/adapter-latest.js" async></script>
<script src="js/main.js"></script>
因為我的網速不是很好,把adapter文件下載到本地來用了。
如果要使用官方的適配器adapter,按下邊的地址來引入
<script src="//webrtc.github.io/adapter/adapter-latest.js"></script>
- video 用來預覽影片。開始分享影片後,把影片流交給它
- 放置一些按鈕,處理交互
- div#msg 用來顯示資訊
控制
在main.js文件里寫上我們的控制邏輯
先把獲取元素
'use strict';
const startBtn = document.getElementById('startBtn');
const recordBtn = document.getElementById('recordBtn');
const downloadBtn = document.getElementById('downloadBtn');
const video = document.querySelector('video'); // 預覽用的
let mediaRecorder;
let isRecording = false;
let recordedBlobs = []; // 暫存影片數據的地方
啟動螢幕分享
主要利用getDisplayMedia
方法。我們這裡只使用影片video: true
startBtn.addEventListener('click', () => {
navigator.mediaDevices.getDisplayMedia({video: true})
.then(gotDisplayStream, onErr);
});
// 拿到螢幕數據流
function gotDisplayStream(stream) {
startBtn.disabled = true;
video.srcObject = stream; // 顯示出來
window.stream = stream; // 快取一下
stream.getVideoTracks()[0].addEventListener('ended', () => {
showMsg('用戶停止了分享螢幕');
startBtn.disabled = false;
recordBtn.disabled = true;
});
recordBtn.disabled = false;
}
function onErr(error) {
showMsg(`getDisplayMedia on err: ${error.name}`, error);
}
function showMsg(msg, error) {
const msgEle = document.querySelector('#msg');
msgEle.innerHTML += `<p>${msg}</p>`;
if (typeof error !== 'undefined') {
console.error(error);
}
}
拿到影片流後,交給video
顯示。
給影片流添加事件監聽器,如果停止了分享,我們能獲得事件。
在這一步,把其它ui元素注釋掉,已經可以測試分享螢幕的效果了。
Chrome和edge會詢問用戶是否分享螢幕,並讓用戶選擇要分享的介面。mac會需要用戶修改隱私設定。
同意後,就能看到分享螢幕的效果了。
???+ note “移動端”
在手機chrome上無法分享
錄屏
上一步我們拿到了影片流。可以仿照之前的方法把影片流數據存下來。
先來找到瀏覽器支援的影片格式。為了簡化操作,後面我們只選用第一種支援的格式。
// 找到支援的格式
function getSupportedMimeTypes() {
const possibleTypes = [
'video/webm;codecs=vp9,opus',
'video/webm;codecs=vp8,opus',
'video/webm;codecs=h264,opus',
'video/mp4;codecs=h264,aac',
];
return possibleTypes.filter(mimeType => {
return MediaRecorder.isTypeSupported(mimeType);
});
}
開始錄製
把影片流數據推進recordedBlobs
。
當然這裡只是試用,實際上這麼多數據存在記憶體里不妥。
function startRecording() {
recordedBlobs = [];
const mimeType = getSupportedMimeTypes()[0];
const options = { mimeType };
try {
mediaRecorder = new MediaRecorder(window.stream, options);
} catch (e) {
showMsg(`創建MediaRecorder出錯: ${JSON.stringify(e)}`);
return;
}
recordBtn.textContent = '停止錄製';
isRecording = true;
downloadBtn.disabled = true;
mediaRecorder.onstop = (event) => {
showMsg('錄製停止了: ' + event);
};
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
showMsg('錄製開始 mediaRecorder: ' + mediaRecorder);
}
function handleDataAvailable(event) {
console.log('handleDataAvailable', event);
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}
停止錄製
mediaRecorder.stop()
function stopRecord() {
isRecording = false;
mediaRecorder.stop();
downloadBtn.disabled = false;
recordBtn.textContent = "開始錄製";
}
下載
把recordedBlobs
里的數據打包好下載下來
downloadBtn.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 = '錄屏_' + new Date().getTime() + '.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
});
小結
我們使用了WebRTC的getDisplayMedia
方法分享螢幕。並結合之前了解的下載影片方法,實現了簡易的錄螢幕下載效果。
{% include ‘webrtc-web-menu.md’ %}
效果
原文鏈接 WebRTC本地分享螢幕,錄製螢幕