4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享
一、共享桌面原理
共享桌面在直播系统中是一个必备功能
共享者:每秒钟抓取多次屏幕,每次抓取的屏幕都与上一次抓取的屏幕做比较,取它们的差值,然后对差值进行压缩;如果是第一次抓屏或切幕的情况,即本次抓取的屏幕与上一次抓取屏幕的变化率超过 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 进行桌面共享的更多相关文章
- 3┃音视频直播系统之浏览器中通过 WebRTC 直播视频实时录制回放下载
一.录制分类 在音视频会议.在线教育等系统中,录制是一个特别重要的功能 录制一般分为服务端录制和客户端录制 服务端录制:优点是不用担心客户因自身电脑问题造成录制失败(如磁盘空间不足),也不会因录制时抢 ...
- 1┃音视频直播系统之浏览器中通过WebRTC访问摄像头
一.WebRTC的由来 对于前端开发小伙伴而言,如果用 JavaScript 做音视频处理 在以前是不可想象的,因为首先就要考虑浏览器的性能是否跟得上音视频的采集 但是 Google 作为国际顶尖科技 ...
- 2┃音视频直播系统之浏览器中通过 WebRTC 拍照片加滤镜并保存
一.拍照原理 好多人小时候应该都学过,在几张空白的纸上画同一个物体,并让物体之间稍有一些变化,然后连续快速地翻动这几张纸,它就形成了一个小动画,音视频播放器就是利用这样的原理来播放音视频文件的 播放器 ...
- 5┃音视频直播系统之 WebRTC 中的协议UDP、TCP、RTP、RTCP详解
一.UDP/TCP 如果让你自己开发一套实时互动直播系统,在选择网络传输协议时,你会选择使用UDP协议还是TCP协议 假如使用 TCP 会怎样呢?在极端网络情况下,TCP 为了传输的可靠性,将会进行反 ...
- 10┃音视频直播系统之 WebRTC 中的数据统计和绘制统计图形
一.数据统计 在视频直播中,还有一项比较重要,那就是数据监控 比如开发人员需要知道收了多少包.发了多少包.丢了多少包,以及每路流的流量是多少,才能评估出目前用户使用的音视频产品的服务质量是好还是坏 如 ...
- 12┃音视频直播系统之 WebRTC 实现1对1直播系统实战
一.搭建 Web 服务器 前面我们已经实现过,但是没有详细说HTTPS服务 首先需要引入了 express 库,它的功能非常强大,用它来实现 Web 服务器非常方便 同时还需要引入 HTTPS 服务, ...
- 8┃音视频直播系统之 WebRTC 信令系统实现以及通讯核心并实现视频通话
一.信令系统 信令系统主要用来进行信令的交换 在通信双方彼此连接.传输媒体数据之前,它们要通过信令服务器交换一些信息,如规范协商 若 A 与 B 要进行音视频通信,那么 A 要知道 B 已经上线了,同 ...
- H264音视频直播系统 服务器端+客户端源码 可用于直播系统搭建
RTP协议实现直播系统搭建,采用H.264和AAC编码,码率极低,同时有较高的视频清晰度和音频音质,可用于视频聊天.视频会议.摄像头监控等多种应用场景. 直播系统搭建发布端,选择视频和音频设备,指定服 ...
- 6┃音视频直播系统之 WebRTC 核心驱动SDP规范协商
一.什么是SDP SDP(Session Description Protocal)其实就是当数据过来时候,告诉数据自己这里支持的解码方式.传输协议等等,这样数据才能根据正确的方式进行解码使用 SDP ...
随机推荐
- runnable 和 callable 有什么区别
callable 有返回值,并允许抛出异常 runnable 没有返回值,不会抛出异常
- npm run start 后台运行
yum provides */nohup nohup npm start & 原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了log的作用. 停止程序 ps -ef ...
- BMZCTF WEB_ezeval
WEB_ezeval 进入环境,源码给出 <?php highlight_file(__FILE__); $cmd=$_POST['cmd']; $cmd=htmlspecialchars($c ...
- Numpy使用Matplotlib实现可视化绘图
Numpy使用Matplotlib实现可视化绘图 可以直接将Numpy的数组传给Matplotlib实现可视化绘图: 曲线图 饼图 柱状图 直方图 1. 绘制正弦曲线 2. 绘制饼图 3. 柱状图 4 ...
- 通过HTML5的getUserMedia实现拍照功能
参考HTML5Rocks的这篇文章实现的一个简单的例子. 思路如下: 1. 把冰箱门打开 2. 把大象放进冰箱里 3. 把冰箱门关上 好了不开玩笑了,其实思路是: 1. 通过getUserMedia调 ...
- 设计一个基于svg的涂鸦组件(一)
基于svg写了一个涂鸦组件,说项目之前先附上几张效果图: 项目地址:SVGraffiti 由于篇幅问题,本文先总体介绍一下项目的大概情况,重点介绍一下组件间的通信方式. 一.项目说明 该项目是基于we ...
- Python窗口学习之给按钮美化
tkinter的按钮很丑也很难改 怎么办呢? 最好的方法就是不用按钮! 给Label添加点击事件,和按钮的作用是一样的! 代码: #!/usr/bin/env python # -*- coding: ...
- Linux安装JDK报错
报错内容: tar (child): jdk-8u141-linux-x64.tar.gz: Cannot open: No such file or directory tar (child): E ...
- 微信小程序下拉加载和上拉刷新两种实现方法
方法一:onPullDownRefresh和onReachBottom方法实现小程序下拉加载和上拉刷新 首先要在json文件里设置window属性 设置js里onPullDownRefresh和onR ...
- 关于json对象的使用小结!
json是前后端数据交互的关键.后端提供的接口中的数据几乎都是通过json来表现的,所以,需要对这个json做一些小结: 这里要推进谷歌的插件Fehelp前端助手,这个可以清楚的看到json的数据: ...