当前位置:网站首页>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
边栏推荐
- [untitled]
- mysql的七种join连接查询
- Possible stack order of stack order with length n
- provide/inject
- 输入的查询SQL语句,是如何执行的?
- WGS84 coordinate system, web Mercator, gcj02 coordinate system, bd09 coordinate system - brief introduction to common coordinate systems
- 【看完就懂系列】一文6000字教你从0到1实现接口自动化
- 【虚幻引擎UE】实现测绘三脚架展开动画制作
- Clickhouse synchronization MySQL (based on materialization engine)
- [Chongqing Guangdong education] 2408t Chinese contemporary literature reference test in autumn 2018 of the National Open University
猜你喜欢
Test d'automatisation de l'interface utilisateur télécharger manuellement le pilote du navigateur à partir de maintenant
The scale of computing power in China ranks second in the world: computing is leaping forward in Intelligent Computing
How to use jedis of redis
JVM garbage collection
NetSetMan pro (IP fast switching tool) official Chinese version v5.1.0 | computer IP switching software download
Soul 3: what is interface testing, how to play interface testing, and how to play interface automation testing?
[moteur illusoire UE] il ne faut que six étapes pour réaliser le déploiement du flux de pixels ue5 et éviter les détours! (4.26 et 4.27 principes similaires)
Threejs rendering obj+mtl model source code, 3D factory model
Deep learning - LSTM Foundation
在线SQL转Excel(xls/xlsx)工具
随机推荐
WGS84 coordinate system, web Mercator, gcj02 coordinate system, bd09 coordinate system - brief introduction to common coordinate systems
kubernetes集群之调度系统
Wechat applet development process (with mind map)
Threejs Internet of things, 3D visualization of farms (II)
为什么百度、阿里这些大厂宁愿花25K招聘应届生,也不愿涨薪5K留住老员工?
UI自動化測試從此告別手動下載瀏覽器驅動
Clickhouse synchronization MySQL (based on materialization engine)
Clickpaas low code platform
Use of vscode software
[array]566 Reshape the matrix - simple
Pyqt pyside custom telescopic menu bar sharing (including tutorial)
UI automation test farewell to manual download of browser driver
Uni app common functions /api
Interview related high-frequency algorithm test site 3
Why is there a reincarnation of 60 years instead of 120 years in the tiangan dizhi chronology
Online sql to excel (xls/xlsx) tool
Sequelize. JS and hasmany - belongsto vs hasmany in serialize js
EasyCVR平台出现WebRTC协议视频播放不了是什么原因?
Threejs realizes rain, snow, overcast, sunny, flame
[untitled]