屏幕共享的英文叫做 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地址:https://zegoim.github.io/express-demo-web/src/Examples/Others/ScreenSharing/index.html)

关键语法:

//  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 帮大家做好了内部兼容, 并提供检测接口方便快速上手

​​​​​​​点击查看:https://doc-zh.zego.im/article/6301

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

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

只看浏览器接口是没有办法实现的,不过 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端即时通讯实践干货:如何让WebSocket断网重连更快速?

    本文作者网易智慧企业web前端开发工程师马莹莹.为了提升内容质量,收录时有修订和改动. 1.引言 在一个完善的即时通讯IM应用中,WebSocket是极其关键的一环,它为基于Web的即时通讯应用提供了 ...

  2. 基于web端和C++的两种深度学习模型部署方式

    深度学习Author:louwillMachine Learning Lab 本文对深度学习两种模型部署方式进行总结和梳理.一种是基于web服务端的模型部署,一种是基... 深度学习 Author:l ...

  3. 【深度学习】基于web端和C++的两种深度学习模型部署方式

    深度学习 Author:louwill Machine Learning Lab 本文对深度学习两种模型部署方式进行总结和梳理.一种是基于web服务端的模型部署,一种是基于C++软件集成的方式进行部署 ...

  4. 关于测试的一篇论文, 基于web端selenium的自动化测试设计与实现(有需要的联系我 此论文内容缺失,不要直接用 一经发现,后果自负)

    论文题目:基于web端selenium的自动化测试设计与实现 学科(专业):计算机科学与技术 申请人: 指导教师: 摘 要 随着我国科学技术的飞速发展,软件应用技术的更新速度日新月异,规模不断扩大.普 ...

  5. 一个快速实现彩屏应用的跨平台快速原型开发工具平台,最重要的是还免费!8ms.xyz平台原以为是单片机版墨刀,今天上去玩了才知道平台厉害的很,基于WEB端免搭建开发环境,跑的还是C代码编译出来的程序!

    哈哈哈哈,最近发现一个好用的在线编译.下载.烧录的跨平台快速原型开发工具平台,名字好记–8ms,单看名字是真的不知道干嘛的,不知道为啥叫这个?不多想了,好用就得分享给大家,独乐乐不如众乐乐呀-- 好用 ...

  6. pytorch基于web端和C++的两种深度学习模型部署方式

    本文对深度学习两种模型部署方式进行总结和梳理.一种是基于web服务端的模型部署,一种是基于C++软件集成的方式进行部署. 基于web服务端的模型部署,主要是通过REST API的形式来提供接口方便调用 ...

  7. 看BIM CHECK如何基于Web端设计端在Revit和Navisworks进行跨平台BIM问题管理协同

    看BIM CHECK如何基于Web端&设计端在Revit和Navisworks进行跨平台BIM问题管理协同 Web端: • 建立项目 • 创建用户和项目阶段等信息 • 创建文件夹 • 设定相应 ...

  8. 身份验证错误错误指定的句柄无效_基于 Web 端的人脸识别身份验证「实践」

    作者:沫沫 政采云前端团队 转发链接:https://mp.weixin.qq.com/s/fRDpXixnLIy9c0Uh2tMezQ 前言 近些年来,随着生物识别技术的逐渐成熟,基于深度学习的人脸 ...

  9. 维护几十种语言和站点,爱奇艺国际站WEB端网页优化实践

    1.前言 爱奇艺国际站(www.iq.com)提供了优质的视频给海外各国用户,自上线以来,现已支持几十个国际站点,并且在东南亚多个国家保证了海量用户高速观看体验. 国际站业务的特点是用户在境外访问,后 ...

最新文章

  1. easyexcel导入时读不到数据_EasyExcel简单使用--导入excel数据
  2. 如何通过远程修改另一台电脑注册表
  3. Are We Ready for SDN? Implementation Challenges for Software-Defined Networks
  4. mysql分析sql语句性能_sql语句执行性能分析
  5. 【基础】jquery全选、反选、全不选代码
  6. Bugfree实用心得_转
  7. POJ 2010 Moo University - Financial Aid【堆的应用】
  8. 第五篇:白话tornado源码之褪去模板的外衣
  9. 2021年江西省研究生数学建模竞赛题目(二)题目:全国人口普查问题
  10. atomic头文件编译_c++11 多线程(3)atomic 总结
  11. 一次错综离奇的super调用的None参数super() argument 1 must be type, not None
  12. Android之流行框架
  13. 2022牛客寒假算法基础集训营1 H题 牛牛看云
  14. 一个 丧心病狂 的开源项目
  15. 阿里巴巴余军:钉钉宜搭低代码实践之路
  16. 激光打印机维护保养完全手册
  17. 如何从JavaScript中的数组替换元素?
  18. Tibco Designer -- 时间日期转换
  19. 自京赴奉先县咏怀五百字
  20. 计算机无法共享打印,解决win7电脑打印机无法共享|打印机共享提示0x000006d9应如何解决...

热门文章

  1. Android逆向之破解某僵尸游戏
  2. Google Guava Splitter
  3. 【Java】获取IP以及归属地
  4. 怎么理解TPS、QPS、RT、吞吐量这些性能指标?
  5. Python自动化办公(一) :滴滴行程单信息提取存入excel表格 2021-04-13
  6. java poi 设置时间空间_java - POI - 如何将单元格值设置为Date并应用默认的Excel日期格式?...
  7. 【封神台】漏洞挖掘XXE wp
  8. created不能异步_详解vue中async-await的使用误区
  9. 小程序和Web项目的区别
  10. MP4文件如何转换成GIF动态图?两种方法帮你搞定