Vue视频播放实战:vue-video-player与dplayer全攻略
Vue 视频播放实战:vue-video-player 与 DPlayer 全攻略
目录
- 前言
- 环境准备
- 3.1 安装与引入
- 3.2 基础使用示例
- 3.3 常用配置与自定义控件
- 3.4 事件监听与 API 调用
- 3.5 组件结构图解
- 4.1 安装与引入
- 4.2 基础使用示例
- 4.3 弹幕、字幕与画中画功能
- 4.4 主题、自定义按钮与插件扩展
- 4.5 技术架构图解
- 对比与选型建议
- 常见问题与优化
- 总结
前言
在现代前端项目中,视频播放几乎是标配功能。Vue 生态下,有两个常见的成熟播放器解决方案:
- vue-video-player:基于 Video.js 封装的 Vue 组件,兼容性好,功能全面;
- DPlayer:一款轻量级、体验感极佳的 HTML5 弹幕播放器,支持弹幕、画中画、章节等高级功能,深受国内社区喜爱。
本文将从零开始,带你一步步掌握以上两个组件在 Vue(Vue 3 + Vite/CLI 或 Vue 2 + Vue CLI)项目中的集成与使用,并通过大量代码示例与图解,帮助你快速上手、灵活定制,轻松应对项目中的各种视频播放需求。
环境准备
Vue 版本
- 若使用 Vue 3,请确保项目使用 Vite 或 Vue CLI 4+,并存在
vue@^3.x
。 - 若使用 Vue 2,请确保 Vue CLI 3+ 创建的项目,且存在
vue@^2.x
。
- 若使用 Vue 3,请确保项目使用 Vite 或 Vue CLI 4+,并存在
Node.js 与包管理
- Node.js 14+ 版本,NPM/Yarn/PNPM 均可。
播放器依赖
- vue-video-player:需要安装
video.js
、vue-video-player
。 - DPlayer:需要安装
dplayer
,可选@types/dplayer
(TypeScript 项目)。
- vue-video-player:需要安装
开发工具
- 推荐 VSCode、Android Studio(若做移动端调试)等。
vue-video-player 实战
vue-video-player
是基于 Video.js 封装的 Vue 组件,兼容 HLS、MP4、WebM 等多种视频格式,支持自定义皮肤、插件。在 Vue 项目中集成后,基本可以当作一个常规组件使用。
3.1 安装与引入
注意:以下示例以 Vue 3 + Vite 为主。Vue 2 项目逻辑类似,仅引入方式略有差异(组件名称与导入写法)。
步骤 1:安装依赖
# Vue 3 + Vite 或 Vue CLI 下
npm install video.js vue-video-player --save
# 或
yarn add video.js vue-video-player
安装后,在 node_modules
中会有:
video.js/
: Video.js 核心库vue-video-player/
: Vue 封装组件
步骤 2:全局注册(可选)
若想在项目全局直接使用 <VideoPlayer>
,可在入口文件(main.js
或 main.ts
)中进行注册。
// main.js(Vue 3)
import { createApp } from 'vue';
import App from './App.vue';
// 1. 引入样式
import 'video.js/dist/video-js.css';
import 'vue-video-player/dist/vue-video-player.css';
// 2. 引入组件
import VueVideoPlayer from 'vue-video-player';
// 3. 创建应用并注册
const app = createApp(App);
app.use(VueVideoPlayer);
app.mount('#app');
Vue 2 + Vue CLI 示例
// main.js(Vue 2) import Vue from 'vue'; import App from './App.vue'; import 'video.js/dist/video-js.css'; import 'vue-video-player/dist/vue-video-player.css'; import VueVideoPlayer from 'vue-video-player'; Vue.use(VueVideoPlayer); new Vue({ render: h => h(App), }).$mount('#app');
如果你不想全局注册,也可以在单个组件里按需引入:
<script setup>
import { VideoPlayer } from 'vue-video-player';
import 'video.js/dist/video-js.css';
import 'vue-video-player/dist/vue-video-player.css';
</script>
<template>
<video-player :options="playerOptions" />
</template>
3.2 基础使用示例
假设我们在 src/components/VideoDemo.vue
中使用 <video-player>
:
<template>
<div class="video-demo">
<h2>vue-video-player 基础示例</h2>
<video-player
class="video-player vjs-custom-skin"
:options="playerOptions"
@ended="onEnded"
@play="onPlay"
@pause="onPause"
></video-player>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { VideoPlayer } from 'vue-video-player';
// 引入样式
import 'video.js/dist/video-js.css';
import 'vue-video-player/dist/vue-video-player.css';
const playerOptions = ref({
autoplay: false, // 是否自动播放
controls: true, // 是否显示控制栏
preload: 'auto', // 视频预加载
loop: false, // 是否循环播放
muted: false, // 是否静音
language: 'en', // 控制栏语言
liveui: false, // 是否使用直播模式样式
sources: [
{
type: 'video/mp4',
src: 'https://www.w3schools.com/html/mov_bbb.mp4'
}
],
// 若需 HLS 格式,可用:
// techOrder: ['html5', 'flash'],
// html5: {
// hls: {
// withCredentials: false,
// }
// },
// sources: [
// {
// src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
// type: 'application/x-mpegURL',
// }
// ],
fluid: true, // 响应式自适应容器
poster: 'https://www.example.com/poster.png', // 封面图
});
// 事件回调
function onPlay() {
console.log('视频开始播放');
}
function onPause() {
console.log('视频已暂停');
}
function onEnded() {
console.log('视频播放结束');
}
onMounted(() => {
console.log('组件挂载完成,playerOptions=', playerOptions.value);
});
</script>
<style scoped>
.video-demo {
max-width: 800px;
margin: 16px auto;
}
.video-player {
width: 100%;
height: 450px;
}
.vjs-custom-skin .vjs-control-bar {
/* 定制控制栏背景,如半透明黑色 */
background: rgba(0, 0, 0, 0.5) !important;
}
</style>
说明:
playerOptions.sources
必须提供type
与src
。fluid: true
可使播放器自动适应父容器宽度。- 通过
@play
、@pause
、@ended
等原生 Video.js 事件,可监听播放状态。
3.3 常用配置与自定义控件
3.3.1 自定义控制栏组件
如果想在控制栏中添加自定义按钮,比如“截图”、“播放速度切换”等,需要使用 Video.js 的插件机制。以“截图”按钮为例:
<template>
<div class="video-demo">
<h2>自定义截图按钮示例</h2>
<video-player
ref="videoPlayer"
class="video-player vjs-custom-skin"
:options="playerOptions"
@ready="onPlayerReady"
></video-player>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { VideoPlayer } from 'vue-video-player';
import videojs from 'video.js';
// 引入样式
import 'video.js/dist/video-js.css';
import 'vue-video-player/dist/vue-video-player.css';
const videoPlayer = ref(null);
const playerOptions = {
controls: true,
sources: [
{
type: 'video/mp4',
src: 'https://www.w3schools.com/html/mov_bbb.mp4'
}
],
fluid: true,
poster: 'https://www.example.com/poster.png'
};
// 自定义按钮:继承 Video.js Button
class ScreenshotButton extends videojs.getComponent('Button') {
constructor(player, options) {
super(player, options);
this.controlText('截图');
}
handleClick() {
const player = this.player();
const track = player.videoWidth() && player.videoHeight()
? player.currentTime()
: 0;
// 创建 Canvas 截图
const videoEl = player.el().getElementsByTagName('video')[0];
const canvas = document.createElement('canvas');
canvas.width = videoEl.videoWidth;
canvas.height = videoEl.videoHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(videoEl, 0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL('image/png');
// 下载或展示
const link = document.createElement('a');
link.href = dataURL;
link.download = `screenshot_${Date.now()}.png`;
link.click();
}
}
// 注册组件
videojs.registerComponent('ScreenshotButton', ScreenshotButton);
function onPlayerReady({ player }) {
// 将自定义按钮插入到控制栏
player.getChild('controlBar').addChild('ScreenshotButton', {}, 0);
}
</script>
<style scoped>
.video-player {
width: 100%;
height: 450px;
}
.vjs-custom-skin .vjs-control-bar {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>
要点解读:
videojs.getComponent('Button')
拿到基类后自定义一个按钮类,重写handleClick
。- 在
onPlayerReady
中,调用player.getChild('controlBar').addChild('ScreenshotButton', {}, index)
把按钮插入控制栏。- 自定义按钮可自行添加 icon、tooltip 等。
3.3.2 切换清晰度(VTT/ID3/HLS 方式)
如果要在播放器中添加清晰度切换(如 480P/720P/1080P),可以在 playerOptions
中利用 Video.js 的 sources
数组,或借助 videojs-http-source-selector
插件。以下示例展示最简单的做法——手动销毁后重建播放器切换源:
<template>
<div class="video-demo">
<h2>手动切换清晰度示例</h2>
<div class="btn-group">
<button @click="changeSource('480p')">480P</button>
<button @click="changeSource('720p')">720P</button>
<button @click="changeSource('1080p')">1080P</button>
</div>
<video-player
ref="videoPlayer"
class="video-player"
:options="playerOptions"
@ready="onPlayerReady"
></video-player>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { VideoPlayer } from 'vue-video-player';
import videojs from 'video.js';
const videoPlayer = ref(null);
const sourcesMap = {
'480p': 'https://example.com/video_480p.mp4',
'720p': 'https://example.com/video_720p.mp4',
'1080p': 'https://example.com/video_1080p.mp4'
};
const playerOptions = ref({
controls: true,
sources: [
{ type: 'video/mp4', src: sourcesMap['480p'] }
],
fluid: true
});
let playerInstance = null;
function onPlayerReady({ player }) {
playerInstance = player;
}
// 切换清晰度
function changeSource(level) {
if (!playerInstance) return;
// 暂存当前播放时间
const currentTime = playerInstance.currentTime();
// 更新源
playerInstance.src({ type: 'video/mp4', src: sourcesMap[level] });
// 重新加载并跳转到之前时间
playerInstance.load();
playerInstance.ready(() => {
playerInstance.currentTime(currentTime);
playerInstance.play();
});
}
</script>
<style scoped>
.btn-group {
margin-bottom: 8px;
}
.btn-group button {
margin-right: 8px;
padding: 6px 12px;
background: #409eff;
border: none;
color: white;
border-radius: 4px;
cursor: pointer;
}
.btn-group button:hover {
background: #66b1ff;
}
.video-player {
width: 100%;
height: 450px;
}
</style>
说明:
- 通过 Video.js 原生的
player.src()
方法可动态切换视频源。- 切换后调用
load()
、ready()
回调确保跳转与播放。
3.4 事件监听与 API 调用
vue-video-player
把 Video.js 常用事件都封装为组件事件。常见事件包括:
事件名 | 说明 | 回调参数 |
---|---|---|
ready | 播放器初始化完成 | { player } |
play | 视频开始播放 | event |
pause | 视频暂停 | event |
ended | 视频播放结束 | event |
error | 播放出错 | event |
timeupdate | 播放进度更新(每隔一定时间触发) | event |
volumechange | 音量变化 | event |
fullscreenchange | 全屏/退出全屏 | event |
在 ready
回调里,你可以拿到 player
实例,进而调用视频的原生方法,例如:
function onPlayerReady({ player }) {
// 暂停
player.pause();
// 获取当前时间
const t = player.currentTime();
console.log('当前播放时间:', t);
// 跳转到某个时间点
player.currentTime(30);
// 全屏
player.requestFullscreen();
// 设置音量
player.volume(0.5);
}
3.5 组件结构图解
VideoDemo.vue
┌─────────────────────────────────────────────────────────────┐
│ <video-player> │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ <div class="video-js vjs-default-skin"> │ │
│ │ <video class="vjs-tech" src="..." preload="auto"></video> │ │
│ │ <div class="vjs-control-bar"> │ │
│ │ <!-- 播放/暂停 按钮 --> │ │
│ │ <!-- 音量、进度条、全屏等控件 --> │ │
│ │ </div> │ │
│ │ <!-- 其他 Video.js 插件容器(例如 弹幕、字幕面板) --> │ │
│ │ </div> │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
事件流示意:
用户点击“播放” →组件触发 @play → Vue 组件逻辑接收 → 或者拿到 player 实例手动调用 play()
<video-player>
本质上是一个包装 Video.js 初始化与销毁的 Vue 组件,内部渲染一个带有vjs-*
类名的容器。- 你只需通过 props 传入
options
,以及监听 Vue 事件即可;若要访问更底层的 Video.js API,可在@ready
拿到player
。
DPlayer 实战
DPlayer 是国内社区非常流行的 HTML5 弹幕播放器,支持弹幕、字幕、画中画、画质切换等丰富功能。DPlayer 核心是原生 JS,而社区有专门的 Vue 封装插件,也可直接用 ref
挂载到 DOM 上。
4.1 安装与引入
步骤 1:安装依赖
npm install dplayer --save
# 如果需要字幕及插件支持,可额外安装:
# npm install flv.js flv.js/dist/flv.min.js --save
若想使用 Vue 封装组件(如 vue-dplayer
),也可:
npm install vue-dplayer --save
但本文以原生 DPlayer + Vue 组合为主,方便你精准控制初始化与销毁。
步骤 2:在组件中引入
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import DPlayer from 'dplayer';
import 'dplayer/dist/DPlayer.min.css';
</script>
<template>
<div class="dplayer-demo">
<h2>DPlayer 基础示例</h2>
<!-- 容器 -->
<div ref="dpContainer" class="dplayer-container"></div>
</div>
</template>
说明:
dplayer
安装后会生成DPlayer.min.css
以及.js
文件,我们需在组件里引入 CSS。ref="dpContainer"
用于挂载播放器实例。
4.2 基础使用示例
<template>
<div class="dplayer-demo">
<h2>DPlayer 基础示例</h2>
<div ref="dpContainer" class="dplayer-container"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import DPlayer from 'dplayer';
import 'dplayer/dist/DPlayer.min.css';
let dp = null;
const dpContainer = ref(null);
onMounted(() => {
// 初始化 DPlayer
dp = new DPlayer({
container: dpContainer.value, // 挂载容器
autoplay: false,
theme: '#FADFA3', // 主题色
loop: false,
lang: 'zh-cn',
preload: 'auto',
volume: 0.7,
video: {
url: 'https://www.w3schools.com/html/mov_bbb.mp4',
pic: 'https://www.example.com/poster.png',
thumbnails: 'https://www.example.com/thumbs.jpg',
type: 'auto'
}
});
// 监听事件
dp.on('play', () => {
console.log('DPlayer:播放');
});
dp.on('pause', () => {
console.log('DPlayer:暂停');
});
dp.on('ended', () => {
console.log('DPlayer:播放结束');
});
});
onBeforeUnmount(() => {
if (dp) {
dp.destroy(); // 组件卸载时销毁实例,释放资源
}
});
</script>
<style scoped>
.dplayer-container {
width: 100%;
max-width: 800px;
height: 450px;
margin: 16px auto;
}
</style>
核心要点:
new DPlayer({ … })
需传入container
(DOM 元素)。video
配置中,url
是视频地址,pic
是封面图,thumbnails
是进度条预览图。- 通过
dp.on('event', callback)
监听play
、pause
、ended
等事件。- 一定要在组件销毁前调用
dp.destroy()
,否则可能造成内存泄漏。
4.3 弹幕、字幕与画中画功能
4.3.1 弹幕(Danmaku)
DPlayer 的最大特色之一就是“弹幕”功能,对视频播放添加实时评论效果。使用非常简单:
<template>
<div class="dplayer-demo">
<h2>DPlayer 弹幕示例</h2>
<div ref="dpContainer" class="dplayer-container"></div>
<div class="danmaku-input">
<input v-model="danmuText" placeholder="请输入弹幕内容" />
<button @click="sendDanmaku">发送弹幕</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import DPlayer from 'dplayer';
import 'dplayer/dist/DPlayer.min.css';
let dp = null;
const dpContainer = ref(null);
// 弹幕输入
const danmuText = ref('');
onMounted(() => {
dp = new DPlayer({
container: dpContainer.value,
video: {
url: 'https://www.w3schools.com/html/mov_bbb.mp4',
pic: 'https://www.example.com/poster.png',
},
danmaku: {
id: 'demo', // 弹幕载体唯一 id,可用于后端区分视频
api: 'https://api.prprpr.me/dplayer/', // 公开的 DPlayer 弹幕API示例
maximum: 1000,
user: '游客', // 自定义弹幕用户名
bottom: '15px', // 弹幕距离底部距离
unlimited: false
}
});
});
// 发送弹幕
function sendDanmaku() {
if (!danmuText.value.trim()) return;
dp.sendDanmaku({
text: danmuText.value,
color: '#ffffff',
type: 'right', // 弹幕类型: 'right' | 'top' | 'bottom'
});
danmuText.value = '';
}
onBeforeUnmount(() => {
if (dp) dp.destroy();
});
</script>
<style scoped>
.dplayer-container {
width: 100%;
max-width: 800px;
height: 450px;
margin: 16px auto;
}
.danmaku-input {
display: flex;
justify-content: center;
margin-top: 8px;
}
.danmaku-input input {
width: 60%;
padding: 6px 8px;
border: 1px solid #ccc;
border-radius: 4px 0 0 4px;
outline: none;
}
.danmaku-input button {
padding: 6px 12px;
background: #e6a23c;
border: none;
color: white;
border-radius: 0 4px 4px 0;
cursor: pointer;
}
.danmaku-input button:hover {
background: #f0ad4e;
}
</style>
说明:
danmaku
配置中,api
指向弹幕接口(可以自行搭建后端或使用公开 API)。dp.sendDanmaku({ text, color, type })
会将弹幕发送到后端并在本地展示。
4.3.2 字幕(Subtitles)
如果要为视频添加字幕,需在初始化时指定 subtitle
:
dp = new DPlayer({
container: dpContainer.value,
video: { url: 'https://www.example.com/video.mp4', pic: '...' },
subtitle: {
url: 'https://www.example.com/subtitle.srt', // 字幕文件地址,可为 .srt 或 .vtt
type: 'srt', // 字幕类型 'webvtt' | 'srt'
fontSize: '25px',
bottom: '10%',
color: '#ff0000'
}
});
subtitle.url
:字幕文件地址,浏览器能直接加载。type
:字幕类型,.srt
或者.vtt
。fontSize
、bottom
、color
等可定制字幕样式。
4.3.3 画中画(Picture-in-Picture)
若需要在支持画中画的浏览器/环境下启用该功能,只需在初始化时设置:
dp = new DPlayer({
container: dpContainer.value,
video: { url: '...', pic: '...' },
pip: true, // 启用画中画
});
在支持的环境(如 Safari、Chrome 70+)下,右下角会出现“画中画”按钮,点击后视频会悬浮在页面上。
4.4 主题、自定义按钮与插件扩展
与 vue-video-player 类似,DPlayer 也支持自定义皮肤、按钮、插件。以“自定义回放速度”按钮为例:
<template>
<div class="dplayer-demo">
<h2>DPlayer 自定义功能示例</h2>
<div ref="dpContainer" class="dplayer-container"></div>
<div class="speed-controls">
<button @click="setSpeed(0.5)">0.5x</button>
<button @click="setSpeed(1)">1x</button>
<button @click="setSpeed(1.5)">1.5x</button>
<button @click="setSpeed(2)">2x</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import DPlayer from 'dplayer';
import 'dplayer/dist/DPlayer.min.css';
let dp = null;
const dpContainer = ref(null);
onMounted(() => {
dp = new DPlayer({
container: dpContainer.value,
video: {
url: 'https://www.w3schools.com/html/mov_bbb.mp4',
pic: 'https://www.example.com/poster.png',
},
playbackSpeed: [0.5, 1, 1.5, 2], // 指定支持的倍速数组
menu: [
{
text: '自定义菜单',
link: 'https://dplayer.js.org/'
}
]
});
});
function setSpeed(rate) {
if (dp) {
dp.speed(rate);
console.log(`已切换到 ${rate} 倍速`);
}
}
onBeforeUnmount(() => {
if (dp) dp.destroy();
});
</script>
<style scoped>
.dplayer-container {
width: 100%;
max-width: 800px;
height: 450px;
margin: 16px auto;
}
.speed-controls {
display: flex;
justify-content: center;
margin-top: 8px;
}
.speed-controls button {
margin: 0 6px;
padding: 6px 12px;
background: #67c23a;
border: none;
color: white;
border-radius: 4px;
cursor: pointer;
}
.speed-controls button:hover {
background: #85ce61;
}
</style>
要点:
- 通过
playbackSpeed
数组设置可选倍速值。dp.speed(rate)
即可实时切换。menu
字段可添加右上角的自定义菜单链接。
4.5 技术架构图解
DPlayer.vue
┌──────────────────────────────────────────────────┐
│ new DPlayer({ │
│ container: dpContainer, │
│ video: { url, pic, type }, │
│ danmaku: { api, id, }, │
│ subtitle: { url, type, fontSize, ... }, │
│ pip: true, │
│ playbackSpeed: [...], │
│ menu: [...] │
│ }) │
│ ┌──────────────────────────────────────────────┐ │
│ │ <div class="dplayer-con"> │ │
│ │ <video class="dplayer-video" src="..." /> │ │
│ │ <!-- Control Bar --> │ │
│ │ <div class="dplayer-control-bar"> │ │
│ │ <!-- 播放/暂停/音量/进度/全屏/弹幕等控件 --> │ │
│ │ </div> │ │
│ │ <!-- 弹幕层 --> │ │
│ │ <canvas class="dplayer-danmaku-layer" /> │ │
│ │ <!-- 字幕层 --> │ │
│ │ <div class="dplayer-subtitle"></div> │ │
│ │ </div> │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
事件流示意:
视频缓冲完成 → DPlayer 自动监听 → 用户可发送弹幕 → dp.sendDanmaku({...})
- 整体架构可分为:视频层(
<video>
)、控制栏(各种按钮)、弹幕层(Canvas 渲染)、字幕层(DOM 元素)。 - DPlayer 内部对 HLS、FLV、Dash 等格式提供了自动识别(
type: 'auto'
),并加载对应 JS 库(需要额外安装)。
对比与选型建议
特性 | vue-video-player (Video.js) | DPlayer |
---|---|---|
体积 | 较大(Video.js 核心 \~200KB+) | 较小(核心 \~100KB+) |
弹幕支持 | 需额外插件,如 videojs-contrib-danmaku | 原生支持,无需额外依赖 |
字幕支持 | Video.js 原生支持 .vtt/.srt | 原生支持 .vtt/.srt |
画质切换 | 需手动切换 player.src() 或插件 | 支持 playlist 功能自动切换 |
插件生态 | 丰富(广告、分析、VR、直播等) | 生态逐步完善,社区插件较多(截图、音效等) |
移动端兼容性 | 良好 | 极佳 |
API 丰富程度 | 完备 | 完备 |
UI 美观度 | 扩展性强,可自定义皮肤 | 开箱即用,默认皮肤较现代 |
二次开发难度 | 中等(需了解 Video.js plugin 机制) | 低(API 直观、文档清晰) |
Vue 封装组件 | 有 vue-video-player 便于集成 | 可用 vue-dplayer 或手动封装 |
- 如果项目需求偏向“基础播放器+广告、分析”或需兼容更多视频格式、插件,请优先考虑 vue-video-player (Video.js);
- 若需快速搭建带弹幕、画中画、倍速切换、主题效果的现代播放器,且更看重“简洁 UI + 易用 API”,则 DPlayer 是更佳选择。
常见问题与优化
页面首次加载白屏/播放器闪烁
- 原因:若在父容器宽高未确定前就渲染播放器,可能出现闪烁。
- 解决:用 CSS 预留容器宽高,或在
v-if="showPlayer"
延迟渲染。
HLS/FLV 视频无法播放
- 原因:浏览器未原生支持 HLS/FLV,需引入对应 JS 库。
解决:
- 对于 vue-video-player,可安装并引入
videojs-flash
/videojs-contrib-hls
等插件; - 对于 DPlayer,可额外安装
flv.js
、mpegts.js
,并在初始化时指定type: 'flv'
。
- 对于 vue-video-player,可安装并引入
弹幕无法显示
- 原因一:
danmaku.api
配置错误,无法请求弹幕数据; - 原因二:跨域请求被阻止,需后端或 CDN 配置 CORS;
- 解决:确认 API 地址可访问、返回数据格式符合 DPlayer 要求,或使用本地模拟。
- 原因一:
截图按钮样式错位
- 原因:自定义按钮未指定图标,尺寸和位置需手动调整。
- 解决:通过 CSS 设置
.vjs-screenshot-button .vjs-icon-placeholder:before { content: '📸'; }
或替换 SVG 图标。
嵌入到 Modal/Drawer 等动态容器中失真
- 原因:CSS 隐藏时播放器无法正确计算宽高。
解决:在容器弹出后触发重绘:
setTimeout(() => { playerInstance && playerInstance.trigger('resize'); }, 300);
- 或使用
player.fluid(true)
重新适配。
手机端长按进度条弹出菜单(复制/粘贴/另存为)
- 原因:浏览器默认行为影响交互。
- 解决:为
<video>
添加controlsList="nodownload noremoteplayback"
,或绑定oncontextmenu="event.preventDefault()"
禁用右键菜单。
总结
本文从基础安装到高级定制,详细介绍了 Vue 应用中集成 vue-video-player(Video.js 封装) 与 DPlayer 两种主流方案:
- vue-video-player:基于 Video.js,功能齐全,插件生态丰富,适合需要广告、分析、直播、VR 等复杂需求的项目;
- DPlayer:轻量级、弹幕体验出色,UI 现代、API 简洁,适合需要弹幕、字幕、画中画等极致体验的项目。
通过丰富的代码示例与图解,你可以掌握:
- 如何在 Vue 中正确引入与注册播放器
- 如何根据项目需求进行基础配置与样式定制
- 如何使用 API 实现“清晰度切换”、“截图”、“弹幕”、以及“画中画”等高级功能
- 如何在组件生命周期中初始化、销毁播放器,避免资源泄漏
评论已关闭