更新记录
1.0.3(2026-09-04)
demo
1.0.2(2026-09-04)
- 【UI重构】底部控制栏重构为 B 站两层布局(上层细红进度条,下层合并时间与控制按钮)
- 【图标与样式】更新播放/暂停/全屏图标,加大音量与全屏图标尺寸,全屏模式下控制栏支持 1.4 倍放大
- 【状态修复】修复视频播放完毕后状态仍停留在
playing的问题 - 【类型与编译】修复 UTS 中 Float 与 Number 类型转换导致的
ClassCastException编译与运行时问题 - 【包体积优化】iOS 平台改为通过 CocoaPods 远程依赖
Libmpv框架,极大减小插件上传体积 - 【文档完善】新增完整 API 使用文档,包含播放控制、音量、速度、弹幕、清晰度、全屏等所有方法的详细说明和示例
平台兼容性
uni-app x(5.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | √ | - | - |
DPlayer 视频播放器
基于 libmpv 的跨平台视频播放器 uni_modules 插件,支持 H.265 解码和直播拉流。
功能特性
- H.265/HEVC 支持:Android/iOS 硬件解码 + FFmpeg 软件解码
- 直播拉流:HLS、HTTP-FLV、RTMP、RTSP 协议
- 多平台:uni-app X (UTS)、uni-app NVue、Web、微信小程序
- 弹幕系统:滚动弹幕、顶部弹幕、底部弹幕
- 清晰度切换:多码率无缝切换
- 自动重连:直播断流自动重连
- B站风格 UI:底部控制栏采用 B 站两层布局设计
安装
- 下载本插件到项目的
uni_modules/目录 - 在
pages.json中配置页面 - 在页面中使用
<d-player-video>组件
iOS 依赖配置
iOS 平台通过 CocoaPods 自动依赖 Libmpv 框架,无需手动下载。首次编译时会自动从 Gitee 下载 libmpv-1.0.0.xcframework.zip。
基础用法
<template>
<d-player-video
ref="player"
src="https://example.com/video.mp4"
:autoplay="true"
:live="false"
@statechange="onStateChange"
@progress=""
@prepared="onPrepared"
@error="onError"
/>
</template>
<script lang="uts">
export default {
methods: {
onStateChange(e: any) {
console.log('状态变化:', e.state)
},
(e: any) {
console.log('进度:', e.position, '/', e.duration)
},
onPrepared(e: any) {
console.log('时长:', e.duration)
},
onError(e: any) {
console.error('错误:', e.code, e.message)
}
}
}
</script>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| src | String | "" | 视频/直播流地址 |
| autoplay | Boolean | false | 自动播放 |
| loop | Boolean | false | 循环播放 |
| live | Boolean | false | 是否为直播流 |
| muted | Boolean | false | 静音 |
| volume | Number | 1.0 | 音量 (0-1) |
| playbackRate | Number | 1.0 | 播放速度 |
| decodeMode | String | "auto" | 解码模式: auto/hw/sw |
| showControls | Boolean | true | 显示控制栏 |
| showDanmaku | Boolean | false | 显示弹幕 |
| objectFit | String | "contain" | 视频填充模式 |
API 使用方法
通过 ref 调用组件方法:
播放控制
// 开始播放(如果未加载媒体则自动加载)
this.$refs.player.play()
// 暂停播放
this.$refs.player.pause()
// 停止播放(重置到开头)
this.$refs.player.stop()
// 跳转到指定位置(单位:毫秒)
this.$refs.player.seek(10000) // 跳转到 10 秒
this.$refs.player.seek(60000) // 跳转到 1 分钟
音量控制
// 设置音量(0-1 之间)
this.$refs.player.setVolume(0.5) // 50% 音量
this.$refs.player.setVolume(0.0) // 静音
this.$refs.player.setVolume(1.0) // 最大音量
// 切换静音状态
this.$refs.player.toggleMute()
// 获取静音状态
const muted = this.$refs.player.getMuted()
播放速度
// 设置播放速度
this.$refs.player.setSpeed(0.5) // 0.5 倍速
this.$refs.player.setSpeed(1.0) // 正常速度
this.$refs.player.setSpeed(1.5) // 1.5 倍速
this.$refs.player.setSpeed(2.0) // 2 倍速
// 获取当前播放速度
const speed = this.$refs.player.getPlaybackRate()
获取播放信息
// 获取播放状态
// 返回值: "idle" | "opening" | "ready" | "playing" | "paused" | "completed" | "error"
const state = this.$refs.player.getState()
// 获取当前播放位置(单位:毫秒)
const position = this.$refs.player.getPosition()
// 获取媒体总时长(单位:毫秒)
const duration = this.$refs.player.getDuration()
// 获取视频尺寸
// 返回值: { width: number, height: number }
const size = this.$refs.player.getVideoSize()
console.log('视频宽度:', size.width, '视频高度:', size.height)
// 获取是否为直播流
const isLive = this.$refs.player.isLive()
// 获取全屏状态
const isFullscreen = this.$refs.player.isFullscreen()
// 获取循环播放状态
const loop = this.$refs.player.getLoop()
// 获取自动播放状态
const autoplay = this.$refs.player.isAutoplay()
// 获取控制栏显示状态
const showControls = this.$refs.player.isShowControls()
// 获取弹幕显示状态
const showDanmaku = this.$refs.player.isShowDanmaku()
// 获取解码模式
// 返回值: "auto" | "hw" | "sw"
const decodeMode = this.$refs.player.getDecodeType()
// 获取视频填充模式
// 返回值: "contain" | "cover" | "fill" | "none"
const objectFit = this.$refs.player.getObjectFit()
弹幕控制
// 添加弹幕
this.$refs.player.addDanmaku("这是一条弹幕")
// 添加带样式的弹幕
this.$refs.player.addDanmaku("彩色弹幕", {
color: "#ff0000", // 弹幕颜色
fontSize: 20, // 字体大小
type: "scroll" // 类型: "scroll" | "top" | "bottom"
})
// 设置弹幕显示/隐藏
this.$refs.player.setDanmakuVisible(true) // 显示弹幕
this.$refs.player.setDanmakuVisible(false) // 隐藏弹幕
// 清空所有弹幕
this.$refs.player.clearDanmaku()
清晰度切换
// 设置清晰度列表
this.$refs.player.setQualityLevels([
{ id: "1080p", label: "1080P 超清", url: "https://example.com/1080p.mp4" },
{ id: "720p", label: "720P 高清", url: "https://example.com/720p.mp4" },
{ id: "480p", label: "480P 标清", url: "https://example.com/480p.mp4" }
])
// 切换清晰度面板显示/隐藏
this.$refs.player.toggleQualityPanel()
// 获取当前清晰度 ID
const qualityId = this.$refs.player.getCurrentQuality()
// 获取当前清晰度标签
const qualityLabel = this.$refs.player.getCurrentQualityLabel()
全屏控制
// 进入全屏
this.$refs.player.setFullscreen(true)
// 退出全屏
this.$refs.player.setFullscreen(false)
// 切换全屏状态
const isFullscreen = this.$refs.player.isFullscreen()
this.$refs.player.setFullscreen(!isFullscreen)
释放资源
// 停止播放并释放所有资源(组件销毁前调用)
this.$refs.player.release()
完整示例
<template>
<view>
<d-player-video
ref="player"
src="https://example.com/video.mp4"
:autoplay="true"
:loop="false"
:live="false"
@statechange="onStateChange"
@progress=""
@prepared="onPrepared"
@completion="onCompletion"
@error="onError"
/>
<view class="controls">
<button @click="togglePlay">播放/暂停</button>
<button @click="seekForward">快进 10 秒</button>
<button @click="seekBackward">快退 10 秒</button>
<button @click="changeSpeed">切换倍速</button>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
isPlaying: false,
currentTime: 0,
duration: 0,
currentSpeed: 1.0
}
},
methods: {
togglePlay() {
const state = this.$refs.player.getState()
if (state === "playing") {
this.$refs.player.pause()
} else {
this.$refs.player.play()
}
},
seekForward() {
const pos = this.$refs.player.getPosition()
this.$refs.player.seek(pos + 10000)
},
seekBackward() {
const pos = this.$refs.player.getPosition()
this.$refs.player.seek(Math.max(0, pos - 10000))
},
changeSpeed() {
const speeds = [0.5, 1.0, 1.5, 2.0]
const idx = speeds.indexOf(this.currentSpeed)
this.currentSpeed = speeds[(idx + 1) % speeds.length]
this.$refs.player.setSpeed(this.currentSpeed)
},
onStateChange(e) {
this.isPlaying = (e.state === "playing")
console.log('状态变化:', e.state)
},
(e) {
this.currentTime = e.position
this.duration = e.duration
},
onPrepared(e) {
this.duration = e.duration
console.log('媒体加载完成,时长:', e.duration)
},
onCompletion() {
console.log('播放完成')
},
onError(e) {
console.error('播放错误:', e.code, e.message)
}
},
onUnmounted() {
this.$refs.player.release()
}
}
</script>
事件
| 事件名 | 参数 | 说明 |
|---|---|---|
| statechange | { state } | 播放状态变化 |
| progress | { position, duration } | 播放进度更新 |
| prepared | { duration } | 媒体加载完成 |
| buffering | { percent } | 缓冲状态 |
| error | { code, message } | 播放错误 |
| videosizechanged | { width, height } | 视频尺寸变化 |
| seekcomplete | {} | 跳转完成 |
| completion | {} | 播放完成 |
| livereconnect | { attempt } | 直播重连 |
直播拉流
<template>
<d-player-video
src="rtmp://live.example.com/stream"
:live="true"
:autoplay="true"
@livereconnect="onReconnect"
/>
</template>
支持的直播协议:
- HLS (m3u8)
- HTTP-FLV
- RTMP
- RTSP
H.265 支持
组件自动检测 H.265 硬件解码能力:
- Android:MediaCodec 硬解 + FFmpeg 软解
- iOS:VideoToolbox 硬解 + FFmpeg 软解
- Web:ffmpeg.wasm 软解(实验性)
- 小程序:不支持 H.265
平台支持
| 平台 | 状态 | 说明 |
|---|---|---|
| uni-app X (Android) | 完整支持 | libmpv + MediaCodec |
| uni-app X (iOS) | 完整支持 | libmpv + VideoToolbox |
| uni-app NVue | 完整支持 | 同 uni-app X |
| Web | 完整支持 | mpegts.js + hls.js |
| 微信小程序 | 基础支持 | 原生 video 组件 |
UI 特性
B站风格控制栏
底部控制栏采用 B 站两层布局设计:
- 上层:细红色进度条,支持拖动 seek
- 下层:播放/暂停按钮、时间显示、倍速、音量、全屏
图标样式
- 播放按钮:饱满三角形(B站风格)
- 暂停按钮:圆角双竖杠(B站风格)
- 全屏按钮:四角向外/向内图标
- 音量按钮:喇叭+声波图标
全屏适配
- 全屏模式下控制栏自动放大 1.4 倍
- 保持 B 站风格布局一致
注意事项
- H.265 专利风险:H.265 编解码器存在专利许可问题,商业使用需注意授权
- Web 端 H.265:依赖 ffmpeg.wasm,性能可能受影响
- 小程序限制:微信小程序原生 video 组件不支持 H.265
- 直播重连:默认最多重试 3 次,间隔 3 秒
- iOS 依赖:首次编译需联网下载 Libmpv 框架(约 10MB)
开发
目录结构
d-player-video/
├── index.uts # 全局入口
├── index.vue # 根组件
├── package.json # uni_modules 配置
├── common/
│ ├── types.uts # 类型定义
│ ├── events.uts # 事件常量
│ ├── state-machine.uts # 状态机
│ ├── player-config.uts # 配置管理
│ ├── danmaku-types.uts # 弹幕类型
│ └── quality-types.uts # 清晰度类型
├── components/
│ ├── DPlayerControl.vue # 控制栏组件
│ ├── DPlayerProgress.vue # 进度条组件
│ ├── DPlayerDanmaku.vue # 弹幕组件
│ └── DPlayerQuality.vue # 清晰度组件
└── utssdk/
├── app-android/
│ ├── index.vue # Android UTS 组件
│ ├── index.uts # Android 平台函数
│ ├── config.json # Android 配置
│ └── DPlayerNative.kt # Native 桥接
├── app-ios/
│ ├── index.vue # iOS UTS 组件
│ ├── index.uts # iOS 平台函数
│ ├── config.json # iOS 配置
│ ├── Libmpv.podspec # CocoaPods 配置
│ └── DPlayerEngine.swift # 引擎实现
├── web/
│ └── index.uts # Web 平台实现
└── mp-weixin/
└── index.vue # 微信小程序实现
更新日志
1.0.2(2026-09-03)
- 【UI重构】底部控制栏重构为 B 站两层布局(上层细红进度条,下层合并时间与控制按钮)
- 【图标与样式】更新播放/暂停/全屏图标,加大音量与全屏图标尺寸,全屏模式下控制栏支持 1.4 倍放大
- 【状态修复】修复视频播放完毕后状态仍停留在
playing的问题 - 【类型与编译】修复 UTS 中 Float 与 Number 类型转换导致的
ClassCastException编译与运行时问题 - 【包体积优化】iOS 平台改为通过 CocoaPods 远程依赖
Libmpv框架,极大减小插件上传体积 - 【文档完善】新增完整 API 使用文档,包含播放控制、音量、速度、弹幕、清晰度、全屏等所有方法的详细说明和示例
1.0.0(2026-08-30)
初始化
许可
MIT License

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 96
赞赏 0
下载 12563068
赞赏 1949
赞赏
京公网安备:11010802035340号