更新vue录制组件
写在开始:部署后提示Cannot read property 'getDisplayMedia' of undefined
,解决方法: 掘金 ,我的解决方式是使用ssl证书
demo预览:https://rec.poshir.top web录屏
来源:简书
如何使用
cmd,粘贴代码,执行 npm install recordrtc
"recordrtc": "^5.6.2",
组件代码
<template>
<div>
<div>
<span @click="startR" class="click-btn"> {{ startTxt }}</span>
</div>
<div v-if="startTxt !== '开始录制'">
<span @click="pauseFn" class="click-btn"> {{ pauseTxt }}</span>
</div>
</div>
</template>
<script>
import RecordRTC from 'recordrtc';
export default {
name: "rec-video",
data() {
return {
startTxt: "开始录制",
pauseTxt: "暂停",
start: null,
isPause: false,
recorder: {},
};
},
methods: {
//开始录制
startR() {
this.startRecording((start) => {
this.start = start;
});
},
startRecording(callback) {
if (this.startTxt === "开始录制") {
this.captureScreen((screenStream) => {
this.addStreamStopListener(screenStream, () => {
console.log("流停止监听");
// 可执行子组件回调
// this.$emit("streamStop", {})
this.stopFn();
});
this.isPause = true;
this.startTxt = "完成录制";
var options = {
type: "video",
mimeType: "video/mp4",
disableLogs: false, // 日志开关
getNativeBlob: false,
ignoreMutedMedia: false,
};
this.recorder = RecordRTC(screenStream, options);
this.recorder.startRecording();
this.recorder.screen = screenStream;
this.videoStart = true;
callback(true);
});
} else if (this.startTxt === "完成录制") {
this.stopFn();
}
},
/**
* 完成录制
*/
stopFn() {
this.startTxt = "开始录制";
this.isPause = false;
this.stopRecording((start) => {
this.start = start;
});
},
/**
* 完成录制回调
*/
stopRecording(callback) {
this.recorder && this.recorder.stopRecording(() => {
this.fileName = this.getTimeIndex()
const url = URL.createObjectURL(this.recorder.getBlob());
this.aTag = document.createElement("a");
// videoFile:File,可上传 预览 下载
let videoFile = new File(
[this.recorder.getBlob()],
this.fileName + ".mp4",
{
type: "video/mp4",
}
);
let downloadUrl = URL.createObjectURL(videoFile);
document.body.appendChild(this.aTag);
this.aTag.style.display = "none";
this.aTag.href = url;
this.videoFile = videoFile;
this.previewVideo = downloadUrl;
// 停止录屏时同时下载到本地
this.aTag.download = this.fileName + ".mp4";
this.aTag.click();
this.recorder.screen.stop();
this.recorder.destroy();
this.recorder = null;
this.videoStart = false;
this.$message({
message: "录屏停止",
type: "success",
});
callback(false);
});
},
$message(e) {
console.log(e);
},
pauseFn() {
if (this.pauseTxt === "暂停") {
this.$message({
message: "录屏已暂停",
type: "success",
});
this.recorder.pauseRecording();
this.pauseTxt = "恢复录制";
} else if (this.pauseTxt === "恢复录制") {
this.$message({
message: "录屏已恢复",
type: "success",
});
this.recorder.resumeRecording();
this.pauseTxt = "暂停";
}
},
//初始化录制
captureScreen(callback) {
if (navigator.getDisplayMedia) {
//录制结束,文件下载
navigator
.getDisplayMedia({
video: true,
audio: true,
})
.then((screenStream) => {
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((mic) => {
screenStream.addTrack(mic.getTracks()[0]);
callback(screenStream);
});
})
.catch(function (error) {
console.log("error", error);
});
} else if (navigator.mediaDevices.getDisplayMedia) {
navigator.mediaDevices
.getDisplayMedia({
video: true,
audio: true,
})
.then((screenStream) => {
navigator.mediaDevices.getUserMedia({ audio: true }).then((mic) => {
screenStream.addTrack(mic.getTracks()[0]);
callback(screenStream);
});
})
.catch(function (error) {
console.log("error", error);
});
} else {
var error = "getDisplayMedia API are not supported in this browser.";
console.log("error", error);
alert(error);
}
},
//流监听
addStreamStopListener(stream, callback) {
stream.addEventListener(
"ended",
function () {
callback();
callback = function () {
};
},
false
);
stream.addEventListener(
"inactive",
function () {
callback();
callback = function () {
};
},
false
);
stream.getTracks().forEach(function (track) {
track.addEventListener(
"ended",
function () {
callback();
callback = function () {
};
},
false
);
track.addEventListener(
"inactive",
function () {
callback();
callback = function () {
};
},
false
);
});
},
getTimeIndex() {
let now = new Date();
let yyyy = now.getFullYear();
let MM = now.getMonth() + 1 > 9 ? now.getMonth() + 1 : `0${now.getMonth() + 1}`;
let DD = now.getDate() > 9 ? now.getDate() : `0${now.getDate()}`;
let HH = now.getHours() > 9 ? now.getHours() : `0${now.getHours()}`;
let mm = now.getMinutes() > 9 ? now.getMinutes() : `0${now.getMinutes()}`;
let ss = now.getSeconds() > 9 ? now.getSeconds() : `0${now.getSeconds()}`;
return `${yyyy}${MM}${DD}${HH}${mm}${ss}`;
}
},
};
</script>
<style>
:root {
--font-color: #fff;
--default-color: #1890ff;
--hover-color: #359dfe;
--text-shadow-color: #0000001f;
--box-shadow-color: #0000000b;
--normal-distance: 15px;
}
.click-btn {
display: inline-block;
transition: .1s;
cursor: pointer;
user-select: none;
padding: 5px var(--normal-distance);
margin-bottom: var(--normal-distance);
border-radius: 2px;
color: var(--font-color);
background: var(--default-color);
border-color: var(--default-color);
text-shadow: 0 -1px 0 var(--text-shadow-color);
box-shadow: 0 2px var(--box-shadow-color);
}
.click-btn:hover {
background: var(--hover-color);
border-color: var(--hover-color);
}
</style>
使用:
父组件内:
<RecVideo/>
...
import RecVideo'@/components/screen.vue';
components: {
RecVideo
}