一、共享桌面原理

  • 共享桌面在直播系统中是一个必备功能

  • 共享者:每秒钟抓取多次屏幕,每次抓取的屏幕都与上一次抓取的屏幕做比较,取它们的差值,然后对差值进行压缩;如果是第一次抓屏或切幕的情况,即本次抓取的屏幕与上一次抓取屏幕的变化率超过 80% 时,就做全屏的帧内压缩。最后再将压缩后的数据通过传输模块传送到观看端;数据到达观看端后,再进行解码,这样即可还原出整幅图片并显示出来

  • 远程控制端:当用户通过鼠标点击共享桌面的某个位置时,会首先计算出鼠标实际点击的位置,然后将其作为参数,通过信令发送给共享端。共享端收到信令后,会模拟本地鼠标,即调用相关的 API,完成最终的操作

  • 共享桌面的过程:抓屏、压缩编码、传输、解码、显示、控制

二、抓取桌面

  • 浏览器 WebRTC 中提供了方法 var promise = navigator.mediaDevices.getDisplayMedia(constraints) 进行桌面的抓取

  • 共享桌面,大多数人知道的可能是RDP(Remote Desktop Protocal)协议,它是 Windows 系统下的共享桌面协议;还有一种更通用的远程桌面控制协议 VNC(Virtual Network Console),它可以实现在不同的操作系统上共享远程桌面,而 TeamViewer、Todesk 都是使用的该协议

  • 远程桌面协议一般分为桌面数据处理与信令控制两部分

  • 桌面数据:包括了桌面的抓取、编码、压缩、传输、解码和渲染

  • 信令控制:包括键盘事件、鼠标事件以及接收到这些事件消息后的相关处理等

<!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>share desktop by WebRTC</title>
</head> <body>
<button onclick="shareDesktop()">抓取桌面</button>
</body>
<script>
// 抓取桌面
function shareDesktop() {
// 只有在 PC 下才能抓取桌面
if (IsPC()) {
// 开始捕获桌面数据
navigator.mediaDevices.getDisplayMedia({ video: true })
.then(getDeskStream)
.catch(handleError);
return true;
}
return false;
} // 得到桌面数据流
function getDeskStream(stream) {
localStream = stream;
} // 判断是否是PC
function IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
</script> </html>

三、桌面展示

  • 桌面采集后,就可以通过 HTML 中的<video>标签将采集到的桌面展示出来

  • 当桌面数据被抓到之后,会触发 getDeskStream 函数

  • 在该函数中将获取到的 stream 与 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>share desktop by WebRTC</title>
</head> <body>
<video autoplay playsinline id="deskVideo"></video>
<button onclick="shareDesktop()">抓取桌面</button>
</body>
<script>
var deskVideo = document.querySelect("video/deskVideo"); // 抓取桌面
function shareDesktop() {
// 只有在 PC 下才能抓取桌面
if (IsPC()) {
// 开始捕获桌面数据
navigator.mediaDevices.getDisplayMedia({ video: true })
.then(getDeskStream)
.catch(handleError);
return true;
}
return false;
} // 得到桌面数据流并播放
function getDeskStream(stream) {
localStream = stream;
deskVideo.srcObject = stream;
} // 判断是否是PC
function IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
</script> </html>

四、录制桌面视频

  • 录制视频其实在上一章中详细说过,这里就不再重复了,这里只贴一下大概的逻辑代码

  • 首先通过 getDisplayMedia 方法获取到本地桌面数据

  • 然后将该流当作参数传给 MediaRecorder 对象

  • 并实现 ondataavailable 事件,最终将音视频流录制下来

  • 具体实现请参考上一篇文章自己进行完善

<!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>share desktop by WebRTC</title>
</head> <body>
<button onclick="startRecord()">开始录制</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(localStream, options);
} catch (e) {
console.error('Failed to create MediaRecorder:', e);
return;
}
// 当捕获到桌面数据后,该事件触发
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(10);
} function handleDataAvailable(e) {
if (e && e.data && e.data.size > 0) {
buffer.push(e.data);
}
}
</script> </html>

