关于前端:基于-Web-端的屏幕共享实践

95次阅读

共计 2866 个字符,预计需要花费 8 分钟才能阅读完成。

屏幕共享的英文叫做 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/expr…)

 要害语法:

//  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/articl…

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

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

只看浏览器接口是没有方法实现的,不过 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/zeg…]()。

实际过程中咱们发现,还有一些问题也十分值得大家留神:

  • 问题一:canvas 渲染对浏览器 cpu 耗费是比拟高的, 性能不好的设施可能会导致整个页面卡顿;
  • 问题二:尽管画面能够从新绘制, 然而从新绘制的流是纯视频的,如果捕获的流是蕴含音频,会导致音频失落。

对于问题一:ZEGO WebRTC 团队 通过大量设施测试,在 rangeShare.js 库中把参数调整到尽可能适配更多设施。同时 demo 中提供了估算 cpu 占用的代码, 在 cpu 耗费过大状况下,能够提醒本设施 cpu 占用过高,开发者可依据提醒抉择更换设施,或敞开其余 cpu 占用较高的过程。

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

总结

以上就是对于在 Web 端实现屏幕共享的技术解读,而随着 5G 技术的到来和硬件设施性能的晋升,浏览器上实现流媒体的低提早传输和流媒体数据处理曾经有较成熟的计划,比方浏览器上实现屏幕捕获。

音视频能表白的信息相比文字图片更丰盛,所以音视频传输正变得更遍及,同时古代浏览器也在一直的更新音视频操作相干 API,浏览器能做的事件兴许比咱们设想中的更多。

ZEGO WebRTC 团队会继续跟大家分享 Web 端对于音视频方面有意思的技术问题,如有出入,欢送大家斧正和交换。

正文完
 0