大牛直播SDK(SmartMediaKit)鸿蒙NEXT RTSP/RTMP低延迟播放器集成与实践指南
本文基于大牛直播SDK(SmartMediaKit)鸿蒙NEXT播放端Demo,系统介绍RTSP/RTMP低延迟播放器的工程集成方法,涵盖ArkTS与NAPI接口声明、XComponent Surface渲染绑定、RTSP/RTMP播放参数配置、低延迟播放、缓冲控制、硬解配置、实时录像、快照、画面控制、事件回调、生命周期与Surface恢复等关键环节。适合鸿蒙NEXT音视频应用、无纸化会议、安防监
一、文档概述
本文介绍如何在 HarmonyOS NEXT 工程中集成 大牛直播SDK(SmartMediaKit)RTSP/RTMP直播播放模块,实现 RTSP、RTMP 实时直播播放(延迟低至100~200ms)、低延迟渲染、实时录像、快照、事件回调、画面控制、下载速度统计、分辨率回调等能力。
本文基于大牛直播SDK鸿蒙NEXT播放端 Demo 工程进行说明,重点覆盖以下内容:
- APP 名称与包名修改;
libSmartPlayer.so动态库拷贝;- ArkTS 调用 Native so 的依赖配置;
- XComponent 渲染 Surface 绑定;
- RTSP/RTMP 播放参数配置;
- 播放端录像与快照集成;
- 播放事件回调处理;
- 页面重建、锁屏恢复、Surface 重绑等生命周期处理;
- 常见问题与排查建议。
二、适用场景
大牛直播SDK鸿蒙NEXT播放器模块适用于以下典型场景:
| 场景 | 说明 |
|---|---|
| 安防监控 | 拉取 IPC/NVR/边缘网关输出的 RTSP 流,进行低延迟预览、录像和快照 |
| 无纸化会议 | 播放会议终端、同屏设备或推流端输出的 RTMP/RTSP 实时视频 |
| 移动执法 | 播放现场终端、布控球、执法设备上传的视频流 |
| 工业巡检 | 播放机器人、无人机、巡检终端输出的实时画面 |
| 远程医疗 | 播放远端诊疗设备、手术示教、会诊终端的视频流 |
| 应急指挥 | 播放前端移动设备、专网设备、现场采集终端的视频流 |
| AI视觉分析 | 通过视频帧回调或 SEI 回调对接算法模块 |
三、功能特性
大牛直播SDK鸿蒙NEXT播放器模块主要支持以下能力:
| 能力分类 | 功能说明 |
|---|---|
| 协议支持 | RTSP、RTMP 实时直播播放 |
| 解码能力 | H.264、H.265 软解/硬解配置 |
| 渲染能力 | 基于 XComponent Surface 进行原生渲染 |
| 低延迟能力 | 支持低延迟模式、缓冲时间设置、快速启动 |
| RTSP控制 | 支持 TCP/UDP 模式、TCP/UDP 自动切换、RTSP 鉴权、超时设置 |
| RTMP播放 | 支持 RTMP H.264、RTMP H.265 扩展流(Enhanced RTMP)播放 |
| 录像能力 | 播放端实时录像,支持录像目录、文件大小、音视频开关配置 |
| 快照能力 | 支持 JPEG/PNG 快照,可保存至沙盒目录或系统图库 |
| 状态回调 | 支持连接状态、播放状态、分辨率、下载速度、缓冲状态、录像文件、快照结果回调 |
| 画面控制 | 支持等比/铺满显示、旋转、水平翻转、垂直翻转、亮度、对比度、饱和度调节 |
| 扩展能力 | 支持视频帧回调、H.264 SEI 数据回调等二次开发能力 |
四、工程结构说明

