当前位置:网站首页>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
边栏推荐
- 如何实现实时音视频聊天功能
- Open graph protocol
- 为什么百度、阿里这些大厂宁愿花25K招聘应届生,也不愿涨薪5K留住老员工?
- error Couldn‘t find a package. JSON file in "your path“
- [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)
- The development of mobile IM based on TCP still needs to keep the heartbeat alive
- Clickhouse synchronization MySQL (based on materialization engine)
- 快手、抖音、视频号交战内容付费
- The new project Galaxy token just announced by coinlist is gal
- [wp][introduction] brush weak type questions
猜你喜欢

Threejs rendering obj+mtl model source code, 3D factory model

Looking back on 2021, looking forward to 2022 | a year between CSDN and me

Use threejs to create geometry and add materials, lights, shadows, animations, and axes

Special Edition: spreadjs v15.1 vs spreadjs v15.0

Rome链分析

Use Firefox browser to quickly pick up Web image materials

Rust blockchain development - signature encryption and private key public key
![[wp][introduction] brush weak type questions](/img/d0/9eb3ade701057837d98e4a20082a10.png)
[wp][introduction] brush weak type questions

在线文本行固定长度填充工具

@The problem of cross database query invalidation caused by transactional annotation
随机推荐
[charging station]_ Secular wisdom_ Philosophical wisdom _
Ctfshow 2022 Spring Festival welcome (detailed commentary)
lds链接的 顺序问题
【虛幻引擎UE】實現UE5像素流部署僅需六步操作少走彎路!(4.26和4.27原理類似)
如何实现实时音视频聊天功能
DFS and BFS concepts of trees and graphs
Rome链分析
Rome chain analysis
[understand series after reading] 6000 words teach you to realize interface automation from 0 to 1
Threejs factory model 3DMAX model obj+mtl format, source file download
About the recent experience of writing questions
Enterprise level: spire Office for . NET:Platinum|7.7. x
已解决(sqlalchemy+pandas.read_sql)AttributeError: ‘Engine‘ object has no attribute ‘execution_options‘
【虚幻引擎UE】运行和启动的区别,常见问题分析
Longyuan war "epidemic" 2021 network security competition web easyjaba
根据入栈顺序判断出栈顺序是否合理
How to use jedis of redis
Why do big companies such as Baidu and Alibaba prefer to spend 25K to recruit fresh students rather than raise wages by 5K to retain old employees?
The order of LDS links
Ctfshow web entry code audit