useDisplayMedia是什么?VueUse官方文档写着这么一句话:Reactive mediaDevices.getDisplayMedia streaming。先说一下这句话。其实mediaDevices 是 Navigator对象的一个只读属性,它返回一个 MediaDevices 对象,里面呢可以对设备的相机、麦克风等媒体输入进行连接访问,同时还可以进行屏幕共享。useDisplayMedia其实就是对它进行了一个封装。这样使用起来呢就更加的方便了。这里我们就做一个跟useDisplayMedia一样的屏幕共享的demo,但是我们在它的基础上增加视频录制、并且下载到本地的功能。这个就比较好玩,比如说你像录制自己玩游戏的视频,或者说一些比较短的视频、音乐等等的录制,你可以对这个demo做一些深入的改造。变成自己的一个录制小工具。
先了解一下navigator的坑。比如我们想通过它获取当前的地理位置定位、媒体的时候。http协议受浏览器的安全机制。是没有办法正常使用相关的API,比如你的ip是192.**.**.**。这种方式的话必须是https协议才可以正常使用相关功能,但是呢http协议下使用localhost或者127.0.0.1是可以正常测试开发的。如果想要深入了解相关规则的话可以去https://goo.gl/Y0ZkNV
案例使用到的一些API 创建媒体记录器 MediaRecorder
MediaRecorder接收两个参数stream和options(可选) 详细看下面的代码
interface MediaRecorderOptions {
audioBitsPerSecond?: number; // 媒体的音频组件选择的比特率。
bitsPerSecond?: number; // 媒体的视频分量选择的比特率。
mimeType?: string; // 指定输出媒体的格式 比如video/mp4
videoBitsPerSecond?: number; // 可以指定它来代替上述audioBitsPerSecond和 videoBitsPerSecond两个属性
}
new MediaRecorder(stream);
new MediaRecorder(stream, options);
// stream: MediaStream options?: MediaRecorderOptions
创建MediaRecorder后我们就可以对它的开始、结束等事件进行一些监听,从而处理一些我们的逻辑。完整示例如下:
注:例子中使用的vue3写法,因为我做了按需引入配置,对应的api自己手动引入一下。
http://Vite4+Pinia2+vue-router4+ElmentPlus搭建Vue3项目(组件、图标等按需引入)[保姆级]
<template>
<div class="demo">
<div style="margin-bottom: 30px;">
<el-button @click="enabled = !enabled">
{{ enabled ? '停止' : '开始' }} 共享我的屏幕
</el-button>
<el-button v-if="enabled && !stopRecordingShow" @click="recording">
录制我的屏幕
</el-button>
<el-button v-if="stopRecordingShow" @click="stopRecording">
停止录制
</el-button>
</div>
<video
ref="video"
muted
autoplay
controls
style="height: 40rem;"
/>
</div>
</template>
<script lang="ts">
import { useDisplayMedia } from '@vueuse/core'
export default defineComponent({
setup() {
const video = ref<HTMLVideoElement>()
let stopRecordingShow = ref<boolean>(false)
const { stream, enabled } = useDisplayMedia({video: true})
watchEffect(() => {
if (video.value)
video.value.srcObject = stream.value!
})
let mediaRecorder = ref<MediaRecorder>()
let videoStreaming = ref<Blob[]>([])
const recording = () => {
stopRecordingShow.value = true
mediaRecorder.value = new MediaRecorder(stream.value!)
// timeslice?: number 传递一个timeslice以毫秒为单位的参数。如果指定了此项
// 则媒体将在该持续时间的单独块中捕获,而不是在单个大块中记录媒体的默认行为。
mediaRecorder.value.start()
// 视频录制视频流数据
// 停止记录,此时会触发dataavailable包含最终Blob保存数据的事件。不再进行记录。
// https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/dataavailable_event
mediaRecorder.value.addEventListener("dataavailable", (event) => {
if (event.data.size > 0) {
videoStreaming.value.push(event.data)
}
})
mediaRecorder.value.addEventListener("stop", () => {
console.log("它暂停了暂停了!!!!!");
const a = document.createElement('a')
const blob = new Blob(videoStreaming.value, { type : 'video/mp4' });
a.href = URL.createObjectURL(blob)
a.setAttribute(
'download',
'这是我的录制视频'
)
document.body.appendChild(a)
a.click();
console.log('成功下载到本地了,你可以打开看看!!!!')
document.body.removeChild(a)
});
mediaRecorder.value.addEventListener("start", (e) => {
console.log("注意注意,开始录制了啊!!!!!");
})
}
const stopRecording = () => {
stopRecordingShow.value = false
if (mediaRecorder.value)
mediaRecorder.value.stop()
}
return {
video,
enabled,
recording,
stopRecording,
stopRecordingShow
}
}
})
</script>
<style lang="less">
.demo {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>
这里只是一个简单的demo演示,所以一些细节的处理就不用那么在意了。
这个是我点击录制以后生成视频。完工!!!!
我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏😍。
👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