更新记录

1.0.0(2026-04-04)

  • 首个正式版本,提供 uni-app x 原生视频播放组件
  • 支持 Android 与 iOS 双端播放,Harmony 当前为不支持状态占位实现
  • 支持 sourceposterautoplaymutedloopcontrolsobjectFitplaybackRate
  • 支持 play()pause()stop()seek()getCurrentTime()getDuration()
  • 支持 enterFullscreen()exitFullscreen()requestPictureInPicture()
  • 支持 loadedplaypauseendedwaitingbufferingseekingseekedtimeupdatefullscreenchangepictureinpicturechangeerror
  • 支持全屏手势、锁定控制层,以及 gesturestartgesturechangegestureendlockchange
  • 支持通过 createHansVideoContext(id) 获取播放器上下文进行控制

平台兼容性

uni-app x(5.06)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - -

hans-video

hans-video 是一个面向 uni-app x 的原生视频组件,提供统一的播放控制、封面、全屏、画中画和手势交互能力。

支持平台

平台 支持情况 说明
Android 支持 调试阶段建议使用自定义基座或云打包产物验证实际播放与画中画能力
iOS 支持 支持播放、全屏、画中画
Harmony 不支持 当前版本仅保留占位实现,运行时会返回 1005 unsupported

功能概览

  • 视频源播放:支持 mp4m3u8(HLS)
  • 播放控制:playpausestopseek
  • 播放参数:autoplaymutedloopplaybackRate
  • 显示能力:posterobjectFit、插件自定义 controls
  • 状态事件:loadedplaypauseendedwaitingbufferingseekingseekedtimeupdate
  • 扩展能力: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:资源类型,可传 mp4hls 等标识;不传时由播放器自行判断
  • 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 包含以下字段:

  • typeseekvolumebrightness
  • phasestartchangeend
  • fullscreen:当前是否处于全屏
  • locked:当前是否已锁定控制层
  • gestureZoneleftrightcenter
  • deltaXdeltaYtargetTimecurrentTimedurationvolumebrightness:按手势类型返回对应数据

上下文控制

通过 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

建议验证项

发布前建议至少验证以下场景:

  • sourcepostercontrolsautoplaymutedloopplaybackRate
  • playpausestopseek
  • loadedtimeupdatefullscreenchangepictureinpicturechangeerror
  • 全屏、画中画、手势、锁定控制层

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。