WebRTC本地分享屏幕,录制屏幕

WebRTC有分享屏幕的功能。使用的是getDisplayMedia方法。用户同意分享屏幕后,可以拿到视频流。
再结合MediaRecorder和Blob,把视频流数据存下来,就能得到录制屏幕的视频。
html 照例先来摆放一些元素在界面上

WebRTC捕捉屏幕示例 getDisplayMedia

因为我的网速不是很好,把adapter文件下载到本地来用了。
如果要使用官方的适配器adapter,按下边的地址来引入

  • 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 += `${msg}
`; 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 = https://www.it610.com/article/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本地分享屏幕,录制屏幕】原文链接 WebRTC本地分享屏幕,录制屏幕

    推荐阅读