
Research
/Security News
jscrambler npm Package Compromised in Supply Chain Attack
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.
vue-video-plus
Advanced tools
bagn # 🎬vuevideoplus
一个基于 Vue 3 开发的功能丰富、高度可定制的现代化视频播放器组件
有任何疑问可以给我发邮件或者加 QQ
📧 邮箱: 250219234@qq.com
💬 QQ: 250219234
npm install vue-video-plus
pnpm add vue-video-plus
yarn add vue-video-plus
import { createApp } from 'vue'
import App from './App.vue'
// 引入组件和样式
import VueVideoPlus from 'vue-video-plus'
import 'vue-video-plus/dist/style.css'
const app = createApp(App)
app.use(VueVideoPlus)
app.mount('#app')
<template>
<VueVideoPlus
@play="handlePlay"
@pause="handlePause"
/>
</template>
<script setup>
import { reactive } from 'vue'
import { VueVideoPlus } from 'vue-video-plus'
import 'vue-video-plus/dist/style.css'
const options = reactive({
width: '1080px',
height: '608px',
// 在线视频
src: 'https://example.com/video.mp4',
// 或使用本地视频(需放在 public 文件夹)
// src: '/videos/demo.mp4',
autoPlay: false,
muted: false,
volume: 0.5,
})
const handlePlay = (event) => {
console.log('视频开始播放', event)
}
const handlePause = (event) => {
console.log('视频暂停', event)
}
</script>
💡 提示:将视频文件放在项目根目录的
public/videos/文件夹中,然后使用/videos/your-video.mp4路径引用。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
src | 视频源地址 | String | 演示视频 URL |
width | 播放器宽度(桌面端) | String | '1080px' |
height | 播放器高度(桌面端) | String | '608px' |
title | 视频标题 | String | '' |
type | 视频类型 | String | 'video/mp4' |
poster | 视频封面图 | String | '' |
autoPlay | 自动播放 | Boolean | true |
muted | 静音 | Boolean | true |
volume | 默认音量(0-1) | Number | 0.3 |
loop | 循环播放 | Boolean | false |
currentTime | 初始播放时间(秒) | Number | 0 |
control | 是否显示控制器 | Boolean | true |
preload | 预加载策略 | String | 'auto' |
默认值:http://www.jplayer.org/video/m4v/Incredibles_Teaser.m4v(演示视频)
播放器支持多种视频源格式,你可以根据需要选择:
1️⃣ 使用在线视频(推荐用于生产环境)
<VueVideoPlus src="https://example.com/video.mp4" />
2️⃣ 使用本地视频文件
在项目根目录创建 public 文件夹(如果还没有),将视频文件放入:
your-project/
├── public/
│ └── videos/
│ └── demo.mp4
├── src/
└── package.json
然后使用相对路径引用:
<VueVideoPlus src="/videos/demo.mp4" />
3️⃣ 导入本地视频(适用于较小的视频)
<script setup>
import { VueVideoPlus } from 'vue-video-plus'
import myVideo from '@/assets/video.mp4'
</script>
<template>
<VueVideoPlus :src="myVideo" />
</template>
4️⃣ 使用默认演示视频(快速测试)
<!-- 不指定 src,使用内置演示视频 -->
<VueVideoPlus />
⚠️ 注意事项:
public 文件夹存放视频,避免打包体积过大| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
colorStart | 主题起始颜色 | String | '#52a0fd' |
colorEnd | 主题结束颜色(空字符串为纯色,否则渐变) | String | '#00e2fa' |
borderRadius | 播放器圆角 | String | '8px' |
主题示例:
// 纯色主题
{ colorStart: '#52a0fd', colorEnd: '' }
// 渐变主题
{ colorStart: '#52a0fd', colorEnd: '#00e2fa' }
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
speed | 是否支持快进快退 | Boolean | true |
speedRate | 倍速选项 | Array | ['2.0', '1.5', '1.25', '1.0', '0.75', '0.5'] |
qualities | 清晰度选项列表 | Array<QualityOption> | [] |
mirror | 镜像画面 | Boolean | false |
lightOff | 关灯模式 | Boolean | false |
webFullScreen | 网页全屏 | Boolean | false |
playsinline | iOS 内联播放(不全屏) | Boolean | false |
类型定义:
interface QualityOption {
label: string // 显示标签,如 "1080P"
value: string // 清晰度标识,如 "1080p"
url: string // 对应的视频源地址
default?: boolean // 是否为默认清晰度
}
使用示例:
<VueVideoPlus
src="/video-1080p.mp4"
:qualities="[
{
label: '超清 1080P',
value: '1080p',
url: '/video-1080p.mp4',
default: true
},
{
label: '高清 720P',
value: '720p',
url: '/video-720p.mp4'
},
{
label: '标清 480P',
value: '480p',
url: '/video-480p.mp4'
}
]"
/>
注意事项:
[] 表示不启用清晰度切换功能storage.fields.quality)📖 详细文档: 清晰度切换配置指南
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
playBtnPosition | 中央播放按钮位置 | String | 'center' |
playBtnAnimation | 播放按钮切换动画 | String | 'scale' |
controlBtns | 显示的控制按钮 | Array | 见下方说明 |
playBtnPosition 可选值:
'center' - 居中'bottom-right' - 右下角'bottom-left' - 左下角playBtnAnimation 可选值:
'rotate' - 旋转'scale' - 缩放'flip' - 翻转'slide' - 滑动'none' - 无动画controlBtns 默认值:
[
'audioTrack', // 音轨(预留)
'quality', // 清晰度(预留)
'speedRate', // 倍速
'volume', // 音量
'setting', // 设置
'pip', // 画中画
'pageFullScreen', // 网页全屏
'fullScreen' // 全屏
]
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
playRetryTimeout | 播放重试超时时间(毫秒) | Number | 500 |
播放器支持自动保存用户设置到本地存储(localStorage),刷新页面后自动恢复。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
storage | 持久化配置对象 | Object | 见下方说明 |
videoId | 视频唯一标识(用于区分不同视频的播放位置) | String | '' |
storage 配置项:
storage: {
enabled: true, // 是否启用持久化
prefix: 'vue-video-player', // localStorage key 前缀
// 要持久化的字段
fields: {
volume: true, // ✅ 音量(强烈推荐)
playbackRate: true, // ✅ 播放速度(强烈推荐)
muted: true, // ✅ 静音状态(推荐)
quality: true, // ✅ 清晰度偏好(推荐)
currentTime: false // ⚖️ 播放位置(默认关闭,可按需开启)
},
// 播放位置保存配置(仅当 fields.currentTime=true 时生效)
currentTimeConfig: {
enabled: false, // 是否启用播放位置保存
minDuration: 300, // 最小保存时长(秒),视频<5分钟不保存
minProgress: 0.05, // 最小保存进度(5%),避免保存刚开始的视频
maxProgress: 0.95 // 最大保存进度(95%),避免保存已完成的视频
},
// 过期时间配置
expiration: {
global: 0, // 全局设置过期时间(毫秒),0=永不过期
currentTime: 30 * 24 * 60 * 60 * 1000 // 播放位置过期时间(30天)
}
}
使用示例:
<template>
<VueVideoPlus
src="/video.mp4"
videoId="my-video-001"
:storage="{
enabled: true,
prefix: 'my-app-video',
fields: {
volume: true,
playbackRate: true,
currentTime: true // 启用断点续播
},
currentTimeConfig: {
enabled: true,
minDuration: 300
}
}"
/>
</template>
💡 使用场景:
fields.currentTime: truestorage: { enabled: false }📖 详细文档:
持久化功能配置较为复杂,详细说明请查看:状态持久化配置指南
组件支持所有原生 HTML5 视频事件:
| 事件名 | 说明 | 回调参数 |
|---|---|---|
loadstart | 开始加载视频 | Event |
play | 开始播放 | Event |
pause | 暂停播放 | Event |
playing | 播放中 | Event |
seeking | 开始跳转 | Event |
seeked | 跳转完成 | Event |
canplay | 可以播放 | Event |
waiting | 缓冲中 | Event |
durationchange | 时长变化 | Event |
progress | 下载进度 | Event |
timeupdate | 播放进度更新 | Event |
ended | 播放结束 | Event |
error | 播放错误 | Event |
stalled | 数据获取失败 | Event |
| 事件名 | 说明 | 回调参数 |
|---|---|---|
mirrorChange | 镜像状态改变 | (isMirror: Boolean, video: HTMLVideoElement) |
loopChange | 循环状态改变 | (isLoop: Boolean, video: HTMLVideoElement) |
lightOffChange | 关灯模式改变 | (isLightOff: Boolean, video: HTMLVideoElement) |
使用示例:
<template>
<VueVideoPlus
v-bind="options"
@play="handlePlay"
@pause="handlePause"
@timeupdate="handleTimeUpdate"
@ended="handleEnded"
@mirrorChange="handleMirrorChange"
@loopChange="handleLoopChange"
/>
</template>
<script setup>
const handlePlay = (event) => {
console.log('播放开始', event)
}
const handlePause = (event) => {
console.log('播放暂停', event)
}
const handleTimeUpdate = (event) => {
const currentTime = event.target.currentTime
console.log('当前播放时间:', currentTime)
}
const handleEnded = (event) => {
console.log('播放结束', event)
}
const handleMirrorChange = (isMirror, video) => {
console.log('镜像模式:', isMirror, video)
}
const handleLoopChange = (isLoop, video) => {
console.log('循环播放:', isLoop, video)
}
</script>
通过 ref 可以调用播放器实例的方法:
| 方法名 | 说明 | 参数 |
|---|---|---|
play() | 播放视频 | - |
pause() | 暂停视频 | - |
togglePlay() | 切换播放/暂停 | - |
使用示例:
<template>
<VueVideoPlus ref="videoRef" v-bind="options" />
<button @click="handlePlay">播放</button>
<button @click="handlePause">暂停</button>
<button @click="handleToggle">切换</button>
</template>
<script setup>
import { ref } from 'vue'
const videoRef = ref(null)
const handlePlay = () => {
videoRef.value?.play()
}
const handlePause = () => {
videoRef.value?.pause()
}
const handleToggle = () => {
videoRef.value?.togglePlay()
}
</script>
播放器支持以下键盘快捷键(仅桌面端):
| 快捷键 | 功能 |
|---|---|
空格 | 播放/暂停 |
← | 快退 10 秒 |
→ | 快进 10 秒 |
→ 长按 | 5 倍速播放 |
↑ | 增加音量 |
↓ | 减少音量 |
F | 全屏/退出全屏 |
ESC | 退出网页全屏 |
<template>
<div class="video-container">
<VueVideoPlus
ref="videoPlayer"
v-bind="options"
@play="onPlay"
@pause="onPause"
@timeupdate="onTimeUpdate"
@ended="onEnded"
@mirrorChange="onMirrorChange"
@loopChange="onLoopChange"
@lightOffChange="onLightOffChange"
/>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { VueVideoPlus } from 'vue-video-plus'
import 'vue-video-plus/dist/style.css'
const videoPlayer = ref()
const options = reactive({
// 基础配置
width: '1080px',
height: '608px',
src: 'https://example.com/video.mp4',
title: '精彩视频',
type: 'video/mp4',
poster: 'https://example.com/poster.jpg',
// 主题配置
colorStart: '#52a0fd',
colorEnd: '#00e2fa',
borderRadius: '8px',
// 播放配置
autoPlay: true,
muted: false,
volume: 0.5,
loop: false,
currentTime: 0,
// 功能配置
speed: true,
speedRate: ['2.0', '1.5', '1.25', '1.0', '0.75', '0.5'],
mirror: false,
lightOff: false,
webFullScreen: false,
// UI 配置
playBtnPosition: 'center',
playBtnAnimation: 'scale',
control: true,
controlBtns: [
'speedRate',
'volume',
'setting',
'pip',
'pageFullScreen',
'fullScreen'
],
// 持久化配置
storage: {
enabled: true,
prefix: 'my-video-app',
fields: {
volume: true,
playbackRate: true,
muted: true,
currentTime: false
}
},
// 高级配置
playRetryTimeout: 500
})
// 事件处理
const onPlay = (event: Event) => {
console.log('视频开始播放', event)
}
const onPause = (event: Event) => {
console.log('视频暂停', event)
}
const onTimeUpdate = (event: Event) => {
const video = event.target as HTMLVideoElement
console.log('播放进度:', video.currentTime, '/', video.duration)
}
const onEnded = (event: Event) => {
console.log('视频播放结束', event)
}
const onMirrorChange = (isMirror: boolean, video: HTMLVideoElement) => {
console.log('镜像模式:', isMirror)
}
const onLoopChange = (isLoop: boolean, video: HTMLVideoElement) => {
console.log('循环播放:', isLoop)
}
const onLightOffChange = (isLightOff: boolean, video: HTMLVideoElement) => {
console.log('关灯模式:', isLightOff)
}
// 控制方法
const playVideo = () => {
videoPlayer.value?.play()
}
const pauseVideo = () => {
videoPlayer.value?.pause()
}
const togglePlayVideo = () => {
videoPlayer.value?.togglePlay()
}
</script>
<style scoped>
.video-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 移动端适配 */
@media (max-width: 768px) {
.video-container {
padding: 10px;
}
}
</style>
// 经典蓝
{ colorStart: '#52a0fd', colorEnd: '' }
// 玫瑰红
{ colorStart: '#eb3b5a', colorEnd: '' }
// 薄荷绿
{ colorStart: '#00b894', colorEnd: '' }
// 科技蓝(默认)
{ colorStart: '#52a0fd', colorEnd: '#00e2fa' }
// 日落橙
{ colorStart: '#ff6b6b', colorEnd: '#ffa500' }
// 炫彩紫
{ colorStart: '#667eea', colorEnd: '#764ba2' }
// 海洋蓝
{ colorStart: '#4b7bec', colorEnd: '#3867d6' }
播放器自动检测设备类型并适配:
width 和 height100% 宽度,高度按 16:9 比例计算浏览器的自动播放策略要求首次自动播放必须静音。播放器已内置处理:
autoPlay: false 让用户手动播放这个问题已在 v1.2.4 版本修复,确保使用最新版本。
播放器支持浏览器原生支持的 HLS 格式(Safari),其他浏览器需要使用 hls.js:
import Hls from 'hls.js'
if (Hls.isSupported()) {
const hls = new Hls()
hls.loadSource('https://example.com/video.m3u8')
hls.attachMedia(videoElement)
}
使用深度选择器覆盖样式:
:deep(.player-wrap) {
/* 自定义样式 */
}
:deep(.control-tool) {
background: rgba(0, 0, 0, 0.8);
}
设置 storage.fields.currentTime: true 并配置 currentTimeConfig:
<VueVideoPlus
src="/movie.mp4"
videoId="movie-001"
:storage="{
fields: {
currentTime: true
},
currentTimeConfig: {
enabled: true,
minDuration: 300, // 只保存5分钟以上的视频
minProgress: 0.05, // 进度>5%才保存
maxProgress: 0.95 // 进度<95%才保存
}
}"
/>
注意:记得设置 videoId 来区分不同视频的播放位置。
确保持久化功能已启用(默认启用):
storage: {
enabled: true, // 确保为 true
fields: {
volume: true, // 保存音量
playbackRate: true // 保存倍速
}
}
如果仍然不生效,检查浏览器是否禁用了 localStorage。
打开浏览器开发者工具(F12):
vue-video-player-settings 键(或你自定义的 prefix)或在代码中清除:
localStorage.removeItem('vue-video-player-settings')
MIT License
鱿鱼溪学院
欢迎提交 Issue 和 Pull Request!
FAQs
一个基于 Vue 3 开发的功能丰富、高度可定制的现代化视频播放器组件
We found that vue-video-plus demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.

Research
/Security News
A malicious .NET package is typosquatting the Braintree SDK to steal live payment card data, merchant API keys, and host secrets from production apps.

Security News
/Research
Compromised Injective SDK npm version 1.20.21 exfiltrates wallet private keys and mnemonics through fake telemetry functionality.