// 开始屏幕录制
async startRecording() {
const stream = await invokeGetDisplayMedia();
if(!stream) return;
let videoIndex = 0; //录屏分片序号
let dataArr = []; // 本地看视频
let mediaRecorderTimer = null; // 定时上传录屏文件
const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")
? "video/webm;codecs=h264"
: "video/webm";
const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });
mediaRecorder.ondataavailable = event => {
if (event.data && event.data.size > 0) {
dataArr.push(event.data);
if(mediaRecorder.state === 'inactive') { // 判断是否停止录制
// to do
let mediaBlob = new Blob(dataArr, { type: "video/webm" });
document.getElementById("recVideo").src = window.URL.createObjectURL(mediaBlob);
}
const formData = new FormData();
formData.append("videoIndex", videoIndex)
formData.append("file", event.data)
request({
url: '/upload',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
responseType: 'blob',
data: formData,
timeout: 1000 * 60 * 10,
})
videoIndex++;
}
};
// 初始化开始
mediaRecorder.start();
// 监听停止录屏
mediaRecorder.onstop = () => {
clearInterval(mediaRecorderTimer);
mediaRecorderTimer = null;
}
// 设置定时上传录屏分片
mediaRecorderTimer = setInterval(() => {
if (mediaRecorder) {
mediaRecorder.requestData();
}
}, 10000); // 每10000毫秒请求一次
}
// 获取屏幕录制授权
async invokeGetDisplayMedia() {
return new Promise(async (resolve, reject) => {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
const displaymediastreamconstraints = {
video: true,
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
},
screen: true,
preferCurrentTab: true,
};
const stream = await navigator.mediaDevices.getDisplayMedia(
displaymediastreamconstraints
);
if (stream) {
resolve(stream);
} else {
reject(false);
}
} else {
console.log('浏览器不支持getUserMedia');
reject(false);
}
});
}
注意
让后端拿到全部的视频流文件再去转成视频,如果拿到第一个就转,那么后面的切片文件会缺少头部数据,视频将无法正常拼接。
网友评论