使用getDisplayMedia实现在Chrome中屏幕共享

原文标题:Chrome Screensharing Blues – preparing for getDisplayMedia
作者: “Philipp Hancke“

使用getDisplayMedia实现在Chrome中屏幕共享

Chrome网上商店已经决定停止允许Chrome扩展部件的内联安装,这对WebRTC应用有着极大的影响,因为目前在Chrome中屏幕共享需要扩展部件。GetDisplayMedia API 能不能解决这个问题呢?

1

Chrome中屏幕共享

Chrome33中引入屏幕共享时,需要扩展部件来解决安全问题。这比之前的做法更好,之前的做法是将这种能力置于一个标志之后,这个标志允许用户根据需求修改。

自2003年之后,Chrome没有做出太大改变。需要扩展部件增加了与屏幕共享过程的摩擦,但是由于内联安装,这种摩擦被最大限度的减小了:

1.用户点击按钮开始屏幕共享。
2.Web应用检测Chrome并确定出未安装的扩展部件。
3.Web应用触发内联安装API,获得成功回调。
4.Chrome桌面、窗口、标签共享选择器弹出,允许用户选择共享哪部分。

关于全部实现请查看getScreenMedia 扩展示例

共享选择器是这里的关键部分,没有web商店安全网的时候,暴露给Web平台,这足够安全吗?

2

在这个计划中共享标签是个主要关注点,因为它能分解跨域沙盒。

Firefox中的屏幕共享

Firefox使用了不同的方法,建立了一个白名单记录允许使用这个API的网站。这个过程包括向Mozilla询问并展示此网站有服务条款和隐私政策。你可以通过扩展部件来修改此白名单。在Firefox52,移除了此白名单,允许任何安全来源使用屏幕共享。它没有使用getDisplayMedia API,但是实现几乎相同,我们之后会讲到。

navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}})
  .then(stream => {
    // we have a stream, attach it to a feedback video element
    videoElement.srcObject = stream;
  }, error => {
    console.log("Unable to acquire screen capture", error);
  });

这将会被更新来支持最终说明

GetDisplayMedia API

W3C一直致力于对屏幕捕捉API的标准化。像getUserMedia一样,简单,基于承诺。

来自示例1的屏幕捕捉API说明
navigator.getDisplayMedia({ video: true })
  .then(stream => {
    // we have a stream, attach it to a feedback video element
    videoElement.srcObject = stream;
  }, error => {
    console.log("Unable to acquire screen capture", error);
  });

微软Edge在今年的早期刚刚使用这个API实现了屏幕共享。用户体验极好,添加了一个黄色的边界,来显示用户正在共享的界面,确保用户时刻知道他们在分享哪些部分。

3

Chrome扩展部件带来了变化

根据实际来讲,appear.in 屏幕共享扩展像先前描述的一样,在上百万次数安装中非常成功。
用户中的绝大多数来自内联安装,因此我们不厌其烦的更新自2014年的Chrome Web商店中扩展屏幕的部件。

目前Chrome Web商店移除了内联安装。这在我学习一个旧版本Chrome关于让屏幕共享更广泛的应用的问题的时候,感到意外。(感谢Wilhelm Wanecek指出这点)。

如果我正确的理解了声明,这将会在不同的标签中打开Chrome Web商店。这将会使检测用户何时从Web App中安装了扩展部件变得困难。帖子上的时间表如下:
1.自6.12起,新扩展部件不需要内联安装。无通知期限。
2.对已经存在的扩展部件的内联安装将会在9.12禁止,三个月通知期限。

抱怨

有几件事是错误的。我甚至没有讨论Google Hangouts/Meet,完全避免了其他人为了使用内置扩展来应对的用户体验。

我期待着Chrome Webstore团队的一些推广延伸。Appear.in扩展被上百万用户当做最大的屏幕共享扩展部件之一。我们的用户与网站建立了信任关系,通常允许我们传输网络摄像头和麦克风。使用基于此信任关系的内联安装比从Chrome WebStore安装更安全。同样我们要求WebStore开发人员对我们拆除由数百名用户安装的扩展程序的非法拷贝进行支持。

Google的WebRTC小伙伴们同样提出了很好的建议。

转到getDisplayMedia

Chrome的前进道路致力于getDisplayMedia API. 消息传出来不久,intent to ship就发布了。然而,考虑到Chrome的发布周期,这将会需要几周的时间来实现。对于安全性和用户的体验来说这是一个不小的变化,以至于在9.12日截止日前之前让人感到怀疑。Chrome69在9.12日发布的稳定分支点只有不到一个月时间了。

Chrome中的情况更加复杂,因为它允许共享标签,同时限制用户可以选择的界面。Chrome支持的共享音频输出也没有被getDisplayMedia指定。

如何应对Chrome的最终改变

实际上关于支持getDisplayMedia部分的代码变化相对简单。这个API 和你使用Firefox的带有mediaSource 参数的getUserMedia call会进入相同的位置。通过检测getDisplayMedia的存在可以轻易的完成特征检测。

if ('getDisplayMedia' in window.navigator) {
  // use it.
} else {
  // fall back to extension way
}

某种程度上,如何指定capture frame rate仍然不清晰。在MediaStreamTrack上使用applyConstraints返回对getUserMedia的工作,并且可能会继续对getDisplayMedia执行同样的操作。

navigator.getDisplayMedia({video: true})
  .then(stream => {
    stream.getTracks()[0].applyConstraints({frameRate: 5});
    return stream;
  })

详细信息请查看具体问题部分。

不幸的是,adapter.js不能真正的获取getDisplayMedia,因为与扩展部分的通信交流不是完全相同,不同的扩展有轻微的差异。

目前与展望

我期待着看到Google的WebRTC小伙伴影响移除内联扩展或及时发布getDisplayMedia的截止时间。有时候Web平台的建立可能会很麻烦,但是通常最终会取得很好的结果。我们期待着这次的结束,也将会高兴的与扩展部分告别。

填写常用邮箱,接收社区更新

WebRTC 中文社区由

运营