HTML5 APP开发从入门到精通(微课精编版)
上QQ阅读APP看书,第一时间看更新

5.1 WebRTC基础

众所周知,浏览器本身不支持相互直接建立信道进行通信,都是通过服务器进行中转。例如,现在有两个客户端:甲和乙。他们想要通信,首先需要甲和服务器、乙和服务器之间分别建立信道。甲给乙发送消息时,甲先将消息发送到服务器上,服务器对甲的消息进行中转,发送到乙处,反过来也是一样。这样甲与乙之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽。同时,这样的信道并不适合数据流的传输。如何建立浏览器之间的点对点传输,一直困扰着开发者,因此WebRTC应运而生。

5.1.1 认识WebRTC

WebRTC表示网页实时通信(Web Real-Time Communication),是一个支持网页浏览器进行实时语音对话或视频对话的技术。它是一个开源项目,旨在使浏览器能为实时通信(RTC)提供简单的JavaScript接口。简单说就是让浏览器提供JavaScript的即时通信接口。这个接口创立的信道并不像WebSocket一样打通一个浏览器与WebSocket服务器之间的通信,而是通过一系列的信令,建立一个浏览器与另一个浏览器之间(peer-to-peer)的信道,这个信道可以发送任何数据,而不需要经过服务器。并且WebRTC实现MediaStream,通过浏览器调用设备的摄像头和麦克风,浏览器之间可以传递音频和视频。

目前,Chrome 26+、Firefox 24+、Opera 18+版本的浏览器均支持WebRTC的实现。Chrome和Opera浏览器将RTCPeerConnection命名为webkitRTCPeerConnection,Firefox浏览器将RTCPeerConnection命名为mozRTCPeerConnection。不过WebRTC标准稳定后,各个浏览器前缀将会被移除。

WebRTC实现了3个API,简单说明如下。

MediaStream:能够通过设备的摄像头和麦克风获得视频、音频的同步流。

RTCPeerConnection:用于构建点对点之间稳定、高效的流传输的组件。

RTCDataChannel:在浏览器间(点对点)建立一个高吞吐量、低延时的信道,用于传输任意数据。

5.1.2 访问本地设备

MediaStream API为WebRTC提供了从设备的摄像头、麦克风获取视频和音频流数据的功能。用户可以通过调用navigator.getUserMedia()访问本地设备,该方法包含3个参数。

约束对象(constraints object)。

调用成功的回调函数,如果调用成功,传递给它一个流对象。

调用失败的回调函数,如果调用失败,传递给它一个错误对象。

提示:由于浏览器之间的不同,经常会在标准版本的方法前面加上前缀,一个兼容版本代码如下。

示例】本示例演示了如何调用getUserMedia方法访问本地摄像头。

在Chrome浏览器中打开页面,浏览器首先询问用户是否允许脚本访问本地摄像头,如图5.1所示。当用户单击“允许”按钮后,浏览器会显示从用户本地摄像头中捕捉的影像,如图5.2所示。

注意:HTML文件要放在服务器上,否则会得到一个NavigatorUserMediaError的错误,显示PermissionDeniedError。也可以在命令行中使用cd命令,进入HTML文件所在目录,找到python -m SimpleHTTPServer(需要安装python),或者在浏览器中输入http://localhost:8000/{文件名称}.html也可以。

图5.1 询问权限

图5.2 捕捉摄像头视频流

在getUserMedia方法中,第一个参数值为一个约束对象,该对象包含一个video属性和一个audio属性,属性值均为布尔类型。video属性值为true,表示捕捉视频信息;video属性值为false,表示不捕捉视频信息。audio属性值为true,表示捕捉音频信息;audio属性值为false,表示不捕捉音频信息。浏览器弹出的要求用户给予权限的请求时,也会根据约束对象的不同而有所改变。注意,在一个浏览器标签中设置的getUserMedia约束将影响之后打开的所有标签中的约束。

第二个参数值为访问本地设备成功时所执行的回调函数,该回调函数具有一个参数,参数值为一个MediaStream对象,浏览器执行getUserMedia方法时将自动创建该对象。该对象代表同步媒体数据流。例如,一个来自于摄像头、麦克风输入设备的同步媒体数据流往往是视频轨道和音频轨道的同步数据。

每一个MediaStream对象都拥有一个字符串类型的ID属性,如“e1c55526-a70b-4d46-b5c1-dd19f9dc6beb”,以标识每一个同步媒体数据流。该对象的getAudioTracks()方法或getVideoTracks()方法将返回一个MediaStreamTrack对象的数组。

MediaStreamTrack对象表示一个视频轨道或一个音频轨道,每一个MediaStreamTrack对象包含两个属性。

kind:字符串类型。标识轨道种类,如“video”或“audio”。

label:字符串类型。标识音频通道或视频通道,如“HP Truevision HD (04f2:b2f8)”。

getUserMedia方法中第3个参数值为访问本地设备失败时所执行的回调函数,该回调函数具有一个参数,参数值为一个error对象,代表浏览器抛出的错误对象。

上面示例结合了HTML5的video元素。window对象的URL.createObjectURL方法允许将一个MediaStream对象转换为一个Blob URL值,以便将其设置为一个video元素的属性,这样可以通过video.src把视频流显示在网页中。

注意,同时为video元素设置autoplay属性,如果不使用该属性,video元素将停留在所获取的第一帧画面位置。

拓展

约束对象可以设置在getUserMedia()和RTCPeerConnection的addStream方法中,这个约束对象是WebRTC用来指定接受什么样的流,其中可以定义如下属性。

video:是否接受视频流。

audio:是否接受音频流。

MinWidth:视频流的最小宽度。

MaxWidth:视频流的最大宽度。

MaxHeight:视频流的最小高度。

MaxHeight:视频流的最大高度。

MinAspectRatio:视频流的最小宽高比。

MaxAspectRatio:视频流的最大宽高比。

MinFramerate:视频流的最小帧速率。

MaxFramerate:视频流的最大帧速率。