GB28181设备接入端如何播放语音广播数据?

简介: GB28181设备接入端如何播放语音广播数据?

 技术背景

语音广播功能是GB28181设备接入端非常重要的功能属性,语音广播让终端和平台之间,有了实时双向互动,可以满足执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终端等场景的技术诉求。

这里我们先回顾下GB28181规范关于语音广播的描述:

语音广播功能实现用户通过语音输入设备向前端语音输出设备的语音广播。

语音输入设备/语音输入联网系统(以下简称“语音流发送者”)、SIP 服务器向语音输出设备/语音输出视频监控联网系统(以下简称“语音流接收者”)发送通知消息,语音流接收者收到通知消息后,进行判断处理。

若能够接收广播,则向语音流发送者发起呼叫请求,获取广播媒体流。

语音输入设备、语音输出设备编码应符合E.1 的规定。如果设备具备语音输出能力,则在设备目录查询和订阅时,需要上报语音输出设备。如果不上报语音输出设备,则表示该设备没有语音输出能力。

上报语音输出通道时,ParentID 填写其父设备的 ID。例如,IPC 具备语音输出能力,在 IPC 上报设备目录时,需要上报语音输出设备。该语音输出设备ID的类型编码为 137,其父设备为该IPC。NVR 本身具备语音输出能力,在 NVR 上报设备目录时,除了上报 NVR 接入的 IPC 以及IPC 自身的语音输出设备之外,还需要上报语音输出设备。该语音输出设备ID的类型编码为137.其父设备为该NVR。监控中心与设备之间进行语音广播,可以直接对语音输出设备发送语音广播通知,也可以对语音输出设备所属的前端主设备发送语音广播通知。

对前端主设备发送语音广播通知消息中仅需携带前端主设备编码,表示对该设备上所有的语音输出设备进行语音广播。例如,对IPC 发送语音广播通知,表示对该IPC 接入的所有语音输出设备进行广播;对 NVR 发送语音广播通知,表示对 NVR 下所有 IPC以及自身的语音输出设备进行广播。

语音流的封装格式应符合 C.2.4 音频流的 RTP 封装的定义。

语音广播宜符合附录 K 规定的媒体流保活机制。

技术实现

本文我们不再探讨GB28181语音广播的具体流程,这里我们假定信令交互已经完成,准备接收数据:

camera2解锁图像方向.jpg

收到broadcast语音广播后,我们的处理逻辑如下:

privatebooleanstartAudioPlay() {
if (player_handle_!=0 )
returnfalse;
player_handle_=lib_player_.SmartPlayerOpen(context_);
if (player_handle_==0)
returnfalse;
lib_player_.SetSmartPlayerEventCallbackV2(player_handle_,newEventHandlerPlayerV2());
// 缓存大小可以调整lib_player_.SmartPlayerSetBuffer(player_handle_, 0);
// lib_player_.SmartPlayerSetFastStartup(player_handle_, 0);// set report download speed(默认2秒一次回调 用户可自行调整report间隔)lib_player_.SmartPlayerSetReportDownloadSpeed(player_handle_, 1, 2);
lib_player_.SmartPlayerClearRtpReceivers(player_handle_);
lib_player_.SmartPlayerAddRtpReceiver(player_handle_, rtp_receiver_handle_);
lib_player_.SmartPlayerSetSurface(player_handle_, null);
lib_player_.SmartPlayerSetAudioOutputType(player_handle_, 1);
lib_player_.SmartPlayerSetMute(player_handle_, 0);
lib_player_.SmartPlayerSetAudioVolume(player_handle_, 100);
lib_player_.SmartPlayerSetExternalAudioOutput(player_handle_, newPlayerExternalPCMOutput());
lib_player_.SmartPlayerSetUrl(player_handle_, "rtp://ntinternal/rtpreceiver/implemention0");
if (0!=lib_player_.SmartPlayerStartPlay(player_handle_)) {
lib_player_.SmartPlayerClose(player_handle_);
player_handle_=0;
Log.e(TAG,  "[daniusdk]start audio play failed");
returnfalse;
  }
lib_player_.SmartPlayerSetAudioDataCallback(player_handle_, newPlayerAudioDataOutput());
lib_player_.SmartPlayerSetPullStreamAudioTranscodeAAC(player_handle_, 0);
if (0==lib_player_.SmartPlayerStartPullStream(player_handle_) ) {
// 启动定时器,长时间收不到音频数据,则停止播放,发送BYElast_received_audio_data_time_.set(SystemClock.elapsedRealtime());
handler_.postDelayed(newAudioPlayerPCMTimer(player_handle_), AudioPlayerPCMTimer.INTERVAL_MS);
  }
returntrue;
}

