背景:主 project 页面中会将视频存储到云端后获得 ID ,然后用 ID 调用 后端API POST到数据库后拿到挂载页面URL,接着传入视频分享组件(由于视频分享子组件的目标是分享视频挂载页面,所以前置步骤不能少)
javascript
const recordBlob = await projectRunnerRef.value?.stopRecording?.()
await projectRunnerRef.value?.pauseGame()
console.log('录制已停止,获得 Blob:', recordBlob)
if (!recordBlob) {
toaster.error('录制失败,未获得录制数据')
isRecording.value = false
return
}
// 将 Blob 转换为 File 对象
const fileExtension = recordBlob.type?.includes('webm') ? 'webm' : 'mp4'
const recordFile = new globalThis.File([recordBlob], `recording_${Date.now()}.${fileExtension}`, {
type: recordBlob.type || 'video/webm'
})
recording.value = recordFile
try {
const projectFile = createProjectFile(recordFile)
const RecordingURL = await saveFile(projectFile) // 存储到云端获得视频存储URL
遇到问题:通过查看网络通信发现传输到云端时间很长,所以页面上就像卡住了一样一直等待视频分享弹窗弹出
解决思路:惰性异步处理-不让阻塞其他执行。将原先先把所有必须的内容拿到再弹出弹框变成先加载弹窗,具体里面要用到视频挂载URL的地方其实就是生成二维码的地方,那么写成 'generating' 来优化交互体验,那么就需要将原先 props 传输 recording 变成一个 Promise 来异步处理
javascript
const props = defineProps<{
recording: Promise<RecordData>,
那么接收的是一个 Promise 而非直接的数据,从而允许异步加载,避免阻塞UI渲染,实现了数据与UI的解耦
那么从 project 父组件获得video(可选值,用于首屏展示),同时传入Promise实例用于并行处理
在云端 cloud.ts 中
javascript
export async function saveFiles(
files: Files,
signal?: AbortSignal
): Promise<{ fileCollection: FileCollection; fileCollectionHash: string }> {
const fileCollection = Object.fromEntries(
await Promise.all(Object.keys(files).map(async (path) => [path, await saveFile(files[path]!, signal)] as const))
)
const fileCollectionHash = await hashFileCollection(fileCollection)
return { fileCollection, fileCollectionHash }
}
通过 Promise.all 处理多文件上传
然后在 录屏组件中写一个副作用回调函数用于更新
javascript
async function loadRecordingData() {
if (currentRecording.value) return
try {
currentRecording.value = await props.recording
await updateVideoSrc()
} catch (error) {
console.error('加载录制数据失败:', error)
}
}
在 watch 中回调
javascript
watch(() => props.visible, (newVisible) => {
if (newVisible) {
// 重置状态
jumpUrl.value = ''
qrCodeData.value = ''
// 立即更新视频源(优先使用 props.video)
updateVideoSrc()
// 加载录制数据(用于分享参数)
loadRecordingData()