更新记录
1.4.1(2026-08-25)
修复:
- 修复部分 iOS 云打包环境生成 Swift 时出现
value of optional type 'String?' must be unwrapped to a value of type 'String'的问题。 - iOS 入口对 RTSP 地址、覆盖层 JSON、截图路径、录像目录和原生状态字符串增加非空兜底,兼容旧版/云端 UTS Swift 生成器。
1.4.0(2026-08-17)
新增:
- 新增 Android 截图 API
takePlayerSnapshot(path, width, height),支持保存 PNG/JPEG 文件。 - 新增 Android 录像 API
startPlayerRecord(directory)、stopPlayerRecord()、isPlayerRecording()。 - 新增
examples/snapshot-record-demo.vue,演示认证 RTSP 地址、稳定参数、截图和录像。
优化:
- 文档补充
rtsp://user:password@host:port/path认证地址说明。 - 文档补充海康/大华子码流不稳定时的 TCP、缓存和重连参数建议。
注意事项:
- Android 录像传入保存目录,实际文件名由底层播放器生成。
- Android 截图/叠加层场景建议使用
renderMode: 'texture'。 - iOS 和 HarmonyOS NEXT 截图/录像能力当前未完成实机验证,API 会返回不支持说明。
1.0(2026-07-13)
更新记录文案
1.0.0(2026-07-13)
- 首次发布 Android/iOS 市场版。
- Android 集成 LibVLC 3.6.5。
- iOS 集成 MobileVLCKit 3.7.3。
- 支持 uni-app Vue2、Vue3。
- 支持 RTSP TCP/UDP、软硬件解码、静音控制。
- 支持连接/缓冲超时检测和自动重连。
- 提供 Vue 组件和 UTS API 两种调用方式。
- 当前版本暂不包含 HarmonyOS NEXT。
平台兼容性
uni-app(5.13)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | - | √ | 1.4.0 | √ | 1.4.0 | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.13)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
shunlu-rtspplayer 1.4.1
顺鹿原生 RTSP 播放器是一个面向 uni-app App 端的 UTS 插件,用于播放局域网或公网 RTSP 实时视频流。适合摄像头预览、车载设备、行车记录仪、安防监控、工业相机、无人机/机器人图传等场景。
平台支持
| 平台 | 状态 | 说明 |
|---|---|---|
| Android App | 支持 | 基于 LibVLC,推荐自定义基座或云打包验证 |
| iOS App | 支持 | 基于 MobileVLCKit 3.7.3,支持 arm64 |
| HarmonyOS NEXT | 预览 | 已提供预览实现,当前市场版未完成实机发布验证 |
| H5 / 小程序 | 不支持 | 浏览器和小程序环境不能直接播放 RTSP |
核心能力
- RTSP TCP/UDP 切换
- 软解/硬解切换
- 播放、暂停、停止、重试、切换地址、销毁
- 静音控制
- 坐标式挂载和位置同步,适用于 Android/iOS
- HarmonyOS NEXT 原生组件预览实现
- Android/iOS 原生 overlay 绘制,支持矩形、线段、多边形和文字
- 连接/缓冲超时检测
- 自动重连、指数退避、最大重试次数限制
- 状态查询和失败提示
- 目标显示帧率参数
targetFrameRate
安装
将 uni_modules/shunlu-rtspplayer 整体复制到项目的 uni_modules 目录中。
推荐同时复制 examples/common-rtsp-player.js 到项目的 common/rtsp-player.js,业务页统一通过该封装调用,便于处理 H5/小程序编译降级。
Android/iOS 快速开始
import { rtspPlayer } from '@/common/rtsp-player'
const result = rtspPlayer.mount({
url: 'rtsp://192.168.1.100/live',
rect: { x: 0, y: 100, width: 375, height: 220 },
autoplay: true,
muted: true,
networkCaching: 1800,
rtspTcp: true,
hardwareDecode: true,
autoReconnect: true,
bufferingTimeout: 10000,
maxReconnectAttempts: 3,
reconnectDelay: 1200,
targetFrameRate: 60,
alwaysOnTop: true,
renderMode: 'surface'
})
完整页面示例见:
examples/basic-app-vue.vueexamples/reconnect-demo.vueexamples/overlay-workaround.vueexamples/snapshot-record-demo.vueexamples/market-screenshot-demo.vue
认证 RTSP 地址
插件支持标准的 RTSP 账号密码地址,例如:
rtsp://user:password@192.168.3.15:554/h264/ch1/sub/av_stream
如果账号或密码里包含 @、#、?、&、/、空格、% 等 URL 特殊字符,需要先对账号密码部分做 URL 编码。普通字母、数字以及类似 PKSPBxx 这样的密码可以直接传入。
海康、大华等设备的子码流如果出现“一直提示不稳定、重连”,优先尝试:
{
rtspTcp: true,
networkCaching: 2500,
bufferingTimeout: 15000,
maxReconnectAttempts: 5,
reconnectDelay: 1200
}
如果设备明确只开放 UDP 或 TCP 多次失败,再把 rtspTcp 改为 false 验证;如果出现绿屏、花屏或固定区域异常,再把 hardwareDecode 改为 false 验证。
HarmonyOS NEXT 快速开始
HarmonyOS NEXT 端请使用 Vue3 原生组件,不支持 Android/iOS 的 mountPlayer({ rect }) 坐标式 API。
<sl-rtsp-player
ref="rtspPlayer"
class="player"
:src="rtspUrl"
:autoplay="true"
:muted="true"
:network-caching="1800"
:rtsp-tcp="true"
:hardware-decode="true"
:auto-reconnect="true"
:buffering-timeout="10000"
:max-reconnect-attempts="3"
:reconnect-delay="1200"
:target-frame-rate="60"
:visible="pageVisible"
@statechange="onStateChange"
@reconnecting="onReconnecting"
@reconnectfailed="onReconnectFailed"
@error="onError"
/>
更多说明见 HARMONY_NEXT.md。
API
mountPlayer(options)
Android/iOS 坐标式挂载播放器。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url |
string | 必填 | RTSP 地址 |
rect |
object | 必填 | { x, y, width, height },单位为页面 px |
autoplay |
boolean | true |
挂载后是否自动播放 |
muted |
boolean | true |
是否静音 |
networkCaching |
number | 1800 |
缓存时长,内部限制 500-5000 ms |
rtspTcp |
boolean | true |
是否使用 TCP;传 false 使用 UDP |
hardwareDecode |
boolean | true |
是否启用硬件解码 |
autoReconnect |
boolean | true |
是否启用自动重连 |
bufferingTimeout |
number | 10000 |
opening/buffering/reconnecting 最大持续时间 |
maxReconnectAttempts |
number | 3 |
最大自动重连次数,内部限制 0-8 |
reconnectDelay |
number | 1200 |
首次重连等待时间 |
targetFrameRate |
number | 60 |
目标显示帧率;不能把 30 FPS 源变成真实 60 FPS |
alwaysOnTop |
boolean | true |
是否主动把播放器置于页面顶层 |
renderMode |
'surface' \| 'texture' |
'surface' |
Android 渲染模式。texture 更适合覆盖层 |
其他方法
| 方法 | 说明 |
|---|---|
setPlayerRect(rect) |
更新播放器位置和大小 |
setPlayerVisible(visible) |
显示/隐藏播放器 |
setPlayerUrl(url, autoplay) |
切换 RTSP 地址 |
playPlayer() |
播放 |
pausePlayer() |
暂停 |
stopPlayer() |
停止 |
retryPlayer() |
清空失败次数并立即重连 |
destroyPlayer() |
销毁播放器 |
setPlayerMuted(muted) |
设置静音 |
getPlayerState() |
获取状态字符串 |
getPlayerUrl() |
获取当前地址 |
getPlayerStatus() |
获取状态、文案、缓冲百分比、重连次数 |
setPlayerOverlay(items) |
Android/iOS 绘制原生覆盖层 |
clearPlayerOverlay() |
清空原生覆盖层 |
takePlayerSnapshot(path, width, height) |
Android 截图保存到指定文件,width/height 可传 0 使用原始视图尺寸 |
startPlayerRecord(directory) |
Android 开始录像,传入保存目录,文件名由底层播放器生成 |
stopPlayerRecord() |
Android 停止录像 |
isPlayerRecording() |
查询 Android 当前是否正在录像 |
isSupported() |
判断当前平台是否支持 |
setPlayerOverlay(items)
Android/iOS 支持原生 overlay 绘制。推荐在 Android 使用 overlay 时把 renderMode 设置为 'texture',这样视频和绘制层更容易参与同一层级合成。
rtspPlayer.setOverlay([
{
type: 'rect',
rect: { x: 60, y: 50, width: 150, height: 100 },
color: '#00E676',
lineWidth: 2
},
{
type: 'line',
points: [
{ x: 30, y: 220 },
{ x: 345, y: 220 }
],
color: '#40A9FF',
lineWidth: 2
},
{
type: 'text',
points: [{ x: 24, y: 30 }],
text: '实时检测中',
color: '#FFFFFF',
fontSize: 14
}
])
坐标以播放器内部左上角为原点,单位与页面传入的 rect 保持一致。
截图和录像
当前版本提供 Android App 端截图和录像 API。截图传入完整文件路径;录像传入保存目录,实际录像文件名由底层 LibVLC 生成。
// #ifdef APP-PLUS
const snapshotPath = plus.io.convertLocalFileSystemURL('_doc/rtsp-snapshot-' + Date.now() + '.png')
const snapshotResult = rtspPlayer.snapshot(snapshotPath)
const recordDirectory = plus.io.convertLocalFileSystemURL('_doc')
const startResult = rtspPlayer.startRecord(recordDirectory)
// 需要停止录像时调用
const stopResult = rtspPlayer.stopRecord()
// #endif
建议 Android 截图/叠加层场景挂载时设置 renderMode: 'texture'。如果当前 LibVLC 环境无法直接截图,插件会使用 TextureView 画面兜底;默认 surface 模式下可能返回“当前渲染模式无法直接截图”。
iOS 和 HarmonyOS NEXT 的截图/录像能力当前未完成实机验证,相关 API 会返回 success: false 和明确说明,不会虚假标记为已保存。
状态值
| 状态 | 说明 |
|---|---|
idle |
未启动或已销毁 |
mounting |
正在初始化原生播放器 |
opening |
正在打开 RTSP 地址 |
buffering |
正在等待视频数据 |
playing |
正常播放 |
paused |
已暂停 |
stopped |
已停止 |
hidden |
页面隐藏或主动隐藏播放器 |
reconnecting |
正在自动重连 |
reconnect_failed |
自动重连次数已用完 |
error |
初始化或播放异常 |
unsupported |
当前平台不支持 |
自动重连策略
默认策略:
- 连接或缓冲持续超过
bufferingTimeout后主动重建连接。 - 默认最多自动重连 3 次。
- 重连延时采用指数退避,默认约 1.2 秒、2.4 秒、4.8 秒。
- 稳定播放 15 秒后清零历史重连次数。
- 页面隐藏、用户主动暂停或停止时不自动重连。
- 连续失败后进入
reconnect_failed,页面应提示用户检查设备 Wi-Fi、摄像头电源或重启设备。
完整处理方式见 RECONNECT_DESIGN.md。
原生层级说明
当前 Android/iOS 坐标式播放器会创建原生视频层,并默认把它放到页面内容之上以避免被普通布局遮挡。因此普通 Vue 弹窗、自定义 View、部分 subNVue 场景可能无法稳定覆盖在视频上方。
当前版本建议:
- 显示业务弹窗、扫码层、表单层前,先调用
setPlayerVisible(false)。 - 弹窗关闭后再调用
setPlayerVisible(true)并同步setPlayerRect(rect)。 - 如果必须长期在视频上绘制框、线、文字、水印,优先使用
setPlayerOverlay()。 - 如果希望业务自己控制页面层级,可以在挂载时设置
alwaysOnTop: false。 - Android 覆盖层场景推荐设置
renderMode: 'texture'。
稳定性建议
推荐默认参数:
{
networkCaching: 1800,
rtspTcp: true,
hardwareDecode: true,
autoReconnect: true,
bufferingTimeout: 10000,
maxReconnectAttempts: 3,
reconnectDelay: 1200
}
个别设备硬件解码出现绿屏、花屏、固定区域异常时,将 hardwareDecode 改为 false 验证。RTSP 源若标注 UDP,TCP 多次失败后可尝试 rtspTcp: false。
Android 编译说明
Android 端依赖 org.videolan.android:libvlc-all:3.6.5。该依赖不在普通标准基座中,首次真机运行建议使用自定义基座或云打包。
如果直接使用普通标准基座,出现 找不到名称 videolan / LibVLC,通常不是源码语法错误,而是三方 AAR 没有进入 Android 编译 classpath。
iOS 编译说明
iOS 端依赖 MobileVLCKit 3.7.3,最低部署版本 iOS 12.0,仅声明 arm64 架构。局域网 RTSP 场景请根据业务项目补充本地网络说明和 ATS 配置。
第三方许可证
Android 依赖 LibVLC,iOS 依赖 MobileVLCKit,HarmonyOS NEXT 依赖 @ohos/ijkplayer。这些依赖涉及 VLC/IJKPlayer/FFmpeg 相关开源协议。商业发布前请阅读 LICENSE-THIRD-PARTY.md 并评估 LGPL/GPL 合规要求。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 46
赞赏 0
下载 12538576
赞赏 1947
赞赏
京公网安备:11010802035340号