咱们在最近的一篇WebKit博客中宣布了对High Sierra平台和iOS中Safari的WebRTC支持。如今,咱们但愿可以带领你们深刻实现其中的一些细节,而且为您网站中的WebRTC应用带来一些建议。html
一个应用了WebRTC和媒体摄像头的网站能够获取并传播一些很是私人的信息。用户必须显式地对网站进行受权,并假设他们的图片和声音会被合理使用。WebKit为了利用技术保护用户的隐私权,要求网站知足一些特定的条件。除此以外,当用户的摄像头设备被使用时,Safari会提醒用户,而且用户能够控制网站对摄像头设备的访问权限。对于在App中使用了WebKit的开发者发来讲,RTCPeerConnection
和RTCDataChannel
能够在任意网页视图中使用,但对摄像头和麦克风的访问目前受限于Safari。ios
Safari技术预览版34向开发者展现了一些选项,能够更容易的测试他们的WebRTC网站或将Safari集成到持续集成系统中,入口在开发>WebRTC子菜单中。git
咱们将介绍每一个选项,并将在下方解释它们是如何帮助你进行开发的。github
此外,WebKit将WebRTC的状态做为日志记录在了系统日志中,包括SDP邀请和应答,ICE候选项,WebRCT状态统计,传入及传出视频帧计数器等。web
但愿访问捕获设备的网站须要知足两个约束。macos
首先,请求须要使用摄像头和麦克风的文档须要来自HTTPS域。因为在本地开发和测试时可能会很麻烦,所以能够经过在开发>WebRTC*菜单中选中"在不安全的站点上容许使用媒体摄像头"来旁路HTTPS限制。canvas
其次,当子帧请求使用摄像头设备时,通向主帧的帧链须要来自相同的安全源。用户可能没法识别与主帧相关的子帧的第三方来源,所以该约束避免了混淆用户授予其访问权限的用户。promise
在开发>WebRTC菜单中,能够选择"使用模拟摄像头设备"来替代真实的摄像头设备。以下所示,模拟循环一个bip-bop AV流。当用做传入流时,模拟的可预测数据能够轻松评估流媒体播放的各个方面,包括同步,延迟和输入设备的选择。浏览器
模拟对于在持续集成系统中运行自动化测试也颇有用。若是您正在使用而且想要避免来自getUserMedia
的提示,能够经过Safari首选项...>网站面板将网站的摄像头和麦克风策略设置为容许。安全
ICE候选项在WebRTC链接的早期阶段进行信息交换,以识别两个对等链接之间的全部可能的网络路径。为此,WebKit必须将每一个对等链接的ICE候选项暴露给网站并共享它们。ICE候选项公开IP地址,特别是那些能够用于跟踪的主机IP地址。
可是,在许多网络拓扑中,主机ICE候选项没必要进行链接。不管是否用于交换视频或任意数据,Server Reflexive和TURN ICE候选项一般都足以确保链接。若是不访问摄像头设备,WebKit只会公开Server Reflexive和TURN ICE候选项,这些候选者会公开可能已经被网站收集的IP。授予访问权限后,WebKit将公开主机ICE候选项,从而最大限度地提升链接成功的可能性。咱们作出此例外的缘由是:咱们认为用户经过授予对其摄像流的访问权限来表达对网站的高度信任。
一些测试页面可能会对主机ICE候选项的可用性做出假设。要对此进行测试,请从开发>WebRTC菜单中启用"禁用ICE候选限制",而后从新加载页面。
随着WebRTC标准化过程的推动(免费下载W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers中文版),RTCPeerConnection
API以各类方式逐步改进。API从最初基于回调,到变为彻底基于promise,从最初专一于将MediaStream
,移动到专一于MediaStreamTrack
。感谢WebRTC in WebKit团队的努力,RTCPeerConnection
API的改进与这两个主要变化保持一致。
咱们已经在Safari技术预览版34上默认关闭了旧版WebRTC API,并计划在没有这些API的状况下在macOS High Sierra和iOS 11上发布Safari 11。保留遗留API限制了咱们在WebRTC上更快推动的能力。任何但愿为Safari提供支持的网站均可能须要进行其余调整,所以这是摆脱这些遗留API的好时机。现有网站仍然能够依赖这些遗留API,您能够经过在开发>WebRTC菜单中启用"启用旧版WebRTC API"来达到目的。
更准确地说,如下API仅在打开旧版API开关时可用,并提供了有关如何更新的建议:
partial interface Navigator {
// Switch to navigator.mediaDevices.getUserMedia
void getUserMedia(MediaStreamConstraints constraints, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback);
};
partial interface RTCPeerConnection {
// Switch to getSenders, and look at RTCRtpSender.track
sequence<MediaStream> getLocalStreams();
// Switch to getReceivers, and look at RTCRtpReceiver.track
sequence<MediaStream> getRemoteStreams();
// Switch to getSenders/getReceivers
MediaStream getStreamById(DOMString streamId);
// Switch to addTrack
void addStream(MediaStream stream);
// Switch to removeTrack
void removeStream(MediaStream stream);
// Listen to ontrack event
attribute EventHandler onaddstream;
// Update to promise-only version of createOffer
Promise<void> createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional RTCOfferOptions options);
// Update to promise-only version of setLocalDescription
Promise<void> setLocalDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
// Update to promise-only version of createAnswer
Promise<void> createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);
// Update to promise-only version of setRemoteDescription
Promise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
// Update to promise-only version of addIceCandidate
Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
};
复制代码
许多站点经过开源的adapter.js项目支持polyfill API。更新到最新版本是弥补API差别的一种方法,但咱们建议切换到规范中列出的API。
如下是如何使用最新API的几个示例。典型的仅接收/在线研讨的WebRTC调用能够像这样完成:
var pc = new RTCPeerConnection();
pc.addTransceiver('audio');
pc.addTransceiver('video');
var offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// send offer to the other party
...
复制代码
典型的音频-视频WebRTC调用也能够像如下方式完成:
var stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
var pc = new RTCPeerConnection();
var audioSender = pc.addTrack(stream.getAudioTracks()[0], stream);
var videoSender = pc.addTrack(stream.getVideoTracks()[0], stream);
var offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// send offer to the other party
...
复制代码
基于MediaStreamTrack
的API颇有意义,由于大多数处理都是在这一层完成的。假设捕获视频轨的640×480默认分辨率不够好,继续前面的示例,动态更改它能够按以下方式完成:
videoSender.track.applyConstraints({width: 1280, height: 720});
复制代码
或者咱们可能想要视频静音但保持音频流动:
videoSender.track.enabled = false;
复制代码
等等,咱们实际上想要对当前的视频轨应用一些很酷的滤镜效果,就像在这个例子中同样,所须要的只是一些不须要任何SDP从新协商的函数调用:
videoSender.track.enabled = true;
renderWithEffects(video, canvas);
videoSender.replaceTrack(canvas.captureStream().getVideoTracks()[0]);
复制代码
Safari容许用户彻底控制网站对其摄像设备的访问权限。
首先,用户首次调用getUserMedia
时,系统会提示用户授予网站访问摄像设备的权限。但与其余浏览器不一样的是,Safari不要求用户选择特定设备; 相反,它提示请求访问某一特定类型的设备,如全部相机或麦克风。这减小了屡次提示带来的困扰,而且可避免用户始终点击"容许"。可能发生这种状况的一种常见情形是在iOS设备的摄像头在先后之间切换。getUserMedia
中已解析的promise将返回知足约束条件的设备,而且后续对getUserMedia
的调用将避免向用户显示提示。若是要容许用户切换到其余设备,请务必提供UI以执行此操做。
其次,用户能够决定经过Safari首选项始终容许或拒绝访问摄像头和麦克风。用户能够基于每一个来源执行此操做,甚至能够为全部网站设置通用策略。
第三,一旦网站为设备建立MediaStream
,Safari UI和系统菜单栏中就会显示图标,代表正在使用摄像设备。用户能够点击或点击该图标以暂停使用中的摄像机和麦克风。在这里,WebKit将发送静音音频和黑色视频帧,您的网站能够经过监听MediaStreamTrack
上的静音
和取消静音
事件来展现合适的UI。
最后,为了不未经容许的摄像,WebKit只容许一个选项捕获一次视频或音频。已使用的捕获设备将看到他们的MediaStreamTracks
静音并在新选项卡得到访问权限时接收静音
事件。
navigator.mediaDevices.enumerateDevices
公开了可用的摄像设备列表,即便未授予对这些设备的访问权限,也能够经过网站查询。对于具备自定义相机和麦克风设置的用户,能够添加到用户的指纹表面。当访问还没有被请求或访问没有被明确拒绝时,WebKit经过返回与实际可用设备集不必定对应的默认设备列表,来避免暴露这些附加信息。此外,根据规范,设备缺乏标签
。一旦访问权限被授予,便可得到完整的设备列表及其标签。
在以前的帖子一和二中,咱们讨论了macOS和iOS上视频自动播放策略的变化。咱们调整了两个平台上的策略以适应WebRTC应用程序,在这些应用程序中,一般须要自动播放包含音频的传入媒体流。为了解决这些问题,同时保留当前自动播放规则的好处,咱们进行了如下更改:
MediaStream
支持的媒体将自动播放。MediaStream
支持的媒体将自动播放。但仍然须要用户手势来激活音频回放。WebRTC是一个很是强大的特性,能够衍生许多应用程序。咱们都知道,强大的力量带来了巨大的责任。设计WebRTC应用程序须要从一开始就考虑到效率。 CPU,内存和网络均可能严重影响用户体验。Web引擎和Web应用程序都应该解决此问题。在Web应用程序方面,已经有各类机制可供选择:选择正确的视频分辨率和帧速率,选择正确的视频编解码器配置文件,使用CVO,在源处将媒体轨静音,以及在客户端执行WebRTC统计数据的监视。
这就是咱们深刻研究WebRTC和媒体摄像的结果。咱们随时欢迎您的反馈。提交错误,发送电子邮件至web-evangelist@apple.com,或发推并@webkit。
顺便说一句,鼓励你们阅读STUN和TURN的RFC规范,以及WebRTC自己的规范。这些文件可能有点难以理解,可是您能够从理解甚至一小部份内容中学到不少东西,这将有助于您的生活更简单。免费下载W3C推荐标准WebRTC 1.0: Real-time Communication Between Browsers中文版。