更新记录

1.0.2(2026-07-09)

文档补充

1.0.1(2026-07-09)

首次提交


平台兼容性

uni-app(4.73)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android Android插件版本 iOS iOS插件版本 鸿蒙
- - × × × 5.1 1.0.2 1.0.2 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.84)

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

hl-hik-player

海康 iSecure Center 视频播放 UTS 原生插件。基于 HatomPlayer SDK(V2.4.6),在 nvue 页面中以原生组件方式使用。

  • 支持平台:Android、iOS(真机;iOS 模拟器不支持)
  • 使用方式:组件标签 + $ref 调方法 + @event 收事件

插件只负责播放。预览 / 回放 / 对讲的 URL 和 header(如 token)由业务层向平台 OpenAPI 获取后传入。


一、能做什么

能力 说明
实时预览 传入预览取流 URL,支持主/子/流畅等码流切换
录像回放 传入回放 URL + 起止时间,支持拖动、进度回调、倍速
抓图 截图保存到指定目录,成功后回调路径
本地录像 开始/停止录像,可选转码为 MP4
声音 开启 / 关闭播放声音
语音对讲 与设备双向语音(需麦克风权限)
鱼眼 开关、展开模式(180° / 360° 等)
电子放大 指定源区域放大到目标区域
全屏 原生全屏进入 / 退出

二、接入前必读

1. 必须打自定义基座

本插件是 UTS 原生插件,标准基座加载不了。请用 HBuilderX 制作「自定义调试基座」后再运行。

修改了插件原生代码、FrameworksResources 后,需要重新打基座,热更新不够。

2. 页面类型

组件只能用在 nvue 页面,不要放在普通 vue 页面里。

3. 取流地址

  • 插件不请求 OpenAPI,不帮你换 token。
  • srcheader、对讲 URL 都由业务传入。
  • SDK 初始化时 accessToken 传空串(插件内部已处理,全局只初始化一次)。

4. 权限

Android(Manifest 已声明):网络、录音、存储/媒体、WAKE_LOCK。对讲时的 RECORD_AUDIO 需运行时申请。

iOS(Info.plist 已声明):麦克风(对讲)、相册读写(抓图/录像存相册)。纯播放一般不弹权限;对讲/存相册时由系统弹窗。


三、快速上手

1. 模板

<template>
  <view>
    <hl-hik-player
      ref="playerRef"
      class="player"
      :src="videoUrl"
      :autoplay="0"
      :play-mode="playMode"
      :playback-time="playbackTime"
      :header="header"
      :player-options="playerOptions"
      @event="handleEvent" />
    <button @click="onPlay">播放</button>
    <button @click="onStop">停止</button>
  </view>
</template>

2. 脚本示例

import { ref } from 'vue'

const playerRef = ref(null)
const videoUrl = ref('rtsp://你的预览地址')
const playMode = ref('live') // live | playback
const header = ref({})       // 如 { token: 'xxx' }
const playbackTime = ref({
  start: Date.now() - 60 * 60 * 1000,
  end: Date.now()
})
const playerOptions = ref({
  hardDecode: true,
  privateData: false,
  qualityType: 1,          // 0 主码流,1 子码流(子码流通常首帧更快)
  timeout: 10,
  // Android 缓冲(毫秒)
  // playBuffer: 200,
  // iOS 缓冲(字节,建议 >= 64KB;官方常用 5*1024*1024)
  bufferLength: 1024 * 1024
})

const getPlayer = () => playerRef.value

const onPlay = () => {
  getPlayer()?.playVideo()
}
const onStop = () => {
  getPlayer()?.stopVideo()
}

const handleEvent = (payload) => {
  // nvue 里真正数据常在 detail 里
  const detail = payload?.detail?.dynamicJSONFields
    ?? payload?.detail
    ?? payload
    ?? {}
  const event = detail.event || ''

  switch (event) {
    case 'playStatusChanged':
      console.log('状态', detail.state, detail.errorCode)
      break
    case 'playbackTimeUpdate':
      // detail.osdTime / playedTime / totalTime(毫秒)
      break
    case 'error':
      console.log('错误', detail.message, detail.action)
      break
    case 'debugLog':
      // 插件诊断信息(含分步耗时等)
      console.log('[插件]', detail.message, detail)
      break
    default:
      if (event) console.log(event, detail)
  }
}

3. 样式注意(nvue)

播放器区域需要明确宽高,例如:

.player {
  width: 750rpx;
  height: 420rpx;
  background-color: #000000;
}

四、属性(Props)