示例工程主要目录结构如下:
SmartPlayerOhos/
├── AppScope/
│ ├── app.json5
│ └── resources/base/element/string.json
│
├── entry/
│ ├── libs/
│ │ ├── arm64-v8a/
│ │ │ └── libSmartPlayer.so
│ │ └── x86_64/
│ │ └── libSmartPlayer.so
│ │
│ ├── oh-package.json5
│ │
│ └── src/main/
│ ├── cpp/types/libSmartPlayer/
│ │ ├── index.d.ts
│ │ └── oh-package.json5
│ │
│ ├── ets/
│ │ ├── config/
│ │ │ └── PlayerConfig.ets
│ │ │
│ │ ├── entryability/
│ │ │ └── EntryAbility.ets
│ │ │
│ │ ├── media/
│ │ │ ├── NTLicenseHelper.ets
│ │ │ ├── SmartPlayerNative.ets
│ │ │ ├── SmartPlayerWrapper.ets
│ │ │ ├── SmartPlayerTypes.ets
│ │ │ ├── SmartPlayerBridge.ets
│ │ │ ├── PlayerRecorderHelper.ets
│ │ │ ├── PlayerSnapshotHelper.ets
│ │ │ └── SoftRenderer.ets
│ │ │
│ │ └── pages/
│ │ ├── SmartPlayerPage.ets
│ │ ├── RecorderManagerPage.ets
│ │ └── RecorderPlaybackPage.ets
│ │
│ ├── module.json5
│ └── resources/base/profile/main_pages.json
核心文件说明如下:
| 文件 | 说明 |
|---|---|
SmartPlayerPage.ets |
播放器主页面,负责 UI、XComponent、播放控制、状态展示 |
SmartPlayerWrapper.ets |
播放器实例封装层,管理 open、start、stop、录像、快照、事件等状态 |
SmartPlayerNative.ets |
ArkTS Native 封装层,统一调用 libSmartPlayer.so 导出的 NAPI 接口 |
SmartPlayerTypes.ets |
播放器事件、枚举、结果码、配置类型定义 |
PlayerRecorderHelper.ets |
播放端录像辅助类,封装录像目录、参数下发、启动/停止录像 |
PlayerSnapshotHelper.ets |
快照辅助类,封装快照路径生成、截图请求、图库保存 |
RecorderManagerPage.ets |
录像文件管理页面 |
RecorderPlaybackPage.ets |
本地录像文件回放页面 |
index.d.ts |
libSmartPlayer.so 的 ArkTS 类型声明文件 |
entry/libs/ |
存放 native 动态库目录 |
五、集成流程概览
鸿蒙NEXT播放器模块的集成流程如下:
1. 修改 APP 名称与 bundleName
2. 拷贝 libSmartPlayer.so 到 entry/libs/ 指定 ABI 目录
3. 配置 entry/oh-package.json5 中的 native 依赖
4. 检查 index.d.ts 接口声明
5. 配置 module.json5 网络权限
6. 在页面中创建 XComponent
7. 获取 XComponent SurfaceId
8. 调用 SmartPlayerOpen() 创建播放器实例
9. 绑定事件回调
10. 调用 SmartPlayerSetSurface() 绑定渲染窗口
11. 设置 RTSP/RTMP 播放地址和播放参数
12. 调用 SmartPlayerStartPlayback() 启动播放
13. 按需接入录像、快照、画面控制和数据回调
六、修改 APP 名称
6.1 修改应用显示名称
应用桌面显示名称通常在以下文件中配置:
AppScope/resources/base/element/string.json
默认示例:
{
"string": [
{
"name": "app_name",
"value": "SmartPlayer"
}
]
}
如果希望修改为“大牛播放器Demo”,可调整为:
{
"string": [
{
"name": "app_name",
"value": "大牛播放器Demo"
}
]
}
6.2 修改 bundleName
应用包名在以下文件中配置:
AppScope/app.json5
示例:
{
"app": {
"bundleName": "com.smartplayer.demo",
"vendor": "SmartPlayer",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}
正式项目中建议修改为业务自己的包名,例如:
"bundleName": "com.company.smartplayer"
6.3 授权信息注意事项
大牛直播SDK授权校验可能与以下信息相关:
- APP 名称;
- bundleName;
- appIdentifier;
- 签名指纹;
- 授权文件或授权字符串。
示例工程中通过 NTLicenseHelper.ets 获取运行时应用信息,并传递给 native SDK。修改 APP 名称、包名或签名证书后,应确保授权信息与实际应用一致。
七、拷贝 libSmartPlayer.so
7.1 so 库目录
示例工程已预留 native so 目录:
entry/libs/
├── arm64-v8a/
└── x86_64/
真机运行时,通常使用:
entry/libs/arm64-v8a/libSmartPlayer.so
如果需要模拟器调试,可放置:
entry/libs/x86_64/libSmartPlayer.so
7.2 依赖声明
在 entry/oh-package.json5 中声明 native so 依赖:
{
"modelVersion": "5.0.0",
"name": "entry",
"version": "1.0.0",
"description": "SmartPlayer Demo Entry Module",
"dependencies": {
"libSmartPlayer.so": "file:./src/main/cpp/types/libSmartPlayer"
}
}
7.3 类型声明目录
类型声明文件位于:
entry/src/main/cpp/types/libSmartPlayer/index.d.ts
ArkTS 层通过如下方式导入 native 模块:
import smartplayer from 'libSmartPlayer.so';
7.4 常见检查项
如果编译或运行时提示无法找到 native 模块,请检查:
| 检查项 | 说明 |
|---|---|
| so 文件是否存在 | 确认 entry/libs/arm64-v8a/libSmartPlayer.so 已放置 |
| ABI 是否匹配 | 真机一般使用 arm64-v8a |
| 依赖是否声明 | 检查 entry/oh-package.json5 |
| 类型声明是否存在 | 检查 index.d.ts |
| 接口是否一致 | index.d.ts 中接口需与 so 导出接口一致 |
| 是否重新构建 | 建议 Clean/Rebuild 工程 |
八、配置应用权限
播放端主要依赖网络权限。module.json5 示例配置如下:
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"deviceTypes": ["phone", "tablet"],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"label": "$string:app_name",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true
}
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
}
]
}
}
权限说明:
| 权限 | 用途 |
|---|---|
ohos.permission.INTERNET |
用于 RTSP、RTMP 网络拉流 |
ohos.permission.GET_NETWORK_INFO |
用于网络状态检测、网络相关辅助逻辑 |
如果快照仅保存到应用沙盒目录,通常无需额外图库权限。
如果需要保存到系统图库,建议通过鸿蒙NEXT推荐的图库授权流程实现,由用户确认保存行为。
九、核心接口说明
9.1 播放器生命周期接口
export function SmartPlayerOpen(): number;
export function SmartPlayerClose(handle: number): number;
说明:
| 接口 | 说明 |
|---|---|
SmartPlayerOpen() |
创建播放器实例,返回播放器句柄 |
SmartPlayerClose(handle) |
释放播放器实例 |
SmartPlayerOpen() 返回值大于 0 表示打开成功。
9.2 事件回调接口
export function SetSmartPlayerEventCallback(
handle: number,
callback: SmartPlayerEventCallback
): number;
用于接收播放器状态事件,包括连接状态、播放状态、分辨率、下载速度、缓冲、录像、快照等。
9.3 渲染窗口绑定接口
export function SmartPlayerSetSurface(
handle: number,
surfaceId: string
): number;
鸿蒙NEXT下通常通过 XComponent 创建渲染 Surface,并将 surfaceId 传递给播放器。
9.4 播放控制接口
export function SmartPlayerSetUrl(handle: number, url: string): number;
export function SmartPlayerStartPlayback(handle: number): number;
export function SmartPlayerStopPlayback(handle: number): number;
export function SmartPlayerSwitchPlaybackUrl(handle: number, url: string): number;
接口说明:
| 接口 | 说明 |
|---|---|
SmartPlayerSetUrl() |
设置 RTSP/RTMP 播放地址 |
SmartPlayerStartPlayback() |
启动播放 |
SmartPlayerStopPlayback() |
停止播放 |
SmartPlayerSwitchPlaybackUrl() |
快速切换播放地址 |
建议保持“设置 URL”和“开始播放”分离,便于在启动前统一配置播放参数。
9.5 RTSP 参数接口
export function SmartPlayerSetRTSPTcpMode(
handle: number,
isTcp: number
): number;
export function SmartPlayerSetRTSPAutoSwitchTcpUdp(
handle: number,
isAutoSwitch: number
): number;
export function SmartPlayerSetRTSPAuthenticationInfo(
handle: number,
userName: string,
password: string
): number;
export function SmartPlayerSetRTSPTimeout(
handle: number,
timeoutSec: number
): number;
接口说明:
| 接口 | 说明 |
|---|---|
SmartPlayerSetRTSPTcpMode() |
设置 RTSP TCP/UDP 模式 |
SmartPlayerSetRTSPAutoSwitchTcpUdp() |
设置 RTSP TCP/UDP 自动切换 |
SmartPlayerSetRTSPAuthenticationInfo() |
设置 RTSP 鉴权用户名和密码 |
SmartPlayerSetRTSPTimeout() |
设置 RTSP 连接超时时间 |
9.6 低延迟与缓冲接口
export function SmartPlayerSetBuffer(
handle: number,
bufferMs: number
): number;
export function SmartPlayerSetLowLatencyMode(
handle: number,
isLowLatency: number
): number;
export function SmartPlayerSetFastStartup(
handle: number,
isFastStartup: number
): number;
export function SmartPlayerSetReportDownloadSpeed(
handle: number,
isReport: number,
intervalSec: number
): number;
接口说明:
| 接口 | 说明 |
|---|---|
SmartPlayerSetBuffer() |
设置播放缓冲时间 |
SmartPlayerSetLowLatencyMode() |
设置低延迟播放模式 |
SmartPlayerSetFastStartup() |
设置快速启动模式 |
SmartPlayerSetReportDownloadSpeed() |
设置下载速度上报 |
9.7 录像接口
export function SmartPlayerCreateFileDirectory(path: string): number;
export function SmartPlayerSetRecorderDirectory(
handle: number,
path: string
): number;
export function SmartPlayerSetRecorderFileMaxSize(
handle: number,
sizeMB: number
): number;
export function SmartPlayerSetRecorderAudioTranscodeAAC(
handle: number,
enable: number
): number;
export function SmartPlayerSetRecorderVideo(
handle: number,
enable: number
): number;
export function SmartPlayerSetRecorderAudio(
handle: number,
enable: number
): number;
export function SmartPlayerStartRecorder(handle: number): number;
export function SmartPlayerStopRecorder(handle: number): number;
9.8 快照接口
export function SmartPlayerSaveImageFlag(
handle: number,
isSave: number
): number;
export function SmartPlayerSaveCurImage(
handle: number,
imagePath: string
): number;
export function SmartPlayerCaptureImage(
handle: number,
compressFormat: number,
quality: number,
fileName: string,
userData: string
): number;
参数说明:
| 参数 | 说明 |
|---|---|
compressFormat |
图片格式,例如 JPEG/PNG |
quality |
图片质量,建议范围 1–100 |
fileName |
图片保存路径 |
userData |
业务自定义透传字段 |
十、播放器集成实现
10.1 创建 XComponent
页面中创建 XComponent,用于承载播放器画面:
XComponent({
id: 'player_xcomponent',
type: XComponentType.SURFACE,
controller: this.xComponentController
})
.onLoad(() => {
this.surfaceId = this.xComponentController.getXComponentSurfaceId();
this.tryRecoverAfterSurfaceReady('XComponent onLoad');
})
.onDestroy(() => {
this.surfaceId = '';
})
10.2 获取 SurfaceId
this.surfaceId = this.xComponentController.getXComponentSurfaceId();
10.3 打开播放器实例
if (!this.player.isOpened()) {
const openRet = this.player.open();
if (!openRet) {
this.statusText = '打开失败';
return;
}
}
10.4 绑定事件回调
this.bindPlayerCallbacks();
10.5 绑定渲染 Surface
const bindRet = this.player.setSurface(this.surfaceId);
if (!bindRet) {
this.statusText = 'Surface绑定失败';
return;
}
10.6 设置播放参数
this.player.setUrl(this.playUrl);
this.player.setBuffer(this.bufferMs);
this.player.setLowLatencyMode(this.isLowLatency);
this.player.setFastStartup(this.isFastStartup);
this.player.setReportDownloadSpeed(true, 1);
RTSP 场景下可额外设置:
this.player.setRTSPTcpMode(this.isTcpMode);
this.player.setRTSPAutoSwitchTcpUdp(true);
this.player.setRTSPTimeout(10);
10.7 启动播放
const startRet = this.player.startPlayback();
if (startRet) {
this.statusText = '启动播放成功';
} else {
this.statusText = '启动播放失败';
}
十一、RTSP播放集成

