4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享

Posted qq_43479892

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享相关的知识,希望对你有一定的参考价值。

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

一、共享桌面原理

  • 共享桌面在直播系统中是一个必备功能
  • **共享者:**每秒钟抓取多次屏幕,每次抓取的屏幕都与上一次抓取的屏幕做比较,取它们的差值,然后对差值进行压缩;如果是第一次抓屏或切幕的情况,即本次抓取的屏幕与上一次抓取屏幕的变化率超过 80% 时,就做全屏的帧内压缩。最后再将压缩后的数据通过传输模块传送到观看端;数据到达观看端后,再进行解码,这样即可还原出整幅图片并显示出来
  • **远程控制端:**当用户通过鼠标点击共享桌面的某个位置时,会首先计算出鼠标实际点击的位置,然后将其作为参数,通过信令发送给共享端。共享端收到信令后,会模拟本地鼠标,即调用相关的 API,完成最终的操作
  • **共享桌面的过程:**抓屏、压缩编码、传输、解码、显示、控制

二、抓取桌面

  • 浏览器 WebRTC 中提供了方法 var promise = navigator.mediaDevices.getDisplayMedia(constraints) 进行桌面的抓取
  • 共享桌面,大多数人知道的可能是**RDP(Remote Desktop Protocal)**协议,它是 Windows 系统下的共享桌面协议;还有一种更通用的远程桌面控制协议 VNC(Virtual Network Console),它可以实现在不同的操作系统上共享远程桌面,而 TeamViewer、Todesk 都是使用的该协议
  • 远程桌面协议一般分为桌面数据处理与信令控制两部分
  • **桌面数据:**包括了桌面的抓取、编码、压缩、传输、解码和渲染
  • **信令控制:**包括键盘事件、鼠标事件以及接收到这些事件消息后的相关处理等
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 WebRTCtitle>
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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-62FrO8fr-1652417664746)(https://static001.geekbang.org/infoq/12/120cf2c955dcdaaa2c3e5c83c8e27ee5.png “共享屏幕提示”)]

三、桌面展示

  • 桌面采集后,就可以通过 HTML 中的标签将采集到的桌面展示出来
  • 当桌面数据被抓到之后,会触发 getDeskStream 函数
  • 在该函数中将获取到的 stream 与 video 标签联系起来,这样就可以显示桌面了
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 WebRTCtitle>
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 事件,最终将音视频流录制下来
  • 具体实现请参考上一篇文章自己进行完善
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 WebRTCtitle>
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>

WebRTC[38]- WEBRTC 与 WEBSOCKETS 的区别

以上是关于4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享的主要内容,如果未能解决你的问题,请参考以下文章

4┃音视频直播系统之浏览器中通过 WebRTC 进行桌面共享

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

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

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

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

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