提交 8b6f8dd9 authored 作者: 王鹏飞's avatar 王鹏飞

feat: add restart functionality to useLive composable and update live monitor to…

feat: add restart functionality to useLive composable and update live monitor to handle camera permissions
上级 faef753a
...@@ -37,7 +37,7 @@ export function useLive({ enabledUserMedia = true, onStart, onRecord, onStop }: ...@@ -37,7 +37,7 @@ export function useLive({ enabledUserMedia = true, onStart, onRecord, onStop }:
const currentMicrophone = computed(() => microphones.value[0]?.deviceId) const currentMicrophone = computed(() => microphones.value[0]?.deviceId)
// 创建媒体流 // 创建媒体流
const { stream } = useUserMedia({ const { stream, restart } = useUserMedia({
enabled: enabledUserMedia, enabled: enabledUserMedia,
constraints: { video: { deviceId: currentCamera as any }, audio: { deviceId: currentMicrophone as any } }, constraints: { video: { deviceId: currentCamera as any }, audio: { deviceId: currentMicrophone as any } },
}) })
...@@ -98,7 +98,18 @@ export function useLive({ enabledUserMedia = true, onStart, onRecord, onStop }: ...@@ -98,7 +98,18 @@ export function useLive({ enabledUserMedia = true, onStart, onRecord, onStop }:
// 停止录制 // 停止录制
const stop = () => { const stop = () => {
if (mediaRecorder) mediaRecorder.stop() if (mediaRecorder) mediaRecorder.stop()
mediaRecorder = null
} }
return { stream, start, stop, startTime, endTime, duration, currentTime } // 重新开始
const handleRestart = async () => {
// 停止录制
stop()
// 重新获取流
await restart()
// 开始录制
start()
}
return { stream, start, stop, restart: handleRestart, startTime, endTime, duration, currentTime }
} }
...@@ -3,6 +3,7 @@ import { useLive, readBlobAsBase64 } from '@/composables/useLive' ...@@ -3,6 +3,7 @@ import { useLive, readBlobAsBase64 } from '@/composables/useLive'
import { useSocket } from '@/composables/useSocket' import { useSocket } from '@/composables/useSocket'
import md5 from 'blueimp-md5' import md5 from 'blueimp-md5'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { usePermission } from '@vueuse/core'
export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } = {}) { export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } = {}) {
const userStore = useUserStore() const userStore = useUserStore()
...@@ -24,7 +25,7 @@ export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } = ...@@ -24,7 +25,7 @@ export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } =
}, },
}) })
const { stream, startTime, start, stop } = useLive({ const { stream, startTime, start, stop, restart } = useLive({
enabledUserMedia: autoStart, enabledUserMedia: autoStart,
onRecord: async (blob) => { onRecord: async (blob) => {
const base64Data = await readBlobAsBase64(blob) const base64Data = await readBlobAsBase64(blob)
...@@ -37,18 +38,28 @@ export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } = ...@@ -37,18 +38,28 @@ export function useLiveMonitor({ autoStart = false }: { autoStart?: boolean } =
}, },
}) })
watchEffect(() => { const cameraPermission = usePermission('camera')
if (autoStart) {
const showMessageBox = () => {
ElMessageBox.alert('本次考试要求全程开启摄像头,请点击‘确定’允许摄像头访问,以便正常参加考试。', '温馨提示', { ElMessageBox.alert('本次考试要求全程开启摄像头,请点击‘确定’允许摄像头访问,以便正常参加考试。', '温馨提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
beforeClose: (action, instance, done) => { beforeClose: (action, instance, done) => {
if (stream.value) done() console.log('stream', stream.value)
console.log('cameraPermission', cameraPermission.value)
if (stream.value && cameraPermission.value === 'granted') done()
}, },
callback: () => { callback: () => {
start() restart()
}, },
}) })
} }
watchEffect(() => {
if (cameraPermission.value === 'denied') showMessageBox()
})
onMounted(() => {
if (autoStart) showMessageBox()
}) })
onUnmounted(() => { onUnmounted(() => {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论