一、背景说明
随着 HarmonyOS NEXT 在行业终端、移动执法、无人机巡检、智慧园区、车载终端、应急指挥等场景中的逐步落地,越来越多实时视频应用开始面临一个共性需求:鸿蒙NEXT设备如何接入现有 GB28181 视频平台体系。
GB28181 是国内安防和行业视频联网中广泛使用的标准协议。传统接入对象多为 IPC、NVR、执法记录仪、车载终端、边缘网关等设备。而在新的国产化终端环境下,鸿蒙NEXT应用也开始承担前端设备角色,需要完成平台注册、心跳保活、平台点播、语音广播、位置上报和设备控制等能力。
大牛直播SDK(SmartMediaKit)在 Android、iOS、Windows 等平台已有多年低延迟音视频能力积累,现已针对鸿蒙NEXT场景提供 GB28181 设备接入能力。开发者可以在鸿蒙NEXT应用中,通过 ArkTS 层接口完成国标平台接入,而无需直接处理复杂的 SIP 状态机和底层媒体封装细节。GB28181 信令由 ArkTS 封装层对接 Native SIP 协议栈,业务侧通过 Listener 方式接收注册、点播、语音广播和设备控制等事件。
本文主要从工程集成角度,介绍大牛直播SDK鸿蒙NEXT GB28181设备接入模块的整体思路、Demo组织方式、核心调用流程和实际对接注意事项。
二、方案定位
大牛直播SDK鸿蒙NEXT GB28181设备接入模块,主要面向“设备端接入平台”的场景。
也就是说,鸿蒙NEXT应用可以作为一个标准 GB28181 前端设备,注册到国标视频平台,并接受平台侧调度。
整体链路可以概括为:
鸿蒙NEXT设备 ↓GB28181注册 ↓平台心跳保活 ↓平台发起视频点播 ↓设备启动摄像头采集与编码 ↓RTP/PS媒体流发送 ↓平台接收实时视频
和普通 RTMP 推流不同,GB28181 不是简单填写一个推流地址后主动推流,而是由平台侧统一纳管设备。平台可以查看设备在线状态,可以按需点播实时视频,也可以下发语音广播、位置订阅、设备控制等请求。
因此,GB28181设备接入更像是一套完整的“设备联网能力”,而不仅仅是单一媒体推流能力。
三、典型应用场景
大牛直播SDK鸿蒙NEXT GB28181模块适用于以下场景:
| |
|---|
| 鸿蒙NEXT终端作为移动视频前端,接入执法调度平台 |
| |
| |
| |
| |
| |
| |
这些场景的共同特点是:设备不仅要能采集视频,还要能被平台发现、管理、点播和控制。
四、Demo工程整体结构
在鸿蒙NEXT Demo 中,GB28181 设备接入并不是单独一个 SIP 示例,而是和 SmartPublisher 推送模块、摄像头采集模块、音频模块、位置模块组合在一起。
推荐结构如下:
SmartPublisherPage.ets 业务页面、参数配置、按钮操作、日志展示Gb28181SipAgent.ets GB28181信令封装,负责注册、心跳、点播、广播、控制等事件SmartPublisherWrapper.ets 推送封装层,负责摄像头、麦克风、编码和媒体链路管理GbAudioBroadcastPlayer.ets 语音广播接收与播放辅助模块GbLocationProvider.ets 位置获取、缓存和位置上报辅助模块libGb28181SipAgent.so GB28181 Native协议模块libSmartPublisher.so 大牛直播SDK Native媒体模块
这种结构的好处是比较清晰:
页面层只负责交互信令层只负责平台事件媒体层只负责采集编码和发送位置模块只负责定位语音广播模块只负责音频接收播放
这样后续维护和扩展都比较方便。
五、核心能力说明
实际项目中,建议按照以下顺序集成:
1. 集成SDK Native库2. 配置工程依赖和权限3. 初始化GB28181 Agent4. 配置平台注册参数5. 注册事件监听6. 启动GB28181模块7. 验证平台注册和心跳8. 验证平台点播9. 打通媒体采集与发送10. 验证语音广播、位置上报和设备控制11. 完善停止和释放逻辑
下面保留少量上层 Demo 代码,主要展示业务侧如何组织调用。底层协议处理、RTP媒体细节和平台适配逻辑不在本文展开。
七、初始化GB28181 Agent
在页面或业务管理类中,可以声明一个 GB28181 Agent 实例:
import { Gb28181SipAgent, Gb28181SipAgentConfig, Gb28181SipEvent, Gb28181AgentListener, Gb28181PlayListener, Gb28181AudioBroadcastListener, Gb28181DeviceControlListener} from '../gb28181/Gb28181SipAgent'private gbSipAgent: Gb28181SipAgent = new Gb28181SipAgent()private isGB28181Running: boolean = falseprivate gb28181StatusText: string = '未启动'
这里建议把 GB28181 相关状态独立出来,不要和 RTMP 推流、RTSP 服务、本地录像状态完全混在一起。因为 GB28181 是“平台调度型链路”,它的状态和主动推流不完全一样。
八、配置并启动GB28181模块
启动 GB28181 时,业务层主要完成三件事
示例代码如下:
private async startGB28181(): Promise { if (this.isGB28181Running) { this.pushLog('[GB28181] 已启动,无需重复启动') return } this.setupGB28181Listeners() const config: Gb28181SipAgentConfig = { serverAddress: this.gbServerAddress, serverPort: this.gbServerPort, serverId: this.gbServerId, serverDomain: this.gbServerDomain, localAddress: this.gbLocalAddress, localPort: this.gbLocalPort, username: this.gbUsername, password: this.gbPassword, deviceId: this.gbDeviceId, deviceName: this.gbDeviceName, manufacturer: 'Daniulive', model: 'SmartPublisherOhos', transport: this.gbTransport, expires: 3600, heartbeatInterval: 20, heartbeatCount: 3 } const ok = await this.gbSipAgent.start(config) this.isGB28181Running = ok this.gb28181StatusText = ok ? '注册中' : '启动失败' this.pushLog(ok ? '[GB28181] 已启动,等待平台注册' : '[GB28181] 启动失败')}
这里的参数建议在 Demo 页面中做成可配置项,方便对接不同 GB28181 平台。
常见配置项包括:
九、注册与心跳监听
GB28181 注册和心跳是基础链路。只有设备稳定在线,平台点播、语音广播和位置订阅才有意义。
示例代码:
private setupGB28181Listeners(): void { const agentListener = new Gb28181AgentListener() agentListener.onRegisterOK = (event: Gb28181SipEvent): void => { this.gb28181StatusText = '已注册' this.pushLog('[GB28181] 注册成功') } agentListener.onRegisterTimeout = (event: Gb28181SipEvent): void => { this.gb28181StatusText = '注册超时' this.pushLog('[GB28181] 注册超时,请检查平台地址、端口和设备配置') } agentListener.onRegisterTransportError = (event: Gb28181SipEvent): void => { this.gb28181StatusText = '传输异常' this.pushLog('[GB28181] 注册传输异常,请检查网络或端口占用') } agentListener.onHeartbeatWarning = (event: Gb28181SipEvent): void => { this.pushLog('[GB28181] 心跳异常预警') } agentListener.onHeartbeatException = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 心跳异常,准备重启链路') await this.restartGB28181() } agentListener.onMobilePositionRequest = (event: Gb28181SipEvent): void => { this.reportLastKnownLocation() } this.gbSipAgent.setAgentListener(agentListener) this.setupGB28181PlayListener() this.setupGB28181AudioBroadcastListener() this.setupGB28181DeviceControlListener()}
这里不建议在公开文章中展开底层鉴权、重试、报文处理等细节。对于客户来说,知道 SDK 提供了注册、心跳和异常回调即可。
十、平台点播处理
平台点播是 GB28181 设备接入的核心。
整体流程可以理解为:
平台发起点播 ↓设备收到点播事件 ↓业务层准备媒体链路 ↓平台确认会话 ↓设备开始发送视频流 ↓平台停止点播 ↓设备释放媒体资源
上层 Demo 可以保持如下简化写法:
privatesetupGB28181PlayListener(): void { const playListener = new Gb28181PlayListener() playListener.onInvitePlay = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 收到平台点播请求') await this.prepareGB28181Media(event) } playListener.onAckPlay = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 平台确认点播,启动媒体发送') await this.startGB28181Media(event) } playListener.onByePlay = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 平台停止点播') await this.stopGB28181Media('bye') } playListener.onCancelPlay = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 平台取消点播') await this.stopGB28181Media('cancel') } playListener.onTerminatePlay = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 点播会话终止') await this.stopGB28181Media('terminate') } this.gbSipAgent.setPlayListener(playListener)}
这里故意不展开底层媒体参数、SDP细节和RTP发送细节。文章只需要表达清楚:平台点播事件由 Listener 接收,媒体链路由业务层统一启动和停止。
十一、媒体链路与SmartPublisher打通
GB28181点播最终需要摄像头采集、编码和媒体发送。大牛直播SDK在鸿蒙NEXT端通过 SmartPublisher 统一处理媒体能力。
业务层可以封装成两个函数:
private async prepareGB28181Media(event: Gb28181SipEvent): Promise { // 实际项目中,可在这里完成媒体链路准备、摄像头状态检查等 this.pushLog('[GB28181] 准备媒体链路') const ok = await this.publisher.prepareGB28181Media({ videoWidth: this.publishWidth, videoHeight: this.publishHeight, fps: this.publishFps, bitrateKbps: this.publishBitrateKbps, audioEnabled: this.audioEnabled }) if (!ok) { this.pushLog('[GB28181] 媒体链路准备失败') return } this.pushLog('[GB28181] 媒体链路准备完成')}
启动媒体发送:
privateasyncstartGB28181Media(event: Gb28181SipEvent): Promise { const ok = await this.publisher.startGB28181Media(event) if (!ok) { this.pushLog('[GB28181] 媒体发送启动失败') await this.stopGB28181Media('start failed') return } this.gb28181StatusText = '点播中' this.pushLog('[GB28181] 媒体发送已启动')}
停止媒体链路:
private async stopGB28181Media(reason: string): Promise { await this.publisher.stopGB28181Media() this.gb28181StatusText = this.isGB28181Running ? '已注册' : '未启动' this.pushLog(`[GB28181] 媒体链路已停止: ${reason}`)}
这里的 prepareGB28181Media()、startGB28181Media()、stopGB28181Media() 可以理解为业务层对 SDK 能力的二次封装。公开文章中不建议直接贴完整底层调用,只展示上层如何组织即可。
十二、语音广播接入
GB28181语音广播适用于平台向前端设备下发语音指令,例如应急指挥、移动执法、车载调度、巡检提醒等场景。
整体流程可以概括为:
平台发起语音广播 ↓设备收到广播事件 ↓建立音频接收链路 ↓播放平台下发的音频 ↓广播结束后释放资源
上层 Demo 可简化为:
privatesetupGB28181AudioBroadcastListener(): void { const audioListener = new Gb28181AudioBroadcastListener() audioListener.onAudioBroadcastNotify = (event: Gb28181SipEvent): void => { this.pushLog('[GB28181] 收到语音广播通知') } audioListener.onAudioBroadcast = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 准备接收语音广播') await this.audioBroadcastPlayer.prepare(event) } audioListener.onAudioBroadcastResponse = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 语音广播链路建立,开始播放') await this.audioBroadcastPlayer.start(event) } audioListener.onByeAudioBroadcast = (event: Gb28181SipEvent): void => { this.pushLog('[GB28181] 语音广播结束') this.audioBroadcastPlayer.stop() } this.gbSipAgent.setAudioBroadcastListener(audioListener)}
这样写既能体现 Demo 具备语音广播能力,又不会暴露音频RTP接收、payload适配和播放器内部处理细节。
十三、位置上报
在移动设备、车载设备、无人机巡检等场景中,平台通常需要知道前端设备的位置。
建议把位置能力单独封装,而不是直接写在 GB28181 事件回调中。
示例:
private reportLastKnownLocation(): void { const location = this.locationProvider.getLastLocation() if(!location) { this.pushLog('[GB28181] 当前暂无可上报位置') return } const ok = this.gbSipAgent.updateDevicePosition({ longitude: location.longitude, latitude: location.latitude, altitude: location.altitude ?? 0, speed: location.speed ?? 0, direction: location.direction ?? 0, time: new Date().toISOString() }) this.pushLog(ok ? '[GB28181] 位置上报成功': '[GB28181] 位置上报失败')}
这种写法比较适合公开文章:只展示“读取缓存位置并上报”的业务逻辑,不展开底层定位订阅和平台报文细节。
十四、设备控制事件
GB28181平台可能下发设备控制命令,例如云台控制、远程重启等。
对于普通鸿蒙手机或平板,部分控制命令可以只做日志记录或业务提示;对于机器人、云台、巡检设备,则可以映射到实际硬件控制。
示例:
privatesetupGB28181DeviceControlListener(): void { const controlListener = new Gb28181DeviceControlListener() controlListener.onDeviceControlPtz = (event: Gb28181SipEvent): void => { this.pushLog('[GB28181] 收到PTZ控制命令') // 可根据实际设备能力映射到云台、摄像头或机器人控制 } controlListener.onDeviceControlTeleBoot = async (event: Gb28181SipEvent): Promise => { this.pushLog('[GB28181] 收到远程重启指令,重启业务链路') await this.restartGB28181() } this.gbSipAgent.setDeviceControlListener(controlListener)}
这里建议使用“重启业务链路”表述,不建议公开文章中写成直接重启设备系统。行业客户能理解这个逻辑,安全性也更好。
十五、生命周期管理
GB28181接入中,启动只是第一步,真正重要的是停止、释放和异常恢复。
建议业务层统一封装停止逻辑:
private async stopGB28181(): Promise { this.pushLog('[GB28181] 准备停止') await this.stopGB28181Media('manual stop') this.audioBroadcastPlayer.stop() this.gbSipAgent.terminateAllPlays(true) this.gbSipAgent.terminateAllAudioBroadcasts(true) this.gbSipAgent.stop() this.isGB28181Running = false this.gb28181StatusText = '未启动' this.pushLog('[GB28181] 已停止')}
页面销毁或应用退出时,建议释放资源:
aboutToDisappear(): void { this.gbSipAgent.release() this.audioBroadcastPlayer.release() this.publisher.release() this.pushLog('[GB28181] 页面退出,资源已释放')}
这里的重点是:所有停止入口最终都走统一清理逻辑。例如平台停止点播、用户手动停止、心跳异常、页面退出、平台取消点播,都不应该各写一套释放流程。
十六、异常恢复建议
弱网、平台重启、网络切换、设备休眠恢复等场景下,GB28181链路可能出现异常。建议业务层提供统一重启函数:
private async restartGB28181(): Promise { this.pushLog('[GB28181] 开始重启链路') await this.stopGB28181Media('restart') this.audioBroadcastPlayer.stop() this.gbSipAgent.stop() this.isGB28181Running = false this.gb28181StatusText = '重连中' await new Promise((resolve) => setTimeout(resolve, 300)) await this.startGB28181()}
公开文章中,这样的代码足够说明工程思路:先清理媒体,再重启信令,不需要把每个底层对象和会话细节完全展开。
十七、与RTMP推流、轻量级RTSP服务协同
大牛直播SDK鸿蒙NEXT方案并不只支持 GB28181。它还可以与 RTMP推流、轻量级RTSP服务、本地录像等能力组合使用。
在实际项目中,可以根据业务需要组合:
GB28181 接入监管平台RTMP 推流到业务直播系统轻量级 RTSP 服务供局域网客户端拉流本地录像用于留痕位置上报用于调度语音广播用于指挥
这也是大牛直播SDK鸿蒙NEXT方案的价值所在:它不是单点协议能力,而是一套面向实时视频系统的组合式 SDK 能力。
总结
大牛直播SDK(SmartMediaKit)鸿蒙NEXT GB28181设备接入模块,主要解决的是鸿蒙NEXT终端如何作为标准国标前端设备接入视频平台的问题。
通过该模块,鸿蒙NEXT应用可以完成:
| | |
|---|
| | |
| | Warning / Exception 两级,可配置阈值 |
| | PS/H.264/H.265,UDP/TCP RTP |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
从工程集成角度看,建议开发者按“先注册、再点播、再媒体、再扩展能力”的顺序逐步验证,不要一开始就同时打开所有功能。
本文中展示的 Demo 代码主要体现上层调用方式:如何初始化 GB28181 Agent,如何配置平台参数,如何监听注册和心跳,如何响应平台点播,如何启动媒体链路,如何处理语音广播、位置上报和生命周期释放。底层 SIP 协议状态机、RTP/PS 封装、媒体参数协商和平台兼容性细节,则由大牛直播SDK内部完成封装。
对于移动执法、应急指挥、无人机巡检、车载终端、智慧园区、工业巡检等场景,鸿蒙NEXT设备通过大牛直播SDK接入 GB28181 平台后,可以从普通视频采集终端升级为可被平台统一纳管、调度和控制的标准前端设备。
结合大牛直播SDK已有的 RTMP推流、RTSP/RTMP播放、轻量级RTSP服务、本地录像、快照等能力,开发者可以进一步构建适合国产化终端、行业专网和低延迟实时视频场景的完整解决方案。