11.1 RTSP URL 示例
rtsp://192.168.1.100:554/live/stream1
带鉴权的 URL 示例:
rtsp://user:password@192.168.1.100:554/live/stream1
也可以通过接口单独设置用户名和密码:
this.player.setRTSPAuthenticationInfo(userName, password);
11.2 TCP/UDP 模式选择
RTSP 支持 TCP 和 UDP 两种常见传输方式。
| 模式 | 特点 | 适用场景 |
|---|---|---|
| UDP | 延迟低,但弱网下可能丢包 | 局域网、专网、网络质量较好场景 |
| TCP | 稳定性更好,但延迟可能略高 | 公网、弱网、跨网段、丢包明显场景 |
设置 TCP 模式:
this.player.setRTSPTcpMode(true);
开启 TCP/UDP 自动切换:
this.player.setRTSPAutoSwitchTcpUdp(true);
11.3 RTSP 超时设置
this.player.setRTSPTimeout(10);
建议根据业务场景设置合理超时时间。超时时间过短可能导致弱网环境误判失败,过长则会增加故障感知时间。
十二、RTMP播放集成

12.1 RTMP URL 示例
rtmp://your-server/live/stream1
12.2 推荐参数
RTMP 低延迟播放场景建议配置:
this.player.setBuffer(0);
this.player.setLowLatencyMode(true);
this.player.setFastStartup(true);
this.player.setReportDownloadSpeed(true, 1);
实际参数可根据业务侧延迟、流畅性和网络情况进行调整。
12.3 RTMP播放注意事项
RTMP播放常见关注点包括:
- 推流端 GOP 是否过大;
- 服务器是否存在转发缓存;
- 播放端 buffer 是否设置过大;
- 网络链路是否稳定;
- 是否开启低延迟模式;
- 是否开启快速启动模式。
HarmonyOS鸿蒙NEXT下RTMP播放器时延测试
十三、播放端实时录像

