封装录屏方法
export class ScreenRecording {
mediaRecorder: MediaRecorder | null;
stream: MediaStream | null;
chunks: any[];
endCallback: any[];
constructor() {
this.mediaRecorder = null;
this.stream = null;
this.chunks = [];
this.endCallback = [];
}
create() {
return new Promise((resolve, reject) => {
this.resetState();
navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }).then((stream) => {
this.stream = stream;
const mime = MediaRecorder.isTypeSupported("video/webm\;codecs=h264") ? "video/webm\;codecs=h264" : "video/webm";
this.mediaRecorder = new MediaRecorder(stream, { mimeType: mime });
resolve({format: mime === "video/webm\;codecs=h264" ? 'mp4': 'webm'});
}).catch((err) => {
reject(err);
});
});
}
start() {
return new Promise((resolve, reject) => {
this.judgeMediaRecorderIs().then((mediaRecorder: MediaRecorder) => {
mediaRecorder.start();
mediaRecorder.addEventListener('dataavailable', (e) => {
this.chunks.push(e.data);
this.endCallback.forEach((resolve) => {
resolve();
this.endCallback.shift();
});
});
resolve('');
}).catch((err) => {
reject(err);
});
});
}
stop() {
return new Promise((resolve, reject) => {
this.judgeMediaRecorderIs().then((mediaRecorder: MediaRecorder) => {
if (mediaRecorder.state === 'inactive') {
return reject({code: 0, message: '已结束'});
};
mediaRecorder.stop();
this.stream.getTracks().forEach((track) => { track.stop(); })
this.endCallback.push(resolve);
}).catch((err) => {
reject(err);
});
});
}
download() {
return new Promise((resolve, reject) => {
this.handleChunksToBolb().then((blob: Blob) => {
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = MediaRecorder.isTypeSupported("video/webm\;codecs=h264") ? 'video.mp4' : 'video.webm';
a.click();
resolve(url);
}).catch((err) => {
reject(err);
});
});
}
viewRecording() {
return new Promise((resolve, reject) => {
this.handleChunksToBolb().then((blob: Blob) => {
let url = URL.createObjectURL(blob);
resolve(url);
}).catch((err) => {
reject(err);
});
});
}
toFile() {
return new Promise((resolve, reject) => {
this.handleChunksToBolb().then((blob: Blob) => {
let filename = MediaRecorder.isTypeSupported("video/webm\;codecs=h264") ? 'video.mp4' : 'video.webm';
let fileType = filename.includes('.mp4') ? 'video/mp4' : 'video/webm';
resolve(new File([blob], filename, { type: fileType }));
}).catch((err) => {
reject(err);
});
});
}
handleChunksToBolb() {
return new Promise((resolve, reject) => {
this.judgeChunksIs().then((chunks: any) => {
let blob = new Blob(chunks, { type: MediaRecorder.isTypeSupported("video/webm\;codecs=h264") ? 'video/mp4' : chunks[0].type })
resolve(blob);
}).catch((err) => {
reject(err);
});
});
}
judgeChunksIs() {
return new Promise((resolve, reject) => {
let chunks = this.chunks;
if (chunks.length === 0) {
return reject({code: 0, message: '没有录制的缓冲'});
};
return resolve(chunks);
});
}
judgeMediaRecorderIs() {
return new Promise((resolve, reject) => {
let mediaRecorder = this.mediaRecorder;
if (!mediaRecorder) { return reject({code: 0, message: '请先创建一个录制对象'}); };
resolve(mediaRecorder);
});
}
setEndCallback(callback) {
this.endCallback.push(callback);
}
resetState() {
this.chunks = [];
this.mediaRecorder = null;
this.stream = null;
}
};
录屏方法使用
let myScreenRecording = new ScreenRecording();
myScreenRecording.create().then((res: {format: 'mp4'}) => {
myScreenRecording.start();
let endRecording = () => {
myScreenRecording.download();
myScreenRecording.viewRecording().then((srcObject) => {});
myScreenRecording.toFile().then((file) => {});
};
myScreenRecording.setEndCallback(endRecording);
});
myScreenRecording.stop().then(() => {});