实现功能
前端页面,点击开始录屏,视频录制,点击停止录屏,视频录制结束,并生成视频下载到本地 相对上个版本,解决了,在页面内点停止按钮,可直接触发浏览器的停止共享按钮,两个按钮直接同步
实现代码
vue3+ts
<template>
<!-- <ContentWrap> -->
<!-- 屏幕共享控制按钮 -->
<BaseButton size="small" type="primary" class="btn mt-2px" @click="toggleScreenShare">
{{ isRecording ? '停止录制' : '开始录制' }}
</BaseButton>
<!-- 权限错误提示 -->
<p v-if="permissionError" class="error-message">请允许屏幕共享权限以便继续。</p>
<!-- </ContentWrap> -->
</template>
<script setup lang="ts">
// import { ContentWrap } from '@/components/ContentWrap'
import { ref } from 'vue'
// 声明变量以跟踪媒体记录器状态、数据块、是否正在录制及权限错误
const mediaRecorder = ref<MediaRecorder | null>(null)
const chunks = ref<BlobPart[]>([])
const isRecording = ref(false)
const permissionError = ref(false)
// 切换屏幕共享状态
async function toggleScreenShare() {
if (!isRecording.value) {
await startScreenShare()
} else {
stopScreenShare()
}
}
// 初始化屏幕共享流
let screenStream = ref<MediaStream | null>(null)
// 开始屏幕共享录制
async function startScreenShare() {
try {
// 请求显示媒体流(屏幕共享)
screenStream.value = await navigator.mediaDevices.getDisplayMedia({ video: true })
if (!screenStream.value) throw new Error('用户未授权屏幕共享。')
// 设置视频编码(优先H264,否则默认)
const mimeType = MediaRecorder.isTypeSupported('video/webm;codecs=h264')
? 'video/webm;codecs=h264'
: 'video/webm'
// 初始化媒体记录器
mediaRecorder.value = new MediaRecorder(screenStream.value, { mimeType })
// 监听数据可用事件,收集录制的数据块
mediaRecorder.value.addEventListener('dataavailable', handleDataAvailable)
// 监听停止事件,处理录制完成后的操作
mediaRecorder.value.addEventListener('stop', onMediaRecorderStop)
// 开始录制
mediaRecorder.value.start()
isRecording.value = true
} catch (error) {
console.error('屏幕共享启动失败:', error)
if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {
permissionError.value = true
}
}
}
// 数据块处理函数
function handleDataAvailable(event: BlobEvent) {
// 收集每个数据块到chunks数组中
chunks.value.push(event.data)
}
// 停止屏幕共享录制
function stopScreenShare() {
if (mediaRecorder.value && mediaRecorder.value.state !== 'inactive') {
mediaRecorder.value.stop()
// 停止所有轨道,//直接触发浏览器的停止分享按钮
screenStream.value?.getTracks().forEach((track) => track.stop())
screenStream.value = null
}
}
// 录制完成后处理函数
function onMediaRecorderStop() {
if (chunks.value.length) {
// 将数据块转换为Blob,创建下载链接
const blob = new Blob(chunks.value, { type: chunks.value[0].type })
const url = URL.createObjectURL(blob)
const downloadLink = document.createElement('a')
downloadLink.href = url
downloadLink.download = 'screen_recording.webm'
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
// 清理资源
chunks.value = []
mediaRecorder.value = null
isRecording.value = false
}
}
</script>
<style scoped>
.error-message {
color: red;
margin-top: 10px;
}
</style>
存在问题
在切换页面的时候,在切回来,原页面的停止按钮他会初始化成 开始录制,点击的话他又重新录,但上个媒体还在进行,这样肯定有问题,如果存在需要切换页面的情况,建议直接使用浏览器的停止共享按钮
参考
// getTracks() developer.mozilla.org/zh-CN/docs/…