WebRTC ( Real-Time Communications)是一个可以在 Web 应用程序中实现音频、视频和数据的实时通信的开源项目,它封装了很多音视频的采集、处理功能,比如音视频流的编解码、降噪和回声消除等。通过WebRTC,我们可以方便地获取优化后的媒体流,将其输入到本地或转发给其他对等端。
WebRTC设计的初衷是为了在无插件的条件下实现两个浏览器之间**点对点(peer to peer,P2P)**连接,从而进行音视频的实时通信。这种通信模式大多数情况下不需要依赖于服务器的中转,WebRtc只适合小范围(8人以内)音视频会议,
在这端时间的学习中,我主要实现了以下功能:
1. 本地视频的播放
2. 视频录制
3. 一对一视频对话
4. 一对多视频对话
5. 多对多视频对话
下面就把我这段时间学习和实践的内容整理一下。
本地视频流的获取是webRTC最基本也是最简单的功能,用到的API是getUserMedia
,调用方法如下:
navigator.mediaDevices.getUserMedia({
audio: ture,
video: true
}) //约束条件
.then(gotLocalMediaStream)
.catch(function (e) {
alert('getUserMedia() error: ' + e.name);
});
function gotLocalMediaStream(mediastream) {
console.log('>>>>正在打开本地摄像头');
localStream = mediastream;
localVideo.srcObject = mediastream;
}
上面代码中的约束条件(constraints)可以用来指定和媒体流有关的属性,比如:
// 只要视频流
{ audio: false, video: true }
//指定视频流的宽高,注意宽高比和采集到的不一样的时候会自动裁剪
{ audio: false, video: { width: 1280, height: 720 } }
//指定视频流的宽高的理想值、最大值和最小值
{
audio: true,
video: {
width: { min: 1024, ideal: 1280, max: 1920 },
height: { min: 776, ideal: 720, max: 1080 }
}
}
另外,对于移动设备,可以通过设置 constraints 指定获取前置摄像头和后置摄像头,对于火狐浏览器,还可以设置视频源为屏幕,但是这些功能我没有自己尝试过,就不放代码了。
有了getUserMedia
这个强大的API,我们就可以很方便地在网页中调用摄像头了。我们可以在HTML文件里加入一个video标签,然后将获得的视频流设置为video对象的srcObject,这点在上面的代码中也体现出来了。
录制视频,需要用到另一个API——MediaRecorder
。这个接口需要通过调用MediaRecorder()构造方法进行实例化,创建一个新的MediaRecorder对象,并对指定的MediaStream对象进行录制。
下面就给出核心的代码,使用的时候把这些方法与对应的事件绑定就好了:
//打开本地摄像头
function openCamera() {
navigator.mediaDevices.getUserMedia({video: true})
.then(stream => {
window.stream = stream;
videoplay.srcObject = stream;
}).catch(error => {
console.log(error);
});
console.log("摄像头已打开!")
}
var buffer;//二进制数组,用于储存视频
var mediaRecorder;
//开始录制
function startRecord() {
buffer = []; //初始化数组
var options = {
//录制视频,格式为webm
mimeType: 'video/webm;codecs=vp8'
};
//检验是否支持mimeType
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
console.log(`${options.mimeType} is not supported`);
return;
}
try {
meidaRecoder = new MediaRecorder(window.stream, options);
} catch (e) {
console.log('Filed tp create MideaRecoder', e);
return;
}
console.log("开始录制视频");
//存储数据时触发事件,数据有效时执行handleDataAvailable
meidaRecoder.ondataavailable = handleDataAvailable;
//设置时间片,每过一个时间片就会存储数据
meidaRecoder.start(10);
}
//停止录制
function stopRecord() {
meidaRecoder.stop();
console.log("结束录制视频");
}
//播放录制的视频
function playRecord() {
var blob = new Blob(buffer, {type: 'video/webm'});
recvideo.src = window.URL.createObjectURL(blob);
recvideo.srcObject = null;
recvideo.control = true;
recvideo.play();
}
//下载录制的视频
function saveRecord(){
var blob = new Blob(buffer, {type: 'video/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.style.display = 'none';
a.download = 'download.mp4';
a.click();
console.log("已下载至本地")
}
上面的代码是用来录制本地摄像头的画面的,如果要录制远程画面也非常容易,只需要将下面这行代码里的 window.stream 替换为远程视频流即可。
meidaRecoder = new MediaRecorder(window.stream, options)