4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享的更多相关文章

  1. 3┃音视频直播系统之浏览器中通过 WebRTC 直播视频实时录制回放下载

    一.录制分类 在音视频会议.在线教育等系统中,录制是一个特别重要的功能 录制一般分为服务端录制和客户端录制 服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢 ...

  2. 1┃音视频直播系统之浏览器中通过WebRTC访问摄像头

    一.WebRTC的由来 对于前端开发小伙伴而言,如果用 JavaScript 做音视频处理 在以前是不可想象的,因为首先就要考虑浏览器的性能是否跟得上音视频的采集 但是 Google 作为国际顶尖科技 ...

  3. 2┃音视频直播系统之浏览器中通过 WebRTC 拍照片加滤镜并保存

    一.拍照原理 好多人小时候应该都学过,在几张空白的纸上画同一个物体,并让物体之间稍有一些变化,然后连续快速地翻动这几张纸,它就形成了一个小动画,音视频播放器就是利用这样的原理来播放音视频文件的 播放器 ...

  4. 5┃音视频直播系统之 WebRTC 中的协议UDP、TCP、RTP、RTCP详解

    一.UDP/TCP 如果让你自己开发一套实时互动直播系统,在选择网络传输协议时,你会选择使用UDP协议还是TCP协议 假如使用 TCP 会怎样呢?在极端网络情况下,TCP 为了传输的可靠性,将会进行反 ...

  5. 10┃音视频直播系统之 WebRTC 中的数据统计和绘制统计图形

    一.数据统计 在视频直播中,还有一项比较重要,那就是数据监控 比如开发人员需要知道收了多少包.发了多少包.丢了多少包,以及每路流的流量是多少,才能评估出目前用户使用的音视频产品的服务质量是好还是坏 如 ...

  6. 12┃音视频直播系统之 WebRTC 实现1对1直播系统实战

    一.搭建 Web 服务器 前面我们已经实现过,但是没有详细说HTTPS服务 首先需要引入了 express 库,它的功能非常强大,用它来实现 Web 服务器非常方便 同时还需要引入 HTTPS 服务, ...

  7. 8┃音视频直播系统之 WebRTC 信令系统实现以及通讯核心并实现视频通话

    一.信令系统 信令系统主要用来进行信令的交换 在通信双方彼此连接.传输媒体数据之前,它们要通过信令服务器交换一些信息,如规范协商 若 A 与 B 要进行音视频通信,那么 A 要知道 B 已经上线了,同 ...

  8. H264音视频直播系统 服务器端+客户端源码 可用于直播系统搭建

    RTP协议实现直播系统搭建,采用H.264和AAC编码,码率极低,同时有较高的视频清晰度和音频音质,可用于视频聊天.视频会议.摄像头监控等多种应用场景. 直播系统搭建发布端,选择视频和音频设备,指定服 ...

  9. 6┃音视频直播系统之 WebRTC 核心驱动SDP规范协商

    一.什么是SDP SDP(Session Description Protocal)其实就是当数据过来时候,告诉数据自己这里支持的解码方式.传输协议等等,这样数据才能根据正确的方式进行解码使用 SDP ...

随机推荐

  1. openldap 资料

    LDAP概念和原理介绍 相信对于许多的朋友来说,可能听说过LDAP,但是实际中对LDAP的了解和具体的原理可能还比较模糊,今天就从"什么是LDAP"."LDAP的主要产品 ...

  2. (stm32f103学习总结)—can总线

    参考:CAN总线的位时序与参数设置 CAN总线位同步 1 CAN总线介绍 CAN 是Controller Area Network 的缩写,中文意思是控制器局域网 络,是ISO国际标准化的串行通信协议 ...

  3. 全面系统讲解CSS工作应用+面试一步搞定

    [TOC] 一.课程介绍 二.HTML基础强化 html常见元素和理解 html常见元素分类 head区元素:(不会在页面上留下元素) * meta * title * style * link * ...

  4. 使用Dropbox搭建静态网站详细教程

    DropBox是一款非常好用的免费网络文件同步工具,是Dropbox公司运行的在线存储服务,通过云计算实现因特网上的文件同步,用户可以存储并共享文件和文件夹.今天小z和大家分享一下如何使用dropbo ...

  5. 微信小程序&mpvue问题总结(1)

    微信小程序进入到首页的时候,日志打印出"created", "onlaunch", "mounted",具体代码如下:那么,在小程序中 cr ...

  6. 将word文件转为excel文件

    有些word文件里的数据是有顺序或者规律,想转成表格的形式,下面就以我要转的word为例. 我的word文件是这样的 1.word转txt(文本文件) 文件--->另存为--->路径--- ...

  7. 猿人学python爬虫第一题

    打开网站.F12,开启devtools.发现有段代码阻止了我们调试 好的.接下来有几种解决方法 1- 绕过阻止调试方法 方法1(推荐) 鼠标放在debugger该行,左边数字行号那一列.右键选择不在永 ...

  8. Spring相关的API-ApplicationContext

    1.ClassPathXmlApplicationContext 它是从类的根路径下加载配置文件推荐使用这种 public class UserController { public static v ...

  9. 在原有mysql机器上增加一台实例

    采用的是yum install mysql-community-server yum方式安装mysql(社区版) 文章基础上新加一个mysql实例. 这个完全可以直接实战上应用,只要规划好即可 服务器 ...

  10. 前端CSS基础

    一:CSS 1.什么是CSS? CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). C ...