WebRtc基本应用
WebRTC(Web Real-Time Communication)是一种支持实时音视频通信的开放标准,它允许在无需任何插件或中间件的情况下,在Web浏览器之间直接进行点对点(Peer-to-Peer)的音视频通信。WebRTC定义了三个关键部分:媒体层、传输层和控制层。媒体层包括音频编解码器、视频编解码器和网络摄像机/麦克风的输入/输出接口。传输层提供了实时传输协议(RTP)和数据交换机制。控制层则提供了API接口,以便开发者在浏览器中集成WebRTC功能。
getUserMedia 视频录制
js
const constraints = { video: true, audio: true }
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
// srcObject 接收 srcObject 属性即可播放内容
videoEl.srcObject = stream
}
getUserMedia 接受参数[constraints]用于指定 MediaStream 中包含哪些类型的媒体轨(音频轨、视频轨),并对媒体轨做设置(如设置视频的宽高、帧率等)。
返回一个 promise 对象,成功后会获得流媒体对象 MediaStream(包含从音视频设备中获取的音视频数据); 使用 getUserMedia 时,浏览器会询问用户,开启音频和视频权限。如果用户拒绝或无权限时,则返回 error。
MediaDevices.enumerateDevices() 设备信息获取
获取可用的媒体输入和输出设备的列表,例如:麦克风、相机、耳机等
js
var enumeratorPromise = navigator.mediaDevices.enumerateDevices()
js
// 获取视频音频授权,回调中就是视频的内容
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
// 将stream流,直接添加到srcObject 中,页面中的video标签就会显示所对应的视频画面
videoPlay.srcObject = stream;
// 获取设备选项
// 可根据对应的kind值,来判断对应的设备所属的类别
// kind类型分别为 audioinput audiooutput videoinput
// 分别是 音频输入 音频输出 视频输入
navigator.mediaDevices.enumerateDevices().then(gotDevice);
return navigator.mediaDevices.enumerateDevices();
});
function gotDevice(deviceInfos) {
deviceInfos.forEach((item) => {
console.log(item);
var option = document.createElement("option");
option.text = item.label;
option.value = item.deviceId;
if (item.kind === "audioinput") {
// 音频输入
audioSource.appendChild(option);
} else if (item.kind === "audiooutput") {
// 音频输出
audioOutput.appendChild(option);
} else if (item.kind === "videoinput") {
// 视频输入
videoSource.appendChild(option);
}
});
}
视频录制约束参数
js
// 视频约束
// 对视频录制时做的一些限制
/** width
* height
* aspectRatio
* frameRate 帧率 帧率高了视频数据就大了
* facingMode
* user 前置摄像头
* environment 后置摄像头
* left 前置左侧摄像头
* right 前置右边摄像头
*
* 电脑没有就会被忽略,不起效
* resizeMode 画面是否需要裁剪
*/
const constraints = {
video: {
width: 640,
height: 480,
frameRate: 30,
facingMode: user,
},
audio: false,
};
音频录制约束参数
js
/**
* 音频约束
* volume 音量大小 0 - 100
* sampleRate 采样率
* sampleSize 采样大小
* echoCancellation 是否开启回音消除 true or false
* autoGainControl 声音增益,在原有的基础上继续增强 true or false
* noiseSuppression 降噪 true or false
* latency 延迟大小 一般低于500ms 最好是在200ms以内 延迟大声音会相对平滑
* channelCount 单声道和多声道
* deviceID 多个录制设备时,可进行多个设备的切换
* groupID 同一个物理设备
*/
MediaDevices.getDisplayMedia() 屏幕共享
提示用户去选择和授权捕获展示的内容或部分内容(如一个窗口)在一个 MediaStream 里。然后,这个媒体流可以通过使用 MediaStream Recording API 被记录或者作为 WebRTC 会话的一部分被传输。用于共享屏幕时传递。
js
const constraints = {
video: {
width: 640,
height: 480,
},
audio: false,
};
navigator.mediaDevices.getDisplayMedia(constraints).then((stream) => {
// 获取视频流直接用于页面播放
videoPlay.srcObject = stream;
window.stream = stream
// 获取媒体流中的视频轨道
var videoTrack = stream.getVideoTracks()[0]
// 获取视频轨道的视频约束
var videoConstraints = videoTrack.getSettings()
// 将约束转为字符串显示在dom元素中
var videoContentDom = document.querySelector('#videoContent')
videoContentDom.textContent = JSON.stringify(videoConstraints, null, 2)
// 获取设备选项
navigator.mediaDevices.enumerateDevices().then(gotDevice);
return navigator.mediaDevices.enumerateDevices();
});
视频录制
js
buffer = []
// 开始录制,需要获取视频流
var options = {
mimeType: 'video/webm; codecs=vp9'
}
// 判断是否支持mimeType这种类型,如果不支持就无法继续录制
if(!MediaRecorder.isTypeSupported(options.mimeType)) {
console.error('不支持mimetype')
return
}
// 视频流,就是getDisplayMedia or getUserMedia 中返回的stream
// 创建 MediaRecorder 对象
try {
mediaRecorder = new MediaRecorder(window.stream, options)
} catch (e) {
console.error(e)
}
// 定义数据片段存储时的存储位置
mediaRecorder.ondataavailable = function (e) {
if (e && e.data && e.data.size > 0) {
buffer.push(e.data)
}
};
// 开始录制 当前的10是时间片,每一段存储一次
mediaRecorder.start(10)
// 存储完成后,将buffer发送给接口即可
录制视频播放
js
// 如果需要将录制的视频本地播放
var blob = new Blob(buffer, { type: "video/webm" });
// 使用window.URL.createObjectURL 创建成对应的播放路径赋值给src即可播放
Luplayer.src = window.URL.createObjectURL(blob);
// 此处srcObject不使用所以设置为null
Luplayer.srcObject = null;
// controls 显示控制表示,例如暂停和开始的按钮
Luplayer.controls = true;
// 开始播放
Luplayer.play();