属性 类型 默认 说明
src String '' 取流地址(预览或回放 URL)
autoplay Number 0 1 自动播放,0 不自动
playMode String 'live' live 实时预览;playback 录像回放
playbackTime Object {} 回放时间:{ start: 毫秒时间戳, end: 毫秒时间戳 }
header Object {} 取流 header,如 { token: '...' }
playerOptions Object {} 播放器配置,见下表

playerOptions

字段 类型 默认 说明
hardDecode Boolean true 是否硬解码
privateData Boolean false 是否解析智能信息 / 私有数据(开启会增加开销)
timeout Number SDK 默认约 20 取流超时(秒),主要影响失败反馈速度
qualityType Number - 0 主码流,1 子码流
playBuffer Number - 仅 Android:播放缓冲(毫秒)
bufferLength Number SDK 默认约 5MB 仅 iOS:流缓冲区大小(字节)。小于 64KB 会被忽略
secretKey String - 加密码流密钥
fetchStreamType Number - 取流方式(按海康 SDK 文档)
useSysAEC Boolean - 系统回声消除(Android)
writePlayData Boolean - 写原始码流,调试用(Android)
openPlayerLog Boolean - 打开播放器日志(Android)

注意:playBuffer(毫秒)和 bufferLength(字节)不是一回事,不要把 Android 的毫秒值直接塞给 iOS。


五、方法(通过 ref 调用)

对外方法都有返回值(booleannumber),避免 nvue 对无返回值方法派发不稳定。

重要: 播放控制请用 playVideo / stopVideo / pauseVideo / resumeVideo,不要用 play / stop 这类容易和原生或其它 API 冲突的名字。

播放控制

方法 参数 返回 说明
playVideo() - boolean 按当前 playMode 开始播放
stopVideo() - boolean 停止
pauseVideo() - boolean 暂停
resumeVideo() - boolean 恢复
switchStream(quality) main / sub / low / super boolean 码流切换(多用于预览)
seekPlayback(timeMillis) number boolean 回放拖动到指定时间(毫秒)
setPlaybackSpeed(speed) number boolean 倍速,约 0.125 ~ 32
getPlaybackSpeed() - number 当前倍速
playFile(path) string boolean 播放本地录像文件

抓图 / 录像 / 声音 / 对讲

方法 参数 返回 说明
takeSnapshot(path, name) 目录, 文件名 boolean 抓图
startRecord(path, convert) 路径, 是否转码 MP4 boolean 开始录像
stopRecord() - boolean 停止录像
setSoundEnabled(enabled) boolean boolean 声音开关
startVoiceTalk(url, header) 对讲 URL, header 或 null boolean 开始对讲
stopVoiceTalk() - boolean 停止对讲

鱼眼 / 电子放大 / 全屏

方法 参数 返回 说明
setFishEyeEnabled(enabled) boolean boolean 鱼眼开关
setFishEyeMode(correctType, placeType) number, number boolean 展开模式,见下方枚举
handleFishEyeCorrect(down, x1, y1, x2, y2) boolean + 4 个 number boolean 鱼眼手势校正(归一化坐标)
setOriginalFECParam(cx, cy, rx, ry) number×4 number 鱼眼 FEC 参数(iOS 不支持,返回 -1)
openDigitalZoom(srcL, srcT, srcR, srcB, dstL, dstT, dstR, dstB) number×8 boolean 电子放大
closeDigitalZoom() - boolean 关闭电子放大
enterFullscreen() - boolean 进入全屏
exitFullscreen() - boolean 退出全屏
isFullscreen() - boolean 是否全屏

时间 / 帧率 / 解码

方法 参数 返回 说明
getPlayedTime() - number 已播放时长(毫秒)
getTotalTime() - number 总时长(毫秒)
getOSDTime() - number OSD 时间(毫秒)
setCurrentFrame(progress) 0~100 number 单帧定位,返回结果码
getFrameRate() - number 当前帧率
setDecodeThreadNum(num) number number 解码线程数,返回结果码
setExpectedFrameRate(rate) number number 期望帧率,返回结果码
setPrivateFatio(ratio) number number 私有画面比例(iOS 不支持,返回 -1)

鱼眼枚举

correctType

含义
0 PTZ
1 180°
2 360°
3 左右
4 半球
5 圆柱
6 平铺
7 圆柱拼接

placeType

含义
0
1 墙面
2 地面
3 顶面

调用示例

const p = playerRef.value
if (!p) return

p.playVideo()
p.switchStream('sub')
p.setSoundEnabled(true)
p.takeSnapshot(saveDir, `snap_${Date.now()}.jpg`)
p.startRecord(`${saveDir}record_${Date.now()}.mp4`, true)
p.enterFullscreen()

