更新记录
1.0.0(2026-04-04)
- 首个正式版本,提供
uni-app x原生视频播放组件 - 支持 Android 与 iOS 双端播放,Harmony 当前为不支持状态占位实现
- 支持
source、poster、autoplay、muted、loop、controls、objectFit、playbackRate - 支持
play()、pause()、stop()、seek()、getCurrentTime()、getDuration() - 支持
enterFullscreen()、exitFullscreen()、requestPictureInPicture() - 支持
loaded、play、pause、ended、waiting、buffering、seeking、seeked、timeupdate、fullscreenchange、pictureinpicturechange、error - 支持全屏手势、锁定控制层,以及
gesturestart、gesturechange、gestureend、lockchange - 支持通过
createHansVideoContext(id)获取播放器上下文进行控制
平台兼容性
uni-app x(5.06)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | √ | - | - |
hans-video
hans-video 是一个面向 uni-app x 的原生视频组件,提供统一的播放控制、封面、全屏、画中画和手势交互能力。
支持平台
| 平台 | 支持情况 | 说明 |
|---|---|---|
| Android | 支持 | 调试阶段建议使用自定义基座或云打包产物验证实际播放与画中画能力 |
| iOS | 支持 | 支持播放、全屏、画中画 |
| Harmony | 不支持 | 当前版本仅保留占位实现,运行时会返回 1005 unsupported |
功能概览
- 视频源播放:支持
mp4、m3u8(HLS) - 播放控制:
play、pause、stop、seek - 播放参数:
autoplay、muted、loop、playbackRate - 显示能力:
poster、objectFit、插件自定义controls - 状态事件:
loaded、play、pause、ended、waiting、buffering、seeking、seeked、timeupdate - 扩展能力:
enterFullscreen()、exitFullscreen()、requestPictureInPicture() - 手势能力:快进快退、亮度、音量、锁定控制层
接入方式
将插件安装到项目的 uni_modules/hans-video 后,可直接在页面中使用 <hans-video />。
基础示例
<template>
<view class="page">
<hans-video
id="video-player"
class="player"
:source="source"
poster="https://example.com/poster.jpg"
:controls="true"
:autoplay="false"
@loaded="handleLoaded"
@error="handleError"
@timeupdate="handleTimeUpdate"
/>
</view>
</template>
<script setup lang="uts">
import { createHansVideoContext, IHansVideoContext } from '@/uni_modules/hans-video'
const source = ref({
url: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
type: 'hls'
})
let videoContext: IHansVideoContext | null = null
onReady(() => {
nextTick(() => {
videoContext = createHansVideoContext('video-player')
})
})
function handleLoaded(): void {
videoContext?.play()
}
function handleError(error: any): void {
console.error('hans-video error', error)
}
function handleTimeUpdate(event: any): void {
console.log('progress', event)
}
</script>
<style>
.page {
padding: 24rpx;
}
.player {
width: 100%;
height: 420rpx;
}
</style>
source 参数
source 为对象类型:
type HansVideoSourceHeader = {
name: string
value: string
}
type HansVideoSource = {
url: string
type?: string | null
headers?: HansVideoSourceHeader[] | null
cookies?: string[] | null
}
字段说明:
url:视频地址,必填type:资源类型,可传mp4、hls等标识;不传时由播放器自行判断headers:附加请求头cookies:附加 Cookie 列表,插件会合并为请求头发送
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
source |
HansVideoSource \| null |
null |
视频源 |
autoplay |
boolean |
false |
是否在新视频源加载完成后自动播放 |
muted |
boolean |
false |
是否静音 |
loop |
boolean |
false |
是否循环播放 |
controls |
boolean |
true |
是否显示插件自定义控制层 |
poster |
string |
'' |
封面图地址,支持本地路径、file://、网络地址 |
objectFit |
'contain' \| 'cover' \| 'fill' \| 'stretch' |
'contain' |
视频缩放模式 |
playbackRate |
number |
1 |
播放倍速,最小值会被限制为 0.01 |
gestureEnabled |
boolean |
true |
是否启用手势 |
gestureSeekEnabled |
boolean |
true |
是否启用快进快退手势 |
gestureVolumeEnabled |
boolean |
true |
是否启用音量手势 |
gestureBrightnessEnabled |
boolean |
true |
是否启用亮度手势 |
gestureOverlayEnabled |
boolean |
true |
是否显示手势反馈层,仅控制 UI,不关闭手势输入 |
lockControlEnabled |
boolean |
true |
是否显示锁定控制层入口 |
title |
string |
'' |
全屏态顶部标题 |
事件
基础事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
loaded |
资源加载完成 | 无 |
play |
开始播放 | 无 |
pause |
暂停播放 | 无 |
ended |
播放结束 | 无 |
waiting |
进入等待状态 | 无 |
buffering |
缓冲中 | 无 |
error |
播放错误 | { code, message } |
进度与状态事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
timeupdate |
播放时间更新 | { currentTime, duration } |
seeking |
开始跳转 | { currentTime } |
seeked |
跳转完成 | { currentTime } |
fullscreenchange |
全屏状态变化 | { fullscreen } |
pictureinpicturechange |
画中画状态变化 | { active } |
lockchange |
锁定状态变化 | { locked } |
手势事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
gesturestart |
手势开始 | HansVideoGestureEvent |
gesturechange |
手势变更中 | HansVideoGestureEvent |
gestureend |
手势结束 | HansVideoGestureEvent |
HansVideoGestureEvent 包含以下字段:
type:seek、volume、brightnessphase:start、change、endfullscreen:当前是否处于全屏locked:当前是否已锁定控制层gestureZone:left、right、centerdeltaX、deltaY、targetTime、currentTime、duration、volume、brightness:按手势类型返回对应数据
上下文控制
通过 createHansVideoContext(id) 获取播放器上下文:
import { createHansVideoContext } from '@/uni_modules/hans-video'
const videoContext = createHansVideoContext('video-player')
注意事项:
id需要和组件上的id保持一致- 需要在组件完成挂载和原生视图绑定后再获取上下文
- 若返回
null,表示当前原生视图尚未完成绑定,应在稍后重试
IHansVideoContext 方法
| 方法 | 说明 |
|---|---|
play() |
播放 |
pause() |
暂停 |
stop() |
停止并回到起点 |
seek(time) |
跳转到指定秒数 |
setPlaybackRate(rate) |
设置播放倍速 |
getCurrentTime() |
获取当前播放时间 |
getDuration() |
获取视频总时长 |
enterFullscreen() |
进入全屏 |
exitFullscreen() |
退出全屏 |
requestPictureInPicture() |
请求进入画中画 |
lockControls() |
锁定控制层 |
unlockControls() |
解除锁定 |
isLocked() |
获取当前是否锁定 |
调试日志
插件提供可选日志开关:
import { isHansVideoLogEnabled, setHansVideoLogEnabled } from '@/uni_modules/hans-video'
setHansVideoLogEnabled(true)
const enabled = isHansVideoLogEnabled()
建议仅在联调阶段开启。
错误码
| 错误码 | 说明 |
|---|---|
1001 |
无效的视频源 |
1002 |
视频加载失败 |
1003 |
播放器初始化失败 |
1004 |
跳转失败 |
1005 |
当前平台或宿主环境不支持 |
1999 |
未知错误 |
平台说明
controls控制的是插件自定义控制层,不是系统原生控制条autoplay只影响新视频源加载后的自动起播,不用于替代运行中的play()/pause()控制- 传入
poster时,组件会在起播前和stop()后显示封面;不传时会尝试提取首帧作为预览 - Android 内联态默认支持横向快进快退;亮度和音量手势主要用于全屏态
- iOS 当前手势能力主要在全屏态启用
- Android 画中画需要宿主支持 PiP;iOS 画中画需要宿主启用
Background Modes -> Audio, AirPlay, and Picture in Picture
建议验证项
发布前建议至少验证以下场景:
source、poster、controls、autoplay、muted、loop、playbackRateplay、pause、stop、seekloaded、timeupdate、fullscreenchange、pictureinpicturechange、error- 全屏、画中画、手势、锁定控制层

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