自制视频播放组件:监视配置项变化
概述
上节完成的基础 VideoPlayer 组件存在一个不足:当用户切换视频源(sources)时,播放器不会自动重新加载新视频。本节为 VideoPlayer 组件添加 watch 监听,当 sources 变化时自动暂停当前播放并加载新的视频源。
问题描述
<!-- 切换视频源无效 -->
<template>
<VideoPlayer :options="playerOptions" />
<el-button @click="changeSource">切换视频</el-button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const playerOptions = ref({
sources: [{ src: 'video-01.mp4', type: 'video/mp4' }]
})
function changeSource() {
// 修改 sources 后,播放器不会自动切换
playerOptions.value.sources = [{ src: 'video-02.mp4', type: 'video/mp4' }]
}
</script>
vue
问题原因:组件初始化时创建了 Video.js 实例,但未监听 props 变化,导致 sources 更新后播放器不响应。
修复方案
监听 sources 变化
// components/video/VideoPlayer.vue
import { watch } from 'vue'
// 监听 sources 变化,动态切换视频源
watch(
() => props.options?.sources,
(newSources) => {
if (!player || !newSources) return
// 1. 先暂停当前播放
player.pause()
// 2. 切换视频源
player.src(newSources)
},
{ deep: true }
)
typescript
完整的 watch 逻辑
// 监听 props.options 变化
watch(
() => props.options,
(newOptions) => {
if (!player || !newOptions) return
// sources 变化:暂停并切换源
if (newOptions.sources) {
player.pause()
player.src(newOptions.sources)
}
// 其他配置项变化
if (newOptions.autoplay !== undefined) {
player.autoplay(newOptions.autoplay)
}
if (newOptions.loop !== undefined) {
player.loop(newOptions.loop)
}
if (newOptions.muted !== undefined) {
player.muted(newOptions.muted)
}
if (newOptions.playbackRates) {
player.playbackRates(newOptions.playbackRates)
}
},
{ deep: true }
)
// 单独监听 src prop(简化版)
watch(
() => props.src,
(newSrc) => {
if (player && newSrc) {
player.pause()
player.src({ src: newSrc, type: getVideoType(newSrc) })
}
}
)
typescript
为什么不重新创建实例
// 方案一:仅切换 sources(推荐)
// 优点:保持播放器状态、不闪烁、速度快
watch(() => props.src, (newSrc) => {
player.pause()
player.src({ src: newSrc, type: getVideoType(newSrc) })
})
// 方案二:销毁并重新创建实例
// 缺点:页面闪烁、丢失播放器状态、性能差
watch(() => props.options, (newOptions) => {
player.dispose()
initPlayer(newOptions) // 重新创建
}, { deep: true })
typescript
| 方案 | 性能 | 用户体验 | 适用场景 |
|---|---|---|---|
| 切换 sources | 好 | 无闪烁 | 日常切换视频 |
| 销毁重建 | 差 | 有闪烁 | 需要完全重置配置 |
Video.js 动态 API
| API | 说明 | 用法 |
|---|---|---|
player.src(source) | 切换视频源 | player.src({ src: 'new.mp4', type: 'video/mp4' }) |
player.pause() | 暂停播放 | player.pause() |
player.play() | 开始播放 | player.play() |
player.autoplay(val) | 设置自动播放 | player.autoplay(true) |
player.loop(val) | 设置循环播放 | player.loop(true) |
player.muted(val) | 设置静音 | player.muted(true) |
player.playbackRates(rates) | 设置倍速选项 | player.playbackRates([0.5, 1, 2]) |
player.dispose() | 销毁实例 | player.dispose() |
实践要点
- 监听
sources变化时,先调用player.pause()暂停当前视频 - 使用
player.src()切换源,而非销毁重建实例 - 配置项(autoplay、loop、muted)变更可通过对应的 setter 方法动态更新
watch需设置{ deep: true }才能检测 sources 数组内部变化- 后续如需完全重置播放器配置,再考虑 dispose + 重新 init
↑