当前位置:网站首页>After the deployment of web resources, the navigator cannot obtain the solution of mediadevices instance (navigator.mediadevices is undefined)
After the deployment of web resources, the navigator cannot obtain the solution of mediadevices instance (navigator.mediadevices is undefined)
2022-07-05 04:08:00 【lyricist 】
problem
Recently in development , There is a function that needs to realize the function of recording screen , I used recordrtc library , There is no problem with local development in the process , When deploying to online environment navigator.mediaDevices by undefined, I searched many articles and official articles to solve
Causes and solutions
This problem is caused by the security policy of the browser , Currently tried , In the following cases navigator.mediaDevices It can be used normally.
1. The address is localhost:// During the interview
2. The address is https:// when
3. For file access file:///
// notes : If there are other plans, please correct
Attached recordrtc Use the source code for reference ( The reference source code uses element UI)
index.vue
<template>
<div>
<button @click="handleScreenRecord"> Start recording </button>
<el-dialog
style="max-width: 60%"
v-model="screenRecorder.dialogVisible"
:before-close="handleClose"
top="0"
>
<Screenrecording
:isSubmitting="screenRecorder.isSubmitting"
@submit="recordedVideoSubmit"
/>
</el-dialog>
</div>
</template>
<script>
import { defineComponent, reactive } from "vue";
import Screenrecording from "./ScreenRecorder.vue";
export default defineComponent({
components: {
Screenrecording,
},
setup() {
const screenRecorder = reactive({
fileurl: "",
dialogVisible: false,
title: "",
isSubmitting: false,
});
const handleScreenRecord = async () => {
screenRecorder.dialogVisible = true;
};
const recordedVideoSubmit = async (file) => {
screenRecorder.isSubmitting = true;
try {
// Get the recorded file file, Here's the deal file Business logic of
console.log("file", file);
} catch (error) {
// notify.error(error.message)
}
screenRecorder.isSubmitting = false;
};
const handleClose = () => {
screenRecorder.dialogVisible = false;
};
return {
screenRecorder,
handleScreenRecord,
recordedVideoSubmit,
handleClose,
};
},
});
</script>
ScreenRecorder.vue
<template>
<div class="h-recorder-wrapper">
<el-card class="row">
<div class="col-12">
<video
ref="video"
style="width: 100%"
loop
controls
autoplay
playsinline
/>
</div>
<div>
<el-button
ref="startRecord"
@click="startRecord"
:disabled="isSubmitting"
v-show="!recording && !startedBefore"
type="primary"
>
record
</el-button>
<el-button
ref="recordAgain"
@click="startRecord"
v-show="!recording && startedBefore"
:disabled="isSubmitting"
type="primary"
>
recordAgain
</el-button>
<el-button
ref="stopRecord"
v-show="recording"
@click="stopRecord"
type="primary"
>
finish
</el-button>
<el-button
v-show="!recording && startedBefore"
@click="handleRecordedVideo(video.blob)"
type="green"
:loading="isSubmitting"
>
submit
</el-button>
</div>
</el-card>
</div>
</template>
<script>
import RecordRTC from "recordrtc";
export default {
name: "screen-recorder",
langPrefix: "components.recorder",
data() {
return {
recorder: null,
stream: null,
video: null,
recording: false,
startedBefore: false,
};
},
props: {
isSubmitting: {
type: Boolean,
required: true,
},
},
methods: {
handleRecordedVideo() {
this.$emit("submit", {
file: this.video.blob,
});
},
startRecord() {
this.captureScreen((screen) => {
this.video.srcObject = screen;
this.recorder = RecordRTC(screen, {
type: "video",
});
this.recorder.startRecording();
this.recorder.screen = screen;
this.startedBefore = this.recording = true;
});
},
stopRecord() {
this.recorder.stopRecording(this.stopRecordingCallback);
this.recording = false;
},
async stopRecordingCallback() {
this.video.src = this.video.srcObject = null;
const blob = this.recorder.getBlob();
this.video.src = URL.createObjectURL(blob);
this.video.blob = blob;
this.recorder.screen.stop();
this.recorder.destroy();
},
getStream() {
if (navigator.mediaDevices.getDisplayMedia) {
return navigator.mediaDevices.getDisplayMedia({
video: {
displaySurface: "monitor",
logicalSurface: true,
cursor: "always",
},
});
}
},
invokeGetDisplayMedia(success, error) {
let displaymediastreamconstraints = {
video: {
displaySurface: "monitor",
logicalSurface: true,
cursor: "always",
},
};
displaymediastreamconstraints = {
video: true,
};
if (navigator.mediaDevices.getDisplayMedia) {
navigator.mediaDevices
.getDisplayMedia(displaymediastreamconstraints)
.then(success)
.catch(error);
} else {
navigator
.getDisplayMedia(displaymediastreamconstraints)
.then(success)
.catch(error);
}
},
addStreamStopListener(stream, callback) {
stream.addEventListener(
"ended",
() => {
callback();
callback = () => {};
},
false
);
stream.addEventListener(
"inactive",
() => {
callback();
callback = () => {};
},
false
);
stream.getTracks().forEach((track) => {
track.addEventListener(
"ended",
() => {
callback();
callback = () => {};
},
false
);
track.addEventListener(
"inactive",
() => {
callback();
callback = () => {};
},
false
);
});
},
captureScreen(callback) {
this.invokeGetDisplayMedia(
(screen) => {
this.addStreamStopListener(screen, () => {
this.$refs.stopRecord.click();
});
callback(screen);
},
(error) => {
console.error(error);
}
);
},
},
mounted() {
this.video = this.$refs.video;
},
};
</script>
recordrtc Kurt's documents :https://github.com/muaz-khan/RecordRTC
边栏推荐
- Common features of ES6
- Interview summary: This is a comprehensive & detailed Android interview guide
- [array]566 Reshape the matrix - simple
- Rust区块琏开发——签名加密与私钥公钥
- ActiveReportsJS 3.1 VS ActiveReportsJS 3.0
- Soul 3: what is interface testing, how to play interface testing, and how to play interface automation testing?
- Rome链分析
- “金九银十”是找工作的最佳时期吗?那倒未必
- FFmepg使用指南
- Uni app change the default component style
猜你喜欢
【虚幻引擎UE】打包报错出现!FindPin错误的解决办法
UI自动化测试从此告别手动下载浏览器驱动
How to solve the problem that easycvr changes the recording storage path and does not generate recording files?
“金九银十”是找工作的最佳时期吗?那倒未必
EasyCVR更改录像存储路径,不生成录像文件如何解决?
【虚幻引擎UE】实现背景模糊下近景旋转操作物体的方法及踩坑记录
线上故障突突突?如何紧急诊断、排查与恢复
在线SQL转Excel(xls/xlsx)工具
面试汇总:这是一份全面&详细的Android面试指南
Clickhouse materialized view
随机推荐
About the project error reporting solution of mpaas Pb access mode adapting to 64 bit CPU architecture
NetSetMan pro (IP fast switching tool) official Chinese version v5.1.0 | computer IP switching software download
Laravel8 export excel file
Official announcement! The third cloud native programming challenge is officially launched!
长度为n的入栈顺序的可能出栈顺序
NEW:Devart dotConnect ADO. NET
Threejs Internet of things, 3D visualization of factory
Interview summary: This is a comprehensive & detailed Android interview guide
[untitled]
Clickpaas low code platform
Summary of scene design
kubernetes集群之调度系统
Online text line fixed length fill tool
行为感知系统
[charging station]_ Secular wisdom_ Philosophical wisdom _
Resolved (sqlalchemy+pandas.read_sql) attributeerror: 'engine' object has no attribute 'execution_ options‘
Use threejs to create geometry and add materials, lights, shadows, animations, and axes
IronXL for .NET 2022.6
[phantom engine UE] only six steps are needed to realize the deployment of ue5 pixel stream and avoid detours! (the principles of 4.26 and 4.27 are similar)
Pyqt5 displays file names and pictures