导语:最近研究了一下网页录制音视频的原理以及实现,现在就目前的实现方法做一个总结。
# 目录
- 相关API
- 方法介绍
- 实战演练
# 相关API
要实现这个功能就涉及到两个js api。
# 方法介绍
# getUserMedia
通过getUserMedia
这个接口来获取设备的摄像头和麦克风,返回一个Promise
对象。
语法var stream = navigator.mediaDevices.getUserMedia(constraints);
constraints
包括一下几种写法:
- 请求音视频
const constraints = {
audio: true,
video: true
}
1
2
3
4
2
3
4
- 请求特定的设备视频分辨率
const constraints = {
audio: true,
video: {
width: {
min: 1280
},
height: {
min: 720
}
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 使用前摄像头(默认)
const constraints = {
audio: true,
video: {
facingMode: "user"
}
}
1
2
3
4
5
6
2
3
4
5
6
- 强制使用后置摄像头
const constraints = {
audio: true,
video: {
facingMode: {
exact: "environment"
}
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
例如:
const constraints = {
audio: true,
video: {
width: 1280,
height: 720
}
};
async function createMedia() {
try {
let stream = await navigator.mediaDevices.getUserMedia(constraints);
var video = document.querySelector('video');
video.srcObject = stream;
video.onloadedmetadata = function (e) {
video.play();
};
} catch (error) {
console.log(`getUserMedia: ${error}`);
}
}
createMedia();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
当然了这个stream
还有一些方法可以使用,比如
addTrack
给流添加一个新轨道getAudioTracks
包含流中所有的音轨getVideoTracks
于媒体流中包含的每个视频轨道getTracks
此流的中的所有对象
# MediaRecorder
这个就是录制流的一个方法。
start
开始录制stop
结束录制onstop
监听结束事件ondataavailable
实时流数据
语法var mediaRecorder = new MediaRecorder(stream[, options]);
例如
// stream就是上面获取的音视频流
let options = {
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000,
}
let mediaRecorder = new MediaRecorder(stream, options);
// 实时的录制流数据
mediaRecorder.ondataavailable = function (e) {
console.log(e.data);
}
// 监听停止录制事件并生成播放地址
mediaRecorder.onstop = function () {
let blob = new Blob(chunks, {'type': mediaRecorder.mimeType});
let url = window.URL.createObjectURL(blob);
console.log(url);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 实战演练
- 页面结构部分
<audio controls src=""></audio>
<video controls src="" style="width: 100%;"></video>
<button id="start">开始音频</button>
<button id="stop">结束音频</button>
<button id="play">播放音频</button>
<button id="startVideo">开始视频</button>
<button id="stopVideo">结束视频</button>
<button id="playVideo">播放视频</button>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- js部分
获取元素添加事件
// 获取按钮
let audioStart = document.querySelector('#start');
let audioStop = document.querySelector('#stop');
let audioPlay = document.querySelector('#play');
let startVideo = document.querySelector('#startVideo');
let stopVideo = document.querySelector('#stopVideo');
let playVideo = document.querySelector('#playVideo');
// 音频操作
audioStart.onclick = function () {
start('audio');
}
audioStop.onclick = function () {
stop('audio');
}
audioPlay.onclick = function () {
document.querySelector('audio').play();
}
// 视频操作
startVideo.onclick = function () {
start('video');
}
stopVideo.onclick = function () {
stop('video');
}
playVideo.onclick = function () {
document.querySelector('video').play();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
开始录制
// 开始录制
function start (type) {
let option = type == 'audio' ? {
audio: true
} : {
video: true,
}
createMedia(type, option);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
停止录制
// 停止录制
function stop (type) {
mediaRecorder.stop();
}
function stopSet (type) {
if (type == 'audio') {
stream.getAudioTracks()[0].stop();
stream = null;
} else {
stream.getVideoTracks()[0].stop();
}
stream = null;
mediaRecorder = null;
chunks = [];
meida = null;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
通用方法
// 全局参数
let stream = null,mediaRecorder = null,chunks = [], media = null;
async function createMedia (type, option) {
try {
// 获取媒体流
stream = await navigator.mediaDevices.getUserMedia(option);
media = document.querySelector(type);
if (type === 'video') {
media.srcObject = stream;
}
console.log(type, stream);
// 录制流
let options = {
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000,
}
mediaRecorder = new MediaRecorder(stream, options);
console.log(type, mediaRecorder);
mediaRecorder.ondataavailable = function (e) {
chunks.push(e.data);
}
mediaRecorder.start();
// 停止录制
mediaRecorder.onstop = function () {
let blob = new Blob(chunks, {'type': mediaRecorder.mimeType});
let url = window.URL.createObjectURL(blob);
if (type === 'video') {
media.srcObject = null;
}
media.src = url;
stopSet(type);
}
} catch (error) {
console.log('getUserMedia: ', error);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
看下效果
想要体验的可以打开这个音视频录制 (opens new window),手机上使用更佳。
好了,今天的教程就介绍到这里,拜拜!