更新记录
1.0.0(2026-07-26)
- 首次发布
hero-inline-player - 支持
uni-appAndroid App 原生内嵌播放器 - 基于
AndroidX Media3 / ExoPlayer封装 - 支持
m3u8、mp4在线播放 - 支持播放、暂停、停止、倍速、循环、静音、画面模式切换
- 支持
seek(position)秒级定位与毫秒级定位 - 支持进度、缓冲、播放状态、控制栏显隐等事件回调
- 支持音量、亮度调节与后台自动暂停
- 支持自定义功能挂载,可扩展业务控制层和页面交互
- 补充 README 文档,新增自定义扩展能力说明
- 补充增值功能说明,投屏功能插件和电池状态展示功能插件可联系作者单独购买
平台兼容性
uni-app(3.7.11)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | - | × | × | × | √ | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
hero-inline-player
hero-inline-player 是一个面向 uni-app Android App 的 UTS 原生视频播放器组件,基于 AndroidX Media3 / ExoPlayer 封装,适合在页面内嵌播放 m3u8、mp4 等在线视频流。
当前版本重点解决了以下场景:
- 页面内嵌原生播放器
seek(position)秒级定位- 自定义与原生控制栏协同显隐
- 支持自定义功能挂载,可围绕播放器自由扩展业务按钮、控制层、选集、线路切换和全屏交互
- 支持基于倍速能力扩展长按临时倍速播放场景,例如长按进入
3x播放、松开恢复原倍速 - 全屏锁屏与全屏临时隐藏态
- 左右滑动快进快退
- 左右侧纵向手势调节亮度与音量
- 切换视频源时保留当前剧集与播放进度
- App 进入后台自动暂停
平台支持
App-Android
当前未提供 App-iOS、小程序、H5 的原生实现。
依赖说明
组件内置以下 Android 依赖:
androidx.media3:media3-exoplayer:1.4.1androidx.media3:media3-exoplayer-hls:1.4.1androidx.media3:media3-datasource:1.4.1androidx.media3:media3-ui:1.4.1
最低 minSdkVersion 为 21。
基础用法
<template>
<hero-inline-player
ref="playerRef"
:src="src"
:autoplay="true"
:muted="false"
:volume="-1"
:brightness="-1"
:loop="false"
:playbackRate="1"
:resizeMode="'contain'"
:controllerLocked="false"
:commandAction="playerCommandAction"
:commandVersion="playerCommandVersion"
:startPosition="0"
@ready="handleReady"
@timeupdate="handleTimeupdate"
@ended="handleEnded"
@error="handleError"
/>
</template>
<script>
export default {
data() {
return {
src: 'https://example.com/demo.m3u8',
playerCommandAction: '',
playerCommandVersion: 0
}
},
methods: {
handleReady() {},
handleTimeupdate(e) {},
handleEnded() {},
handleError(e) {},
issueCommand(action) {
this.playerCommandAction = action
this.$nextTick(() => {
if (this.playerCommandAction === action) {
this.playerCommandVersion += 1
}
})
},
seekTo60s() {
if (this.$refs.playerRef && typeof this.$refs.playerRef.seek === 'function') {
this.$refs.playerRef.seek(60)
}
}
}
}
</script>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
src |
string |
'' |
视频地址,当前已支持 m3u8、mp4 |
autoplay |
boolean |
false |
是否自动播放 |
poster |
string |
'' |
预留海报字段,当前原生层未渲染海报 |
muted |
boolean |
false |
是否静音 |
loop |
boolean |
false |
是否单集循环 |
playbackRate |
number |
1 |
播放倍速 |
volume |
number |
-1 |
音量范围 0-1,-1 表示不在初始化阶段改动系统音量 |
brightness |
number |
-1 |
亮度范围 0-1,-1 表示不主动设置亮度 |
controllerLocked |
boolean |
false |
是否锁定原生控制栏与触摸显隐 |
resizeMode |
string |
'contain' |
画面模式:contain / cover / fill |
commandAction |
string |
'' |
命令动作,配合 commandVersion 使用 |
commandVersion |
number |
0 |
命令版本号,每次发新命令时递增 |
startPosition |
number |
0 |
初始播放位置,单位毫秒 |
事件
| 事件名 | 说明 |
|---|---|
ready |
组件原生视图已加载 |
play |
开始播放 |
pause |
暂停播放 |
error |
播放或初始化错误 |
timeupdate |
播放进度更新 |
progress |
缓冲与进度更新 |
buffering |
缓冲状态变化 |
ended |
当前视频播放结束 |
seeking |
开始定位 |
seeked |
定位完成 |
controlvisibilitychange |
原生控制栏显隐变化 |
statechange |
综合状态事件,含播放态、控制栏、亮度、音量等信息 |
常用事件字段包括:
statusmessagepositionbufferedPositiondurationplayerStateisPlayingvisiblecontrollerVisiblesystemVolumesystemVolumePercent
Ref 方法
通过 ref 可调用以下方法:
| 方法 | 说明 |
|---|---|
startPlayback() |
开始播放 |
pausePlayback() |
暂停播放 |
stopPlayback() |
停止播放并回到起点 |
setSource(url, autoplay, position) |
设置播放源,position 单位毫秒 |
reloadSourceAtPosition(position, autoplay) |
重载当前源并定位 |
seek(position) |
秒级定位,position 单位秒 |
seekToPosition(position, autoplay) |
毫秒级定位 |
getCurrentPosition() |
获取当前播放位置,单位毫秒 |
getDuration() |
获取总时长,单位毫秒 |
getBufferedPosition() |
获取缓冲位置,单位毫秒 |
getPlayerState() |
获取播放器状态 |
isPlaying() |
是否正在播放 |
isControllerVisible() |
原生控制栏当前是否显示 |
runCommandAction(action) |
执行命令:play / pause / stop / show-controller / hide-controller |
updateMuted(muted) |
更新静音状态 |
updateVolume(volume) |
更新系统音量,范围 0-1 |
updateBrightness(brightness) |
更新亮度,范围 0-1 |
updateControllerLock(locked, showControllerAfterUnlock) |
更新控制栏锁定状态 |
getSystemVolume() |
获取系统音量原始值 |
getSystemVolumePercent() |
获取系统音量百分比 |
getSystemBrightness() |
获取当前亮度值 |
canWriteBrightnessSettings() |
是否拥有系统亮度写入权限 |
openBrightnessSettingsPermission() |
打开系统亮度授权页 |
updatePlaybackRate(rate) |
更新播放倍速 |
updateLoop(loop) |
更新循环状态 |
updateResizeMode(mode) |
更新画面模式 |
命令下发建议
commandAction 和 commandVersion 适合在模板绑定场景下驱动播放器命令。
建议始终使用下面这种顺序:
this.playerCommandAction = action
this.$nextTick(() => {
if (this.playerCommandAction === action) {
this.playerCommandVersion += 1
}
})
这样可以避免原生侧在监听 commandVersion 时读取到上一条旧命令。
注意事项
- 本组件当前仅支持
Android App。 volume = -1用于避免页面初始化时主动拉起系统音量浮层。- 亮度调节会优先尝试系统亮度,若没有写设置权限,会回退到窗口亮度。
- 组件支持锁屏与全屏隐藏态;若页面自己做一层自定义控制栏,建议把“原生控制栏显隐”和“页面控制栏显隐”统一管理。
- 若页面需要拖动进度,优先调用
seek(position),其行为更接近 uni-appvideoContext.seek()。 - 当前内置的地址类型识别已覆盖
m3u8与mp4;其他格式是否可用取决于 ExoPlayer 对源地址和容器格式的实际支持情况。
适用场景
- 剧集播放页
- 短剧/短视频详情页
- 需要自定义全屏交互的播放器页面
- 需要原生
m3u8/mp4播放能力的uni-appAndroid 项目
自定义扩展能力
本插件不只是一个固定样式的播放器组件,也可以作为业务播放器内核使用。
开发者可围绕播放器自由接入自定义功能,例如:
- 自定义顶部栏、底部栏
- 自定义播放控制按钮
- 自定义全屏/小窗交互
- 自定义选集面板
- 自定义线路切换
- 自定义长按临时倍速播放交互
- 自定义手势交互联动
- 自定义业务状态展示
- 自定义页面层控制栏显隐逻辑
适合需要保留原生播放能力,同时接入自有业务功能的项目场景。
增值功能
- 投屏功能插件可联系作者单独购买
- 电池状态展示功能插件可联系作者单独购买

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 2689
赞赏 59
下载 12462929
赞赏 1936
赞赏
京公网安备:11010802035340号