13.1 功能说明
播放端录像用于在拉流播放过程中,将当前 RTSP/RTMP 流实时录制为本地文件。
典型应用场景:
- 安防监控取证;
- 移动执法留痕;
- 巡检过程记录;
- 远程会诊资料留档;
- 故障现场视频保存。
13.2 录像目录
示例工程默认录像目录为:
context.filesDir + "/smartplayer_record"
可在 PlayerRecorderHelper.ets 中统一管理。
13.3 录像参数配置
const recorderConfig: PlayerRecorderConfig = {
recorderDir: this.recordDir,
recorderFileMaxSizeMB: this.recordFileMaxSizeMB,
recorderAudioTranscodeAAC: this.recordAudioTranscodeAAC,
recorderVideoEnabled: this.recordVideoEnabled,
recorderAudioEnabled: this.recordAudioEnabled
};
13.4 启动录像
const result = this.recorderHelper.startRecorder(
this.player,
this.recordDir,
recorderConfig
);
if (result.ok) {
this.statusText = '录像已启动';
} else {
this.statusText = result.message;
}
底层调用流程:
SmartPlayerCreateFileDirectory()
SmartPlayerSetRecorderDirectory()
SmartPlayerSetRecorderFileMaxSize()
SmartPlayerSetRecorderAudioTranscodeAAC()
SmartPlayerSetRecorderVideo()
SmartPlayerSetRecorderAudio()
SmartPlayerStartRecorder()
13.5 停止录像
const result = this.recorderHelper.stopRecorder(this.player);
if (result.ok) {
this.statusText = '录像已停止';
} else {
this.statusText = result.message;
}
底层调用:
SmartPlayerStopRecorder(handle);
13.6 录像事件
录像相关事件包括:
| 事件 | 说明 |
|---|---|
RECORDER_START_NEW_FILE |
开始新的录像文件 |
RECORDER_FILE_FINISHED |
单个录像文件完成 |
建议在页面日志中输出完整录像文件路径,便于测试、定位和文件管理。
十四、播放端快照

