遇到困难就克服困难
客户有需要,需要在浏览器中进行录屏,然后生成视频,传给后端,保存当前的操作流程,然后进行回看
这里用到了navigator.mediaDevices用来获取需要录制的窗口
首先进行窗口的获取(注:获取窗口是因为安全机制的需要进行授权,如果不想多进行一步这样的操作,可以选择rrweb)
多唠叨一句,rrweb是对与操作的记录,利用的是canvas的原理,只有页面发生变化时才会记录此次操作,但是如果记录的页面有canvas,就会有记录不上的问题
// 屏幕捕获参数
const displayMediaOptions= {
video: {
cursor: "always",
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
},
};
let captureStream = navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
然后进行屏幕的录制
// 找到支持的格式
let recordedBlobs = []
function getSupportedMimeTypes() {
const possibleTypes = [
"video/webm;codecs=vp9,opus",
"video/mp4;codecs=h264,aac",
"video/webm;codecs=vp8,opus",
"video/webm;codecs=h264,opus",
];
return possibleTypes.filter((mimeType) => {
return MediaRecorder.isTypeSupported(mimeType);
});
}
const mimeType = this.getSupportedMimeTypes()[0];
const options = { mimeType };
//录制屏幕
let mediaRecorder = new MediaRecorder(captureStream, options);
//设置保存
mediaRecorder.ondataavailable = (event: any) => {
if (event.data && event.data.size > 0) {
console.log("handleDataAvailable", event);
//保存的为二进制
recordedBlobs.push(event.data);
}
};
//开始录制
mediaRecorder.start();
停止视频的录制
mediaRecorder.stop();
最后进行视频的下载
function downloadVideo() {
const blob = new Blob(this.recordedBlobs, { type: "video/webm" });
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = "录屏_" + new Date().getTime() + ".webm";
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
}
最后对于视频录制功能进行了封装,直接将视频流传给后端
// 屏幕捕获参数
const displayMediaOptions: any = {
video: {
cursor: "always",
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
},
};
// 定义函数
class recordVideo {
// 保存窗口
private captureStream: any = null;
// 保存开始录制的视屏
private mediaRecorder: any = null;
// 保存录制视频
private recordedBlobs: any[] = [];
constructor() {
// this.startCapture();
}
// 开始捕获
startCapture() {
this.recordedBlobs = [];
var promise = new Promise((resolve: any, reject) => {
if (!this.captureStream) {
navigator.mediaDevices
.getDisplayMedia(displayMediaOptions)
.then((result: any) => {
this.captureStream = result;
console.log("选择窗口后", result);
this.startRecording(result);
resolve(true);
});
} else {
this.startRecording(this.captureStream);
resolve(true);
}
});
return promise;
// 停止捕获
stopCapture() {
let tracks = this.captureStream.getTracks();
tracks.forEach((track: any) => track.stop());
this.captureStream = null;
}
// 找到支持的格式
getSupportedMimeTypes() {
const possibleTypes = [
"video/webm;codecs=vp9,opus",
"video/mp4;codecs=h264,aac",
"video/webm;codecs=vp8,opus",
"video/webm;codecs=h264,opus",
];
return possibleTypes.filter((mimeType) => {
return MediaRecorder.isTypeSupported(mimeType);
});
}
// 开始录制
startRecording(captureStream: any) {
const mimeType = this.getSupportedMimeTypes()[0];
const options = { mimeType };
// console.log(121212, this.captureStream, options);
try {
this.mediaRecorder = new MediaRecorder(captureStream, options);
// console.log(this.mediaRecorder, "123123");
} catch (e) {
// showMsg(`创建MediaRecorder出错: ${JSON.stringify(e)}`);
return;
}
this.mediaRecorder.ondataavailable = (event: any) => {
if (event.data && event.data.size > 0) {
console.log("handleDataAvailable", event);
this.recordedBlobs.push(event.data);
}
};
this.mediaRecorder.start();
}
// 保存
handleDataAvailable(event: any) {
console.log("handleDataAvailable", event);
if (event.data && event.data.size > 0) {
this.recordedBlobs.push(event.data);
}
}
// 停止录制
//
stopRecord(callback: Function) {
this.mediaRecorder.stop();
setTimeout(() => {
callback(this.recordedBlobs);
}, 1000);
}
// 下载视频
downloadVideo() {
const blob = new Blob(this.recordedBlobs, { type: "video/webm" });
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = "录屏_" + new Date().getTime() + ".webm";
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
}
}
export default new recordVideo();
调用
recordVideo.startCapture().then(() => {
//获取完屏幕,记录下面的操作,开始录屏
})
//停止录屏
recordVideo.stopRecord((video: any) => {
const blob = new Blob(video, { type: "video/webm" });
let formate = new FormData();
formate.append("id", data[0].id);
formate.append("file", blob, "video.mp4");
//将视频传给后端(formate)
。。。
});