屏幕共享的英文叫做 DesktopSharing,通俗点讲就是将自己电脑的画面分享给其他人, 被分享的可以是整个电脑屏幕、应用程序或者某一个打开的网页等等。

而随着音视频领域的深入发展,完备的功能在用户需求激增的背景下催生,不管是是在学习、生活或是娱乐场景下,屏幕共享作为实现互动的一种方式被越来越多的用户应用在日常生活中:

1、远程协作(TeamViewer):控制远程计算机,完成协作等;

2、在线会议:参会者只需在自己的电脑屏幕上查看共享的文件材料,并观看文件演示等;

3、在线课堂:屏幕共享可以将老师的课件、笔记、讲课内容等画面展示给学生观看等;

......

由此可见,屏幕共享这个衍生功能已经在越来越多的场景上成功使用,那么该如何实现屏幕共享呢?本篇文章我们将详细介绍在 Web 端的屏幕共享实践

Web 端如何实现屏幕捕捉

Web 端浏览器可以实现屏幕共享么? 在电脑端是可以做到的。屏幕共享分为两个步骤:屏幕捕捉 + 流媒体传输

屏幕捕捉: 获取数据, 为流媒体传输提供数据源;

流媒体传输: 将音视频数据从一个客户端传输到另一个客户端。当前比较成熟的方案是使用WebRTC协议提供的低延迟和抗弱网能力以此来保证体验;

WebRTC 协议要求提供的流数据必须是 MediaStream 对象,所以屏幕采集的流也必须是 MediaStream 类型。我们先以电脑端  Chrome 72 为例 ( 不同浏览器写法会有点不一样),捕捉屏幕画面代码是这样的:

async function startCapture(displayMediaOptions){
let captureStream = null;
try{
captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
}catch(err){
console.error("Error: "+ err);
}
return captureStream;
}

效果如下:

(示例demo地址:Screen Sharing

关键语法:

//  constraints 参数可参考https://developer.mozilla.org/zhCN/docs/Web/API/MediaDevices/getDisplayMedia
let promise = navigator.mediaDevices.getDisplayMedia(constraints);

屏幕捕捉兼容性问题及应对方案

作为 Web 前端开发,相信这个问题是大家比较关心的,目前屏幕捕捉接口兼容情况比较复杂,仅支持在以下桌面端浏览器中进行屏幕捕捉:

  • Chrome 58 或以上版本

  • Firefox 56 或以上版本

  • Edge 80 及以上版本

  • macOS 的 Safari  13 及以上版本

其中Chrome浏览器还可以进一步分为: 有插件和无插件。

  • 有插件: 需要在浏览器上额外安装插件, 利用 Chrome 提供的能力捕捉屏幕,插件方式可以在较低版本上实现捕捉;

  • 无插件: 不用额外安装任何插件, 但要求 Chrome 必须是 72 及以上版本。

Chrome 浏览器如果要支持音频分享, 无插件方式必须要是 Chrome 74 及以上版本,Safari 浏览器目前则只支持分享整个屏幕,无法选择应用程序和浏览器页面。

清楚浏览器兼容情况后,就可以针对浏览器进行判断了,大致思路是通过 navigator.appVersion 判断浏览器类型/平台/版本,并对接口做是否存在的判断,在正式业务开始前,提前感知浏览器是否支持该能力。

代码写起来是纯体力活,如果不想对浏览器类型和版本一一处理,ZEGO 即构科技的 zego-express-engine-webrtc.js 帮大家做好了内部兼容, 并提供检测接口方便快速上手

点击查看:Web JavaScript 实时音视频 SDK 屏幕共享 - 开发者中心 - ZEGO即构科技

浏览器实现自定义尺寸分享

我们看浏览器提供的接口, 无论是什么浏览器类型或版本,最小粒度只能捕捉到一个页面,如果要分享的页面或者程序有比较敏感的信息,不希望全部被分享出去,我们应该怎么办呢?

只看浏览器接口是没有办法实现的,不过 MediaStream 对象还可以从 video 或者 canvas 这类媒体标签上获取。如果把捕捉到的流媒体对象渲染到画布上,再从画布上截取我们想要分享的部分画面,就可以实现指定尺寸分享了。

实现伪代码如下:

// 获取屏幕捕捉流
let screenStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions); // 创建画布
const ctx = canvas.getContext('2d'); // 滚动渲染视频
let timer = null;
function videoDrawInCanvas(){
timer = setTimeout(async () => {
videoDrawInCanvas( ctx, source, canvas, videoX, videoY, videoWidth, videoHeight);
}, 60);
} // 获取重新绘制的画布流
const canvasMedidaStream = canvas.captureStream(25);

效果如下:

可以看到这种方式的确是可行的,ZEGO WebRTC 团队也提供了对应的 demo 和源码, 免费给大家参考和体验,并封装了对应的库 rangeShare.js,帮助大家快速上手直接使用,可点击链接查看:https://zegodev.github.io/zego-express-webrtc-sample/screen/index.html