14.1 功能说明
播放端快照用于在播放过程中抓取当前视频帧,并保存为图片文件。
典型应用场景:
- 监控画面截图;
- 现场取证;
- 异常画面留存;
- AI识别结果存档;
- 远程会诊关键画面保存。
14.2 快照路径生成
private buildImagePath(baseDir: string): string {
return `${baseDir}/snapshot_${this.buildTimestamp()}.png`;
}
14.3 发起快照
const ret = player.captureImage(
1,
100,
imagePath,
'snapshot'
);
参数说明:
| 参数 | 示例 | 说明 |
|---|---|---|
compressFormat |
1 |
图片格式,例如 PNG |
quality |
100 |
图片质量 |
imagePath |
/data/.../snapshot_xxx.png |
图片保存路径 |
userData |
snapshot |
业务透传字段 |
14.4 保存到图库
如果需要将快照保存到系统图库,可先将图片保存到应用沙盒目录,再通过系统图库授权流程保存到图库。
示例逻辑:
const phHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
const destUris = await phHelper.showAssetsCreationDialog(
srcUris,
creationConfigs
);
这种方式可以确保图库写入过程符合鸿蒙NEXT的系统授权机制。
十五、事件回调处理

15.1 事件类型
播放器事件定义在 SmartPlayerTypes.ets 中,常见事件如下:
| 事件 | 说明 |
|---|---|
CONNECTING |
正在连接 |
CONNECTED |
连接成功 |
STARTED |
播放启动 |
CONNECTION_FAILED |
连接失败 |
DISCONNECTED |
连接断开 |
STOP |
播放停止 |
RESOLUTION_INFO |
视频分辨率信息 |
DOWNLOAD_SPEED |
下载速度 |
START_BUFFERING |
开始缓冲 |
BUFFERING |
缓冲中 |
STOP_BUFFERING |
停止缓冲 |
CAPTURE_IMAGE |
快照结果 |
RECORDER_START_NEW_FILE |
开始新的录像文件 |
RECORDER_FILE_FINISHED |
单个录像文件完成 |
15.2 事件处理示例
private onPlayerEvent(
eventId: SmartPlayerEvent,
param1: number,
param2: number,
strParam: string
): void {
switch (eventId) {
case SmartPlayerEvent.CONNECTING:
this.statusText = '连接中...';
this.setLastEvent('CONNECTING');
break;
case SmartPlayerEvent.CONNECTED:
this.statusText = '已连接';
this.setLastEvent('CONNECTED');
break;
case SmartPlayerEvent.STARTED:
this.statusText = '播放中';
this.setLastEvent('STARTED');
break;
case SmartPlayerEvent.CONNECTION_FAILED:
this.statusText = '连接失败';
this.setLastEvent('CONNECTION_FAILED');
break;
case SmartPlayerEvent.RESOLUTION_INFO:
this.resolutionText = `${param1}x${param2}`;
break;
case SmartPlayerEvent.DOWNLOAD_SPEED:
this.speedText = `${param1} KB/s`;
break;
case SmartPlayerEvent.RECORDER_START_NEW_FILE:
this.setLastEvent(`开始新录像文件: ${strParam}`);
break;
case SmartPlayerEvent.RECORDER_FILE_FINISHED:
this.setLastEvent(`录像文件完成: ${strParam}`);
break;
case SmartPlayerEvent.CAPTURE_IMAGE:
this.setLastEvent(param1 === 0 ? `快照成功: ${strParam}` : `快照失败: ${strParam}`);
break;
}
}
15.3 事件处理建议
建议遵循以下原则:
- 事件回调中只做轻量级状态更新;
- 文件扫描、图库保存等耗时操作应放到异步逻辑中;
- 页面状态更新应集中封装,避免多处直接修改状态;
- 对录像、快照等文件路径建议完整输出,方便测试;
- 对连接失败、断开等事件建议保留最近错误信息。
十六、画面控制能力

