一、文档概述

本文介绍如何在 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博客 

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