实践过程中我们发现,还有一些问题也非常值得大家注意:

  • 问题一:canvas 渲染对浏览器 cpu 消耗是比较高的, 性能不好的设备可能会导致整个页面卡顿;

  • 问题二:虽然画面可以重新绘制, 但是重新绘制的流是纯视频的,如果捕捉的流是包含音频,会导致音频丢失。

对于问题一:ZEGO WebRTC 团队 经过大量设备测试,在 rangeShare.js 库中把参数调整到尽可能适配更多设备。同时 demo 中提供了估算 cpu 占用的代码, 在 cpu 消耗过大情况下,可以提示本设备 cpu 占用过高,开发者可根据提示选择更换设备,或关闭其他 cpu 占用较高的进程。

对于问题二:rangeShare.js 也帮你把这个问题考虑到了,屏幕捕捉到的流传进来时,若检测到包含音频,会自动缓存音轨,并在输出的时候和画布流混合。

总结

以上就是关于在 Web 端实现屏幕共享的技术解读,而随着 5G 技术的到来和硬件设备性能的提升,浏览器上实现流媒体的低延迟传输和流媒体数据处理已经有较成熟的方案,比如浏览器上实现屏幕捕捉。

音视频能表达的信息相比文字图片更丰富,所以音视频传输正变得更普及,同时现代浏览器也在不断的更新音视频操作相关 API,浏览器能做的事情也许比我们想象中的更多。

ZEGO WebRTC 团队会持续跟大家分享 Web 端关于音视频方面有意思的技术问题,如有出入,欢迎大家指正和交流。

技术教程 | 基于 Web 端的屏幕共享实践的更多相关文章

  1. 基于 Web 端 3D 地铁站可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  2. 基于web端去除空格小工具

    读论文时,不时需要抓取PDF版的段落,可是复制到word的时候会出现很多空格,利用javascript强大的功能,几行命令实现了去除段落里的空格,实现如下: <!DOCTYPE html PUB ...

  3. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...

  4. Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE

    1. 前言 Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Serve ...

  5. 新手入门:史上最全Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  6. Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  7. Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!

    本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...

  8. web端及时通讯原理

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

  9. 20155201 网络攻防技术 实验八 Web基础

    20155201 网络攻防技术 实验八 Web基础 一.实践内容 Web前端HTML,能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. We ...

  10. Web端直传数据至OSS

    官方文档 最佳实践 小程序直传实践 支付宝小程序直传实践 微信小程序直传实践 Web端PostObject直传实践 Web端PostObject直传实践简介 JavaScript客户端签名直传 服务端 ...

随机推荐

  1. react-devtools安装以及使用中的问题

    使用react框架开发的小伙伴肯定都想使用想vue-devtools开发工具一样,可以看见组件的状态,和当前组件里的props,data等等. 当然react也有一个开发者工具,现在废话少说,开始安装 ...

  2. P2872

    [USACO07DEC]Building Roads S 题意描述 输入 4 1 1 1 3 1 2 3 4 3 1 4 输出 4.00 点拨 题目大意就是求最小的能把几个集合连起来的边权值之和,我们 ...

  3. 数据盘故障导致journalnode异常恢复

    背景环境:hdp2.6.6部署的小集群(4节点),这个投入生产后,转手了很多批次人维护,安装源介质这些通通都找不到了,目前官网无法下载hdp的安装介质,中途有坏了一个节点的系统盘,维修好了后,因为没有 ...

  4. Python生成PDF:Reportlab的六种使用方式

    Reportlab是Python创建PDF文档的功能库 这里是整理过的六种Reportlab使用方式,主要参考的是<ReportLab User Guide> 一.使用文档模板DocTem ...

  5. API是什么

    API就是接口,就是通道,负责一个程序和其他软件的沟通,本质是预先定义的函数.譬如我们去办事,窗口就类似一个API,如果对于某一件不简单的事情,这个窗口能做到让我们"最多跑一次", ...

  6. 女朋友问我 LB 是谁?

    科普一下 LB(负载均衡)技术 我的编程导航网站:www.code-nav.cn 大家好,我是鱼皮. 周末在家写代码,无意中跟女朋友提了下 LB,还说 LB 好的呱呱叫. 她笑了笑,问我 LB 是谁? ...

  7. 产品探秘:智影AI——你的创意视频制作神器!

    只需3步,把小说变成视频.免费试用,首次注册赠送600积分. https://icomicai.com/ 在这个快节奏的时代,创意与效率并重成为了我们追求的新风尚.今天,就让我带你一起揭秘一款颠覆传统 ...

  8. JMeter 逻辑控制之IF条件控制器

    逻辑控制之IF条件控制器 测试环境 JMeter-5.4.1 循环控制器介绍 添加While Controller 右键线程组->添加->逻辑控制器->While控制器 控制器面板介 ...

  9. 彻底搞懂python super函数的作用

    super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了. 调用父类同名方法有两种方式: 1.调 ...

  10. golang对遍历目录操作的优化

    一转眼go1.23都快发布了,时间过得真快. 不过今天我们把时间倒流回三年半之前,来关注一个在go1.16引入的关于处理目录时的优化. 对于go1.16的新变化,大家印象最深的可能是io包的大规模重构 ...