iOS 上部分「有返回值」的 ref 方法可能拿不到同步返回值(表现为 undefined),但方法本身一般会执行。以 @event 回调为准更稳妥。


六、事件(@event)

统一走一个事件名:@event="handleEvent"。业务字段在 payload 里,关键字段是 event

nvue 解析建议:

const detail = payload?.detail?.dynamicJSONFields
  ?? payload?.detail
  ?? payload
  ?? {}
const event = detail.event || ''
event 主要字段 说明
componentReady timestamp 组件初始化完成
sourceSet url 已设置取流地址
playStatusChanged state, errorCode, firstFrameMs? 播放状态变化;首次 playing 时可能带首帧耗时
playbackTimeUpdate osdTime, playedTime, totalTime 进度(约每秒一次,单位毫秒)
streamChanged quality, ret 码流切换结果
playbackSpeedChanged speed, success 倍速设置结果
snapshotTaken path 抓图成功
recordingStarted path 录像开始
recordingStopped code 录像停止
recordTime time 录像时长(秒)
soundChanged enabled, ret 声音开关结果
voiceTalkStatus success, errorCode 对讲状态
fishEyeChanged enabled / correctType / placeType, ret 鱼眼变化
fullscreenChanged fullscreen 全屏状态变化
debugLog message, 以及各类耗时字段 插件诊断日志
error action, message, errorCode / code 错误

playStatusChanged.state

state 含义
idle 空闲
loading 取流 / 加载中
playing 播放中(通常表示已出画)
paused 暂停
stopped 已停止
finished 播放结束
failed 失败,可看 errorCode

debugLog 常见耗时字段(便于排查首帧慢)

字段 含义
setDataSourceMs 设置数据源耗时
setPlayConfigMs 设置播放配置耗时
setVideoWindowMs 绑定渲染窗口耗时(iOS)
startMs 调用 start 耗时
submitTotalMs 本地提交 SDK 总耗时
firstFrameMs 从 start 提交到 SUCCESS 的耗时(接近「等流 + 解码出画」)

submitTotalMs 很小、firstFrameMs 很大,瓶颈多半在网络 / 平台取流,而不是本地 API 调用。


七、Android 与 iOS 差异

前端方法名一致,内部做了适配。需要知道的差异:

项目 Android iOS
渲染 TextureView + SurfaceTexture setVideoWindow(UIView)
playBuffer 毫秒缓冲 忽略
bufferLength 无此前端映射 字节缓冲
setOriginalFECParam 支持 不支持,返回 -1
setPrivateFatio 支持 不支持,返回 -1
handleFishEyeCorrect (down, x1, y1, x2, y2) 近似映射为 SDK 的点/缩放参数
setExpectedFrameRate / setDecodeThreadNum 返回 int SDK 返回 BOOL,插件转成 0 / -1
getPlaybackSpeed float int,对外仍是 number
回放时间字符串 ISO8601(带时区) yyyy-MM-dd'T'HH:mm:ss.SSSxxx
metallib 资源 不需要 必须打包,否则首帧可能闪退

八、常见问题

1. 黑屏 / 一直 loading

  • 确认自定义基座已安装,且是最新打的。
  • 确认 src 有效;预览/回放 URL 是否过期(openUrl 临时码常有时效)。
  • 回放模式是否传了正确的 playbackTime.start / end
  • header 里的 token 是否有效;不要误传干扰鉴权的字段。

2. iOS 播放一会儿闪退

优先检查 App 包内是否有:

com.hri.hpc.mobile.ios.player.metallib

该文件应来自插件目录:

uni_modules/hl-hik-player/utssdk/app-ios/Resources/

缺失时,SDK 在 Metal 渲染初始化阶段会断言崩溃。

3. 事件来了但 detail 是空对象

iOS 侧事件必须用 UTSJSONObject$emit。当前插件已按此实现。若仍为空,多半是旧基座,请重打自定义基座。

解析时请使用:

payload.detail.dynamicJSONFields ?? payload.detail ?? payload

4. Android 加载 so 失败

确认自定义基座,且 ABI 只有 armeabi-v7aarm64-v8a

5. 对讲无声

确认已授予录音权限,设备扬声器已开,对讲 URL 正确。

6. 首帧很慢(例如接近 10 秒)

可尝试:

  • qualityType: 1(子码流)
  • privateData: false
  • iOS 适当减小 bufferLength(如 1 * 1024 * 1024),观察是否花屏/卡顿再回调

隐私、权限声明

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

网络、录音、存储、媒体读写

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

插件不采集任何数据

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

暂无用户评论。