image.gif

简单来说,就是启动了个纯语音播放的实例,来处理过来的PCMA或PS的audio数据。

其中PlayerExternalPCMOutput()主要是把数据塞到GB28181数据采集处理的模块,来实现语音广播的回音消除的目的。

classPlayerExternalPCMOutputimplementsNTExternalAudioOutput {
privateintbuffer_size_=0;
privateByteBufferpcm_buffer_=null;
@OverridepublicByteBuffergetPcmByteBuffer(intsize)  {
//Log.i("getPcmByteBuffer", "size: " + size);if(size<1)
returnnull;
if(buffer_size_!=size) {
buffer_size_=size;
pcm_buffer_=ByteBuffer.allocateDirect(buffer_size_);
    }
returnpcm_buffer_;
  }
publicvoidonGetPcmFrame(intret, intsampleRate, intchannel, intsampleSize, intis_low_latency) {
if (null==pcm_buffer_)
return;
pcm_buffer_.rewind();
if (ret==0&&isGB28181StreamRunning&&publisherHandle!=0 )
libPublisher.SmartPublisherOnFarEndPCMData(publisherHandle, pcm_buffer_, sampleRate, channel, sampleSize, is_low_latency);
  }
}

image.gif

如果需要停止播放,调用以下逻辑即可:

privatevoidstopAudioPlayer() {
if (player_handle_!=0 ) {
lib_player_.SmartPlayerStopPullStream(player_handle_);
lib_player_.SmartPlayerStopPlay(player_handle_);
lib_player_.SmartPlayerClose(player_handle_);
player_handle_=0;
  }
}

image.gif

总结

GB28181语音广播这块,如果平台侧和终端,都是按照规范来实现的话,问题会少很多,实际尴尬的是,大厂或部分厂商先入为主,实际生产环境,不一定按照预期的,谁的问题谁处理,作为Android终端模块,push不动国标平台侧的时候,有时候只有兼容它,这种痛苦真是一言难尽。

相关文章
|
设计模式 C++
设计模式之抽象工厂模式(C++)
设计模式之抽象工厂模式(C++)
254 0
|
负载均衡 算法 安全
硬件负载均衡和软件负载均衡有什么区别?
硬件负载均衡和软件负载均衡有什么区别?
619 127
|
敏捷开发 前端开发 测试技术
Apipost与Apifox分享操作便捷性对比
在现代软件开发中,API接口文档的快速共享至关重要。繁琐的分享流程可能导致沟通滞后、需求理解偏差,甚至延误项目交付。本文对比了Apipost与Apifox在文档分享上的差异。Apipost通过一键分享功能,集成调试、Mock和测试流程,支持权限控制和Markdown定制,大幅提升了跨部门协作效率。相比之下,Apifox的分享操作较为复杂,需多步骤完成,且存在版本管理和权限控制不足的问题。
296 0
|
测试技术 Android开发 Python
python | 大麦网抢票(移动端)
上篇文章写到了使用windows11打开安卓应用,那么使用python来抢大麦网票应该也是可以的吧。库使用的是`pyautogui`。
2002 0
python | 大麦网抢票(移动端)
|
存储 JSON Kubernetes
在K8S中,服务是如何发布的?
在K8S中,服务是如何发布的?
|
人工智能 自然语言处理 语音技术
GigaSpeech 2:三万小时东南亚多语种语音识别开源数据集发布
GigaSpeech 2 是一个持续扩展的、多领域多语言的大规模语音识别语料库,旨在促进低资源语言语音识别领域的发展和研究。
|
消息中间件 测试技术 Linux
GoogleTest 测试框架
GoogleTest 测试框架
|
Web App开发
ZLMediaKit webrtc RTP包接受与重传
ZLMediaKit webrtc RTP包接受与重传
|
Java Android开发
成功解决eclipse启动报错 A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available
成功解决eclipse启动报错 A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available
|
机器学习/深度学习 人工智能 算法
强化学习从基础到进阶-常见问题和面试必知必答[8]:近端策略优化(proximal policy optimization,PPO)算法
强化学习从基础到进阶-常见问题和面试必知必答[8]:近端策略优化(proximal policy optimization,PPO)算法

热门文章

最新文章