更新记录
1.0.0(2025-11-10) 下载此版本
✅ 多格式支持:自动识别并播放 M3U8、FLV、MP4、WEBM、OGG 等多种视频格式
✅ 直播/点播:支持直播流和点播视频,通过 isLive 参数区分
✅ 跨平台兼容:H5、APP、微信小程序全平台支持
✅ 智能降级:根据浏览器能力自动选择播放方案
✅ iOS 优化:针对 iOS 环境特殊处理,避免不兼容问题
✅ 错误提示:友好的错误提示界面,提升用户体验
✅ 画中画支持:小程序直播场景支持画中画功能
平台兼容性
uni-app(4.21)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | √ | √ | √ | - | 5.0 | 12 | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - |
VideoPlayer 视频播放器组件使用文档
📋 目录
组件概述
video-player.vue 是一个跨平台的视频播放器组件,支持 H5、APP 和小程序端,能够智能识别视频格式并选择最优播放方式。
能干什么?
✅ 多格式支持:自动识别并播放 M3U8、FLV、MP4、WEBM、OGG 等多种视频格式
✅ 直播/点播:支持直播流和点播视频,通过 isLive 参数区分
✅ 跨平台兼容:H5、APP、微信小程序全平台支持
✅ 智能降级:根据浏览器能力自动选择播放方案
✅ iOS 优化:针对 iOS 环境特殊处理,避免不兼容问题
✅ 错误提示:友好的错误提示界面,提升用户体验
✅ 画中画支持:小程序直播场景支持画中画功能
⚠️ 重要提示:使用组件时必须正确设置
isLive参数!
- 直播场景:
isLive=true(小程序使用 live-player)- 点播场景:
isLive=false(小程序使用 video)错误的
isLive设置会导致小程序端播放失败或功能异常!
核心功能
1. 智能格式识别
组件会根据视频 URL 自动识别格式:
| 格式 | 识别规则 | 播放方式 |
|---|---|---|
| M3U8/HLS | URL 包含 .m3u8 或 m3u8 |
hls.js (H5/APP) / 原生支持 (iOS) |
| FLV | URL 包含 .flv 或 flv |
flv.js (非 iOS) / 不支持 (iOS) |
| RTMP | URL 以 rtmp:// 开头 |
不支持 (提示错误) |
| MP4 | URL 包含 .mp4 |
原生 video 标签 |
| WEBM | URL 包含 .webm |
原生 video 标签 |
| OGG | URL 包含 .ogg |
原生 video 标签 |
2. 平台适配
H5 端
- 使用 DOM 创建
<video>元素 - 动态加载 hls.js 和 flv.js 库
- 支持所有现代浏览器
APP 端
- 使用 renderjs 在渲染层操作 DOM
- 性能更优,避免逻辑层与渲染层通信开销
- 支持 iOS 和 Android
小程序端
- 使用微信原生
<live-player>组件 - 仅支持直播流播放
3. iOS 特殊处理
为什么 iOS 不支持 FLV?
FLV (Flash Video) 格式依赖 Adobe Flash 技术,而:
- iOS 从未支持 Flash:苹果设备从未内置 Flash Player
- flv.js 依赖 MSE:虽然 flv.js 可以通过 Media Source Extensions (MSE) 播放 FLV,但 iOS Safari 对 MSE 的支持有限且不稳定
- 安全性考虑:iOS 严格限制底层媒体解码能力
为什么 iOS 推荐使用 HLS?
HLS (HTTP Live Streaming) 是苹果公司开发的流媒体协议:
- 原生支持:iOS Safari 原生支持 HLS,无需任何插件
- 性能最优:硬件加速解码,功耗低、流畅度高
- 自适应码率:根据网络状况自动调整清晰度
- 行业标准:被广泛应用于直播和点播场景
建议:如果需要兼容 iOS,请使用 M3U8/HLS 格式的视频源。
Props 参数
| 参数名 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
url |
String | '' |
✅ | 视频播放地址,支持 http/https 协议 |
isLive |
Boolean | false |
❌ | 是否为直播源(影响 FLV 播放器配置) |
muted |
Boolean | false |
❌ | 是否静音 |
autoplay |
Boolean | true |
❌ | 是否自动播放 |
loop |
Boolean | false |
❌ | 是否循环播放(仅点播有效) |
controls |
Boolean | false |
❌ | 是否显示控制条 |
poster |
String | '' |
❌ | 视频封面图 URL |
参数详解
url - 视频地址
// M3U8 直播流
url: 'https://example.com/live/stream.m3u8'
// FLV 直播流(注意:iOS 不支持)
url: 'https://example.com/live/stream.flv'
// MP4 点播视频
url: 'https://example.com/video/demo.mp4'
isLive - 直播标识
// 直播场景
:isLive="true" // 优化 FLV 播放器配置,禁用 seek 等点播功能
// 点播场景
:isLive="false" // 启用完整的播放控制功能
autoplay - 自动播放
:autoplay="true" // 页面加载后自动播放(可能受浏览器策略限制)
:autoplay="false" // 需要用户手动点击播放
⚠️ 注意:大部分浏览器要求用户交互后才能自动播放有声视频,建议配合
muted使用。
Events 事件
组件会向父组件抛出以下事件:
| 事件名 | 参数 | 说明 | 触发时机 |
|---|---|---|---|
error |
{ message, code?, format? } |
播放错误 | 加载失败、格式不支持、播放异常 |
play |
Event |
开始播放 | 视频开始播放 |
pause |
Event |
暂停播放 | 视频暂停 |
ended |
Event |
播放结束 | 视频播放完毕(仅点播) |
timeupdate |
Event |
时间更新 | 播放进度变化 |
loadedmetadata |
Event |
元数据加载完成 | 视频时长、尺寸等信息加载完成 |
waiting |
Event |
等待数据 | 缓冲中 |
canplay |
Event |
可以播放 | 数据加载足够,可以开始播放 |
statechange |
Event |
状态变化 | 小程序端专用 (live-player) |
netstatus |
Event |
网络状态 | 小程序端专用 (live-player) |
fullscreenchange |
Event |
全屏变化 | 进入/退出全屏 |
pictureinpicturechange |
{ type, isEnter, detail } |
画中画变化 | 小程序端进入/退出画中画 |
错误事件详解
iOS 不支持 FLV 错误
{
message: 'iOS系统不支持FLV格式播放',
code: 'FLV_NOT_SUPPORTED_ON_IOS',
format: 'flv'
}
RTMP 不支持错误
{
message: 'RTMP协议不支持',
code: 'RTMP_NOT_SUPPORTED',
format: 'rtmp'
}
FLV 播放错误
{
message: 'FLV播放错误',
errorType: 'NetworkError',
errorDetail: 'HttpStatusCodeInvalid',
errorInfo: { ... }
}
画中画事件详解
进入画中画
{
type: 'enterpictureinpicture',
isEnter: true,
detail: { ... }
}
退出画中画
{
type: 'leavepictureinpicture',
isEnter: false,
detail: { ... }
}
使用示例:
<video-player
:url="videoUrl"
:isLive="false"
@pictureinpicturechange="handlePipChange"
/>
<script setup>
const handlePipChange = (e) => {
if (e.isEnter) {
console.log('进入画中画模式')
} else {
console.log('退出画中画模式')
}
}
</script>
Methods 方法
通过 ref 可以调用组件的控制方法:
| 方法名 | 参数 | 返回值 | 说明 |
|---|---|---|---|
play() |
- | - | 播放视频 |
pause() |
- | - | 暂停视频 |
stop() |
- | - | 停止视频(暂停并回到起点) |
setVolume(volume) |
volume: Number (0-1) |
- | 设置音量 |
setMuted(muted) |
muted: Boolean |
- | 设置静音状态 |
方法调用示例
<template>
<view>
<video-player ref="playerRef" :url="videoUrl" />
<button @click="handlePlay">播放</button>
<button @click="handlePause">暂停</button>
</view>
</template>
<script setup>
import { ref } from 'vue'
const playerRef = ref(null)
const handlePlay = () => {
playerRef.value?.play()
}
const handlePause = () => {
playerRef.value?.pause()
}
</script>
使用示例
示例 1:基础直播播放(M3U8)
<template>
<video-player
:url="liveUrl"
:isLive="true"
:autoplay="true"
:muted="false"
@error="handleError"
@play="handlePlay"
/>
</template>
<script setup>
import { ref } from 'vue'
import VideoPlayer from './components/video-player.vue'
const liveUrl = ref('https://example.com/live/stream.m3u8')
const handleError = (error) => {
console.error('播放错误:', error)
uni.showToast({
title: error.message,
icon: 'none'
})
}
const handlePlay = () => {
console.log('开始播放')
// 小程序端会使用 <live-player> 组件
// H5/APP端会使用 hls.js 播放
}
</script>
示例 2:FLV 直播流(带 iOS 检测)
<template>
<view>
<!-- iOS 环境下会自动显示不支持提示 -->
<video-player
:url="flvUrl"
:isLive="true"
:autoplay="true"
@error="handleError"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
const flvUrl = ref('https://example.com/live/stream.flv')
const handleError = (error) => {
if (error.code === 'FLV_NOT_SUPPORTED_ON_IOS') {
// iOS 环境,建议切换到 M3U8
console.log('检测到 iOS 环境,建议使用 M3U8 格式')
// 可以在这里切换到备用的 M3U8 地址
// flvUrl.value = 'https://example.com/live/stream.m3u8'
}
}
</script>
示例 3:点播视频(带控制条)
<template>
<video-player
ref="playerRef"
:url="videoUrl"
:isLive="false"
:autoplay="false"
:controls="true"
:loop="false"
:poster="posterUrl"
@ended="handleEnded"
@timeupdate="handleTimeUpdate"
/>
</template>
<script setup>
import { ref } from 'vue'
const playerRef = ref(null)
const videoUrl = ref('https://example.com/video/demo.mp4')
const posterUrl = ref('https://example.com/poster.jpg')
const handleEnded = () => {
console.log('视频播放完毕')
}
const handleTimeUpdate = (e) => {
// 获取播放进度
const currentTime = e.target?.currentTime
const duration = e.target?.duration
console.log(`播放进度: ${currentTime}/${duration}`)
}
</script>
示例 4:多清晰度切换
<template>
<view>
<video-player :url="currentUrl" :isLive="true" />
<view class="quality-selector">
<button @click="switchQuality('hd')">高清</button>
<button @click="switchQuality('sd')">标清</button>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const currentUrl = ref('')
const urlMap = {
hd: 'https://example.com/live/hd.m3u8',
sd: 'https://example.com/live/sd.m3u8'
}
const switchQuality = (quality) => {
currentUrl.value = urlMap[quality]
}
// 默认高清
switchQuality('hd')
</script>
示例 5:小程序画中画功能
<template>
<view>
<video-player
ref="playerRef"
:url="videoUrl"
:isLive="false"
:controls="true"
@pictureinpicturechange="handlePipChange"
/>
<view class="pip-status">
画中画状态: {{ pipStatus }}
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const playerRef = ref(null)
const videoUrl = ref('https://example.com/video/demo.mp4')
const pipStatus = ref('未激活')
const handlePipChange = (e) => {
if (e.isEnter) {
pipStatus.value = '已进入画中画'
console.log('进入画中画模式,事件类型:', e.type)
} else {
pipStatus.value = '已退出画中画'
console.log('退出画中画模式,事件类型:', e.type)
}
}
</script>
📱 注意:画中画功能仅在小程序端的
<video>组件中可用(isLive=false)
注意事项
1. iOS 兼容性
❌ 不支持的格式:
- FLV 格式(会显示错误提示)
- RTMP 协议
✅ 推荐格式:
- M3U8/HLS(最佳选择)
- MP4(点播视频)
iOS FLV 格式自动处理: 组件会自动检测 iOS 环境下的 FLV 格式播放请求:
- H5 端:显示警告覆盖层,阻止播放,触发 error 事件
- APP 端:显示警告覆盖层,阻止播放,触发 error 事件
- 小程序端:不受影响(使用原生组件)
错误事件参数:
{
message: 'iOS系统不支持FLV格式播放',
code: 'FLV_NOT_SUPPORTED_ON_IOS',
format: 'flv'
}
2. 自动播放限制
大部分浏览器(尤其是移动端)限制自动播放有声视频:
<!-- 方案 1:静音自动播放 -->
<video-player :url="url" :autoplay="true" :muted="true" />
<!-- 方案 2:用户交互后播放 -->
<video-player ref="player" :url="url" :autoplay="false" />
<button @click="$refs.player.play()">点击播放</button>
3. 跨域问题
视频资源需要配置 CORS 响应头:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD
4. 直播延迟优化
对于直播场景,建议配置:
<video-player
:url="liveUrl"
:isLive="true"
:autoplay="true"
:muted="false"
/>
组件内部已针对直播优化:
- HLS:
lowLatencyMode: true,减少缓冲 - FLV:
isLive: true,禁用 seek 功能
5. 资源释放
组件会在卸载时自动释放资源,无需手动清理。
常见问题
Q1: isLive 参数有什么作用?为什么很重要?
A: isLive 是组件最重要的参数之一,它决定了:
-
小程序端组件选择:
isLive=true→ 使用<live-player>组件(直播专用)isLive=false→ 使用<video>组件(点播专用)
-
H5/APP 端播放优化:
isLive=true→ FLV 播放器配置为直播模式,禁用 seek、优化缓冲isLive=false→ 启用完整的播放控制功能
-
功能可用性:
- 直播模式:不支持进度条拖拽、循环播放等点播功能
- 点播模式:支持完整的播放控制、画中画等功能
错误示例:
<!-- ❌ 错误:直播流使用 isLive=false -->
<video-player :url="live.m3u8" :isLive="false" />
<!-- 小程序端会使用 video 组件,可能无法正常播放直播流 -->
<!-- ✅ 正确:直播流使用 isLive=true -->
<video-player :url="live.m3u8" :isLive="true" />
Q2: 为什么 iOS 上 FLV 不能播放?
A: iOS 不支持 Flash 技术,且对 MSE 支持有限。建议使用 M3U8 格式,这是 iOS 原生支持的流媒体格式。
Q3: 如何判断当前是否为 iOS 环境?
A: 组件内部已自动检测,当 iOS 环境遇到 FLV 格式时会自动显示错误提示。你也可以监听 error 事件:
const handleError = (error) => {
if (error.code === 'FLV_NOT_SUPPORTED_ON_IOS') {
// 切换到 M3U8 或提示用户
}
}
Q4: 如何实现多清晰度切换?
A: 直接修改 url 属性即可,组件会自动重新加载:
const switchQuality = (newUrl) => {
videoUrl.value = newUrl // 组件会自动销毁旧播放器并加载新地址
}
Q5: 小程序端支持哪些格式?
A: 小程序端根据 isLive 参数使用不同组件:
直播场景 (isLive=true),使用 <live-player> 组件,支持:
- RTMP
- FLV
- M3U8
点播场景 (isLive=false),使用 <video> 组件,支持:
- MP4
- M3U8
- 其他微信支持的视频格式
具体支持情况以微信官方文档为准。
Q6: 如何监听播放进度?
A: 监听 timeupdate 事件(仅点播场景有效):
<video-player :isLive="false" @timeupdate="handleTimeUpdate" />
<script setup>
const handleTimeUpdate = (e) => {
const video = e.target
console.log('当前时间:', video.currentTime)
console.log('总时长:', video.duration)
console.log('进度百分比:', (video.currentTime / video.duration * 100).toFixed(2) + '%')
}
</script>
⚠️ 注意:直播场景 (
isLive=true) 不支持进度监听。
Q7: 如何使用画中画功能?
A: 画中画功能仅在小程序端的直播场景可用:
<video-player
:url="videoUrl"
:isLive="true"
:controls="false"
@pictureinpicturechange="handlePipChange"
/>
<script setup>
const handlePipChange = (e) => {
if (e.isEnter) {
console.log('进入画中画')
// 可以在这里更新UI状态
} else {
console.log('退出画中画')
}
}
</script>
📱 限制:
- 仅小程序端支持
- 必须设置
isLive=true(直播模式)- 需要用户手动触发(微信限制)
Q8: 如何处理网络错误?
A: 监听 error 事件并根据错误类型处理:
const handleError = (error) => {
if (error.errorType === 'NetworkError') {
// 网络错误,可以重试
setTimeout(() => {
playerRef.value?.play()
}, 3000)
} else {
// 其他错误
uni.showToast({ title: error.message, icon: 'none' })
}
}
技术支持
如有问题,请联系开发团队或查阅相关文档:

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 115
赞赏 0
下载 10848120
赞赏 1799
赞赏
京公网安备:11010802035340号