WebRTC有分享屏幕的功能。使用的是getDisplayMedia方法。用户同意分享屏幕后,可以拿到视频流。

再结合MediaRecorderBlob,把视频流数据存下来,就能得到录制屏幕的视频。

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="https://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本地分享屏幕,录制屏幕

WebRTC本地分享屏幕,录制屏幕的更多相关文章

  1. 录制Android屏幕软件——屏幕录像专家

    本文不是技术文章,今天分享下录制屏幕的软件.这个软件的效果还是不错的,前提是需要Root.软件名字:屏幕录像专家 来源网址:http://www.mumayi.com/android-350180.h ...

  2. 【Android应用开发】分享一个录制 Android 屏幕 gif 格式的小技巧

    因为写博客总是需要录制 Android 软件的演示效果, 研究了将近一小时找到了合适的工具; 录制流程 : -- 1. 录制 Android 手机屏幕内容 : 使用 拍大师 软件录制 Android ...

  3. Android屏幕录制

    自己实现了Android的屏幕录制App. 用了MediaProjection类来作为源,MediaRecoder来捕捉,编码转换为本地视频. 效果图: 主要是这段代码开始录像: startActiv ...

  4. Android 屏幕录制

    自己实现了Android的屏幕录制App. 用了MediaProjection类来作为源,MediaRecoder来捕捉,编码转换为本地视频. 效果图: 主要是这段代码开始录像: startActiv ...

  5. Android 录制屏幕的实现方法

    Android 录制屏幕的实现方法 Chrome   2017-02-15 15:32:01 发布 您的评价:       5.0   收藏     0收藏 长久以来,我一直希望能够直接从Androi ...

  6. anyRTC iOS端屏幕录制开发指南

    一. 概述 实现直播过程中共享屏幕分为两个步骤:屏幕数据采集和流媒体数据推送.前对于 iOS 来说,屏幕采集需要系统的权限,受制于iOS系统的限制,第三方 app 并没有直接录制屏幕的权限,必须通过系 ...

  7. iOS 屏幕录制实现

    iOS 屏幕录制实现 目录 iOS 屏幕录制实现 录屏API版本变化 App内部录制屏幕 录音麦克风声音 App内部录屏直播 Bonjour APP广播端实现 广播端App(直播平台)的实现 iOS1 ...

  8. C#实现录制屏幕

    以前写过两篇录制麦克风语音和摄像头视频的文章(实现语音视频录制.在服务器端录制语音视频),最近有朋友问,如果要实现屏幕录制这样的功能,该怎么做了?实际上原理是差不多的,如果了解了我前面两篇文章中介绍的 ...

  9. C# 与 Microsoft Expression Encoder实现屏幕录制

    在日常开发中,我们会经常遇到屏幕录制的需求.在C#中可以通过Expression Encoder的SDK实现这样的需求.首先需要下载Expression Encoder SDK,实现代码: priva ...

随机推荐

  1. linux下的IO模型---学习笔记

    1.linux文件系统和缓存 文件系统接口 文件系统-一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问. 存储层次 文件系统缓存 主存(通常时DRAM)的一块区域 ...

  2. 『学了就忘』Linux基础 — 6、VMware虚拟机安装Linux系统(超详细)

    目录 1.打开VMware虚拟机软件 2.选择Linux系统的ISO安装镜像 3.开启虚拟机安装系统 (1)进入Linux系统安装界面 (2)硬件检测 (3)检测光盘 (4)欢迎界面 (5)选择语言 ...

  3. Android App隐私合规检测辅助工具(Camille)

    Camille Android App隐私合规检测辅助工具,项目仓库:https://github.com/zhengjim/camille 简介 现如今APP隐私合规十分重要,各监管部门不断开展AP ...

  4. Burp Suite Pro 2021.10 Full (macOS, Linux) -- 查找、发现和利用漏洞

    申明:底层组件来自网络论坛或开源社区的分享,本站所有软件免费分享,仅供学习和测试使用,严禁用于任何商业用途!!! 请访问原文链接:https://sysin.cn/blog/burp-suite-pr ...

  5. spark structured-streaming 最全的使用总结

    一.spark structured-streaming  介绍 我们都知道spark streaming  在v2.4.5 之后 就进入了维护阶段,不再有新的大版本出现,而且 spark strea ...

  6. TCP粘"包"问题浅析及解决方案Golang代码实现

    一.粘"包"问题简介 在socket网络编程中,都是端到端通信,客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一条连接.在TCP的sock ...

  7. 无法复现的“慢”SQL《死磕MySQL系列 八》

    系列文章 四.S 锁与 X 锁的爱恨情仇<死磕MySQL系列 四> 五.如何选择普通索引和唯一索引<死磕MySQL系列 五> 六.五分钟,让你明白MySQL是怎么选择索引< ...

  8. LeetCode刷题 DFS+回溯

    一.DFS介绍 二.LeetCode 实战 LC 17. 电话号码的字母组合 解法思路 解题步骤 代码 LC 79. 单词搜索 解题思路 解题步骤 代码 LC 46. 全排列 解题思路一 解题步骤 代 ...

  9. 如何解决Redis缓存雪崩、缓存穿透

    缓存雪崩 数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机. 比如一个雪崩的简单过程: 1.redis集群大面积故障 2.缓存失 ...

  10. 001.AD域控简介及使用

    一 AD概述 1.1 AD简介 域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系. 当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可 ...