- WebRTC音视频实时互动技术:原理、实战与源码分析
- 李超编著
- 1094字
- 2021-08-06 14:49:36
5.3 采集音视频数据
通过enumerateDevices()接口获得音视频设备后,就可以选择其中的设备进行数据采集了。在浏览器下采集音视频数据也很方便,调用getUserMedia()这个API就可以采集到。getUserMedia的接口格式如代码5.4所示。
代码5.4 getUserMedia()接口格式
navigator.mediaDevices. getUserMedia(MediaStreamConstrains);
该接口有一个MediaStreamConstrains类型的输入参数,可以用来控制从哪个设备上采集音视频数据,以及限制采集到的数据的格式,如限制采集到的视频分辨率、音频数据的采样率、采样大小等。其结构如代码5.5所示。
代码5.5 MediaStreamConstrains结构体
dictionary MediaStreamConstrains { (boolean) or (MediaTrackConstrains) video = false; (boolean) or (MediaTrackConstrains) audio = false; }
从上面MediaStreamConstrains类型的定义可以看出,video和audio属性既可以是boolean类型,也可以是MediaTrackConstrains类型(只有像JavaScript这种弱类型语言才可以做这一点)。因此,我们既可以直接给video和audio赋值true/false,简单地指明是否采集视频或音频数据,也可以给它赋值一个MediaTrackConstrains类型的值,对音视频设备做更精准的设置。
如果直接给video/audio属性赋值true,则浏览器会使用默认设备和默认参数采集音视频数据,否则如果给video/audio赋值MediaTrackConstrains类型值,则浏览器会按MediaTrackConstrains中的限制,从指定的设备中采集音视频数据。MediaTrackConstrains结构如代码5.6所示。
代码5.6 MediaTrackConstraintSet结构体
dictionary MediaTrackConstraintSet { //视频相关 ConstrainULong width; ConstrainULong height; ConstrainDouble aspectRatio;//宽高比 ConstrainDouble frameRate; ConstrainDOMString facingMode; //前置/后置摄像头 ConstrainDOMString resizeMode; //缩放或裁剪 //音频相关 ConstrainULong sampleRate; ConstrainULong sampleSize; ConstrainBoolean echoCancellation; ConstrainBoolean autoGainControl; ConstrainBoolean noiseSuppression; ConstrainDouble latency;//目标延迟 ConstrainULong channelCount; //设备相关 ConstrainDOMString deviceId; ConstrainDOMString groupId; };
从上面的代码片段中可以看到,MediaTrackConstrains结构由三部分组成,即视频相关属性、音频相关属性以及设备相关属性。视频属性中包括分辨率、视频宽高比、帧率、前置/后置摄像头、视频缩放;音频属性包括采样率、采样大小、是否开启回音消除、是否开启自动增益、是否开启降噪、目标延迟、声道数;设备相关属性包括设备ID、设备组ID。
我们来看一个具体的例子,看看如何通过getUserMedia()接口来采集音视频数据。具体代码参见代码5.7。
代码5.7 获取音视频流
1 // 采集到某路流 2 function gotMediaStream(stream){ 3 … 4 } 5 … 6 // 从设备选项栏里选择某个设备 7 var deviceId = xxx; 8 9 // 设置采集限制 10 var constraints = { 11 video : { 12 width: 640, 13 height: 480, 14 frameRate : 15 , 15 facingMode : 'enviroment ', 16 deviceId : deviceId ?{ exact:deviceId }: undefined 17 }, 18 audio : false 19 } 20 21 // 开始采集数据 22 navigator.mediaDevices.getUserMedia(constraints) 23 .then(gotMediaStream) 24 .catch(handleError); 25 …
在上面的代码片段中,首先执行第22行代码,即调用getUserMedia()接口,然后根据constraints中的限制获取音视频数据。在这个例子中,getUserMedia()从指定设备(deviceId)上按指定参数采集视频数据,具体参数如下:分辨率为640×480、帧率为15帧/秒、使用后置摄像头(environment)。因为audio属性为false,所以此例中仅采集视频数据而不采集音频数据。
此外,从上面的代码中还可以看到,调用getUserMedia()接口的方式与调用enumerate Devices()接口的方式是一样的,也是使用Promise方式。当调用getUserMedia()成功时,会回调gotMediaStream()函数,该函数的输入参数MediaStream里存放的就是音视频数据流。当获得音视频数据后,既可以把它作为本地预览,也可以将它传送给远端,从而实现一对一通信。如果调用getUserMedia()接口失败,则调用错误处理函数handleError。
[1] https://w3c.github.io/mediacapture-main/#def-constraint-facingMode