播放器支持常见画面控制能力:
this.player.setRenderScaleMode(mode);
this.player.setRotateDegrees(degrees);
this.player.setFlipHorizontal(enable);
this.player.setFlipVertical(enable);
this.player.setVideoBrightness(value);
this.player.setVideoContrast(value);
this.player.setVideoSaturation(value);
常见配置建议:
| 功能 | 说明 | 适用场景 |
|---|---|---|
| 等比显示 | 保持原始宽高比 | 监控、医疗、工业画面 |
| 铺满显示 | 填满整个显示区域 | 大屏展示、全屏预览 |
| 水平翻转 | 左右镜像 | 前置镜像、特殊安装方向 |
| 垂直翻转 | 上下翻转 | 摄像头倒装 |
| 旋转角度 | 90/180/270 度旋转 | 竖屏流、设备安装角度异常 |
| 亮度调节 | 调整画面明暗 | 暗光环境 |
| 对比度调节 | 提升画面对比 | 弱纹理、低对比度画面 |
| 饱和度调节 | 调整色彩浓度 | 色彩偏淡或过饱和场景 |
十七、生命周期与Surface恢复

鸿蒙NEXT播放端需要重点处理 XComponent Surface 生命周期。
典型场景包括:
- 页面首次加载;
- 页面返回后重建;
- 全屏/非全屏切换;
- 锁屏恢复;
- 前后台切换;
- XComponent 销毁后重新创建。
17.1 推荐策略
推荐采用以下策略:
1. 播放器 Native 实例生命周期与页面 Surface 生命周期解耦
2. 页面重建时优先 attach 已存在的播放器实例
3. SurfaceId 变化后优先重新调用 SmartPlayerSetSurface()
4. 不要因为 XComponent 重建就立即 close 播放器
5. 只有播放、录像全部停止后,再释放播放器实例
十八、视频帧回调与SEI回调
18.1 视频帧回调
播放器可提供视频帧回调能力,用于 AI 分析或业务二次处理:
SmartPlayerSetVideoDataCallback(
handle,
callback: ((width: number, height: number, data: ArrayBuffer) => void) | null
): void;
适用场景:
- AI识别;
- 目标检测;
- 画面质量分析;
- 视频帧二次渲染;
- 业务截图分析。
18.2 SEI 数据回调
SmartPlayerSetSEIDataCallback(
handle,
callback: ((type: number, pts: number, data: ArrayBuffer) => void) | null
): number;
适用场景:
- 时间戳同步;
- 字幕信息;
- 告警信息;
- AI结果透传;
- 业务指令同步。
18.3 使用建议
视频帧和 SEI 回调属于高频或实时性较强的扩展能力,建议注意:
- 不要在回调中执行耗时操作;
- AI 分析建议引入丢帧策略;
- 页面销毁时及时清理回调;
- 对二进制数据解析需做好长度校验;
- 如需跨线程处理,应设计队列和背压机制。
十九、录像文件管理
示例工程提供录像管理demo页面:
RecorderManagerPage.ets
以及录像回放页面:
RecorderPlaybackPage.ets
打开录像管理页示例:
router.pushUrl({
url: 'pages/RecorderManagerPage',
params: {
recordDir: this.recordDir
}
});
产品化时可按需补充以下能力:
| 功能 | 说明 |
|---|---|
| 文件列表 | 展示当前录像目录下的 MP4 文件 |
| 文件大小 | 显示每个录像文件大小 |
| 文件时间 | 显示创建时间或修改时间 |
| 文件删除 | 支持删除指定录像文件 |
| 文件回放 | 点击录像文件进入本地播放 |
| 文件分享 | 按业务需要对接系统分享 |
| 空间管理 | 限制目录最大容量或文件数量 |
| 异常提示 | 磁盘空间不足时给出明确提示 |
二十、推荐集成架构
推荐业务侧采用以下分层方式:
SmartPlayerPage.ets
│
▼
SmartPlayerWrapper.ets
│
▼
SmartPlayerNative.ets
│
▼
libSmartPlayer.so
各层职责如下:
| 层级 | 职责 |
|---|---|
| 页面层 | UI 展示、用户操作、XComponent 生命周期、状态显示 |
| Wrapper 层 | 播放器实例管理、状态维护、播放/录像/快照封装 |
| Native 封装层 | ArkTS 到 NAPI 接口的薄封装 |
| Native SDK 层 | 解协议、解码、渲染、录像、快照、事件回调 |
这种分层方式的优势是:
- UI 逻辑清晰;
- native 接口边界明确;
- 播放状态可恢复;
- 录像和快照逻辑独立;
- 便于和 Android/iOS/Windows 等平台接口语义对齐;
- 便于后续扩展多实例播放、AI 分析、SEI 数据处理等能力。
二十一、常见问题
21.1 SmartPlayerOpen() 返回 0
请检查:
libSmartPlayer.so是否已放到entry/libs/arm64-v8a/;- ABI 是否与设备匹配;
entry/oh-package.json5是否声明依赖;index.d.ts是否存在;- APP 名称、bundleName、签名是否与授权匹配;
- 授权初始化逻辑是否正常执行。
21.2 编译时报找不到 libSmartPlayer.so
请检查:
"dependencies": {
"libSmartPlayer.so": "file:./src/main/cpp/types/libSmartPlayer"
}
以及:
entry/src/main/cpp/types/libSmartPlayer/index.d.ts
同时确认 DevEco Studio 已重新同步和构建工程。
21.3 有声音无画面
重点检查:
- XComponent 是否正常加载;
surfaceId是否为空;- 是否调用
SmartPlayerSetSurface(); - Surface 重建后是否重新绑定;
- 播放流是否包含视频;
- 当前硬解配置是否与设备兼容。
21.4 RTSP 播放失败
建议检查:
- RTSP URL 是否正确;
- 摄像头或服务端是否在线;
- 用户名密码是否正确;
- TCP/UDP 模式是否匹配;
- 是否需要开启 TCP 模式;
- 是否需要开启 TCP/UDP 自动切换;
- RTSP 超时时间是否合理;
- 手机与 RTSP 设备网络是否互通。
21.5 RTMP 播放延迟较大
建议检查:
- 播放端 buffer 是否设置过大;
- 是否开启低延迟模式;
- 是否开启快速启动模式;
- 推流端 GOP 是否过大;
- RTMP 服务器是否存在缓存;
- 网络链路是否稳定。
21.6 录像没有生成文件
建议检查:
- 是否创建录像目录;
- 是否设置录像目录;
- 是否开启录像视频或音频;
- 是否调用
SmartPlayerStartRecorder(); - 当前播放流是否有有效音视频数据;
- 是否收到
RECORDER_START_NEW_FILE事件。
21.7 快照失败
建议检查:
- 当前是否正在播放;
- 是否已有视频帧输出;
- 快照路径是否可写;
- 图片格式参数是否正确;
- 保存图库时用户是否取消授权;
- 是否收到
CAPTURE_IMAGE事件。
二十二、集成建议与最佳实践
22.1 播放流程建议
推荐流程:
open → setEventCallback → setSurface → setUrl → setConfig → startPlayback
不建议在未绑定 Surface 的情况下直接启动播放,避免出现有声音无画面或首帧渲染异常。
22.2 Surface 生命周期建议
建议将播放器实例生命周期和 XComponent Surface 生命周期解耦:
- Surface 创建后绑定;
- Surface 销毁时只清空 surfaceId;
- 页面重建后优先重绑 Surface;
- 播放器实例仍有效时不要重复 open;
- 播放和录像全部停止后再 close。
22.3 录像建议
播放中启动录像时,只下发录像相关参数,不建议重复下发完整播放参数。
推荐
播放链路保持不变
│
├── 下发录像目录
├── 下发录像文件大小
├── 设置录像音视频开关
└── 启动录像
这样可以减少播放闪断和状态错乱风险。
22.4 快照建议
快照建议先保存到应用沙盒目录,再根据业务需要保存到图库。
这样可以:
- 避免图库授权失败影响截图结果;
- 保留内部文件路径,便于日志排查;
- 兼容更多业务场景。
22.5 事件日志建议
建议保留以下日志:
- open 结果;
- RTSP/RTMP 连接事件;
- 分辨率变化;
- 下载速度;
- 录像文件路径;
- 快照文件路径;
- 连接失败和断开原因。
对音视频类 SDK 集成来说,日志是定位现场问题的关键依据。
二十三、总结
大牛直播SDK(SmartMediaKit)鸿蒙NEXT RTSP、RTMP播放器模块,提供了一套面向实时音视频场景的播放端能力体系。它不仅支持基础的 RTSP/RTMP 直播播放,还覆盖了低延迟播放、XComponent 原生渲染、播放端录像、快照、画面控制、事件回调、视频帧回调、SEI 数据回调等工程化能力。
从集成角度看,推荐采用以下架构:
页面 UI 层
↓
播放器 Wrapper 层
↓
ArkTS Native 封装层
↓
libSmartPlayer.so 播放内核
这种方式可以让页面层保持清晰,让播放生命周期、Surface 生命周期、录像和快照逻辑都具备良好的可维护性。
对于无纸化会议、安防监控、移动执法、工业巡检、机器人视觉、远程医疗、应急指挥等场景,SmartPlayer 不只是一个播放器组件,而是一套可直接嵌入鸿蒙NEXT应用的低延迟实时视频播放内核。它能够帮助开发者快速构建稳定、可控、可扩展的行业级实时视频播放系统。
📎 CSDN官方博客:音视频牛哥-CSDN博客
更多推荐

所有评论(0)