WebRTC系列文章
4.WebRTC源码研究(4)web服务器工作原理和常用协议基础
WebRTC源码研究(12)视频约束
1. WebRTC 视频相关api简介
2. WebRTC 视频参数设置
通过WebRTC提供的视频属性设置api ,我们可以精确的控制音频和视频的采集数据,接下来看看,这些属性的含义和使用方法:
| 属性 | 含义 | 用途 |
|---|---|---|
| width | 视频的宽度 | |
| height | 视频的高度 | 宽高有两种比例 :一种是4:3,另一种是16:9;像320 - 240的,640 - 480,这都属于4:3的比例,就是它更方一些。还有一种是16:9,比如是720P的,就是1280 - 720,这就是16:9的比例。它显得更长一些,但是对于我们的手机来说,它就翻过来了,如果我们竖屏拍摄那它高度就是16,比如1280 - 720,宽度就变成了720,这是宽和高,通过这个约束我们就可以控制这个分辨率,你想设置多少,就可以根据自己的情况去调节。 |
| aspectRatio | 比例 | 一般情况下我们只需要设置宽和高就可以了,这个aspectRatio通过宽高进行一个除,宽除以高,1.333,这个4:3的比例,这里这里我们一般不会设置这个值。 |
| frameRate | 帧率 | 我们可以通过帧率的多少来控制我们的码流,当然帧率低的话,你会看这个画面不太平滑,帧率高的话画面就很平滑,我们看电影也能看出这个效果,如果每秒钟只有十几帧的话,眼睛比较敏感的人它会看到一卡一卡的现象,但是对于 比如30帧或60帧的,就特别平滑,现在的高清电影一般都是60帧。从另外一方面讲如果你帧率过高了,那你码流就会过大,相当于你1秒钟采集的数据多了。 |
| facingMode | 镜像模式 | 它是用来控制我们的摄像头翻转的。正常情况下我们 用的是前置摄像头对着自己拍,那你也可以设置成后置摄像头,就是往外拍;还可以打开 前置 的左边的摄像头和前置的右边摄像头,如果你是双 摄像头的话,这都可以做到。在PC上一般是没有前后摄像头的,所以这个设置就会不起作用,它会忽略。而对于手机来说就可以看出它的区别来。facingMode 有四种模式:user: 前置摄像头,environment:后置摄像头 ,left:前置左侧摄像头,right:前置右侧摄像头 |
| resizeMode | 大小模式 | 它表示采集的画面要不要裁剪,它可以设置为null,就是原封不动的,就是采集什么样他就是什么样。还有一种就是利用裁剪,把他 裁掉 一块去,这个用的不是太多,具体根据业务需求来看了。 |
3. WebRTC视频约束代码实现
3.1 浏览器中设置视频约束的代码实现
我们先来看看,在浏览器中怎么实现视频约束参数的设置,代码如下:
'use strict'
var audioSource = document.querySelector('select#audioSource');
var audioOutput = document.querySelector('select#audioOutput');
var videoSource = document.querySelector('select#videoSource');
// 获取video标签
var videoplay = document.querySelector('video#player');
// deviceInfos是设备信息的数组
function gotDevices(deviceInfos){
// 遍历设备信息数组, 函数里面也有个参数是每一项的deviceinfo, 这样我们就拿到每个设备的信息了
deviceInfos.forEach(function(deviceinfo){
// 创建每一项
var option = document.createElement('option');
option.text = deviceinfo.label;
option.value = deviceinfo.deviceId;
if(deviceinfo.kind === 'audioinput'){ // 音频输入
audioSource.appendChild(option);
}else if(deviceinfo.kind === 'audiooutput'){ // 音频输出
audioOutput.appendChild(option);
}else if(deviceinfo.kind === 'videoinput'){ // 视频输入
videoSource.appendChild(option);
}
})
}
// 获取到流做什么, 在gotMediaStream方面里面我们要传人一个参数,也就是流,
// 这个流里面实际上包含了音频轨和视频轨,因为我们通过constraints设置了要采集视频和音频
// 我们直接吧这个流赋值给HTML中赋值的video标签
// 当时拿到这个流了,说明用户已经同意去访问音视频设备了
function gotMediaStream(stream){
videoplay.srcObject = stream; // 指定数据源来自stream,这样视频标签采集到这个数据之后就可以将视频和音频播放出来
// 当我们采集到音视频的数据之后,我们返回一个Promise
return navigator.mediaDevices.enumerateDevices();
}
function handleError(err){
console.log('getUserMedia error:', err);
}
// 判断浏览器是否支持
if(!navigator.mediaDevices ||
!navigator.mediaDevices.getUserMedia){
console.log('getUserMedia is not supported!');
}else{
// 这里是约束参数,正常情况下我们只需要是否使用视频是否使用音频
// 对于视频就可以按我们刚才所说的做一些限制
var constraints = { // 表示同时采集视频金和音频
video : {
width: 640, // 宽带
height: 480, // 高度
frameRate:15, // 帧率
facingMode: 'enviroment', // 设置为后置摄像头
deviceId : deviceId ? {exact:deviceId} : undefined //
},
audio : false
}
navigator.mediaDevices.getUserMedia(constraints)
.then(gotMediaStream) // 使用Promise串联的方式,获取流成功了
.then(gotDevices)
.catch(handleError);
}
4. WebRTC视频截取图片代码实现
通过WebRTC api我们很容易就能实现从视频流总截取一张图片
主要是利用html5浏览器的一个api : canvas, 主需要一行代码就可以实现获取图片:
button.onclick = function() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
};
具体完整代码如果下:
test.html内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="mobile-web-app-capable" content="yes">
<meta id="theme-color" name="theme-color" content="#ffffff">
<base target="_blank">
<title>getUserMedia to canvas</title>
</head>
<body>
<div id="container">
<h1><a href="https://github.com/kongyuluEleven/WebRTCPro" title="WebRTC snap picture kongyulu">WebRTC samples</a> <span>getUserMedia ⇒ canvas</span>
</h1>
<video playsinline autoplay></video>
<button>Take snapshot</button>
<canvas></canvas>
<p>Draw a frame from the video onto the canvas element using the <code>drawImage()</code> method.</p>
<p>The variables <code>canvas</code>, <code>video</code> and <code>stream</code> are in global scope, so you can
inspect them from the console.</p>
<a href="https://github.com/kongyuluEleven/WebRTCPro/tree/master/demos/js/webrtc_js_003_snap/canvas"
title="View source for this page on kongyulu's GitHub" id="viewSource">View source on GitHub</a>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/test.js" async></script>
</body>
</html>
test.js内容如下:
'use strict';
// Put variables in global scope to make them available to the browser console.
const video = document.querySelector('video');
const canvas = window.canvas = document.querySelector('canvas');
canvas.width = 480;
canvas.height = 360;
const button = document.querySelector('button');
button.onclick = function() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
};
const constraints = {
audio: false,
video: true
};
function handleSuccess(stream) {
window.stream = stream; // make stream available to browser console
video.srcObject = stream;
}
function handleError(error) {
console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
运行结果如下: