Android平台GB28181接入端语音广播和语音对讲规范解读和技术实现

简介: 我在之前的blog,有提到过Android端GB28181接入端的语音广播和语音对讲,今天主要从GB/T28181-2016官方规范和交互流程,大概介绍下Android平GB28181接入端的语音广播和语音对讲。

规范解读

我在之前的blog,有提到过Android端GB28181接入端的语音广播和语音对讲,今天主要从GB/T28181-2016官方规范和交互流程,大概介绍下Android平GB28181接入端的语音广播和语音对讲。


关于交互流程,本文不再赘述,一张图足矣:

1e0e7bae7138431f93bb44c111174310.png

接下来,我们主要来看看规范里面提到的协议接口。


语音广播通知、语音广播应答命令


消息头 Content-type字段为 Content-type:Application/MANSCDP+xml。


语音广播通知、语音广播应答命令采用 MANSCDP协议格式定义。


消息示例如下:


a) 语音广播通知

MESSAGE sip:31010403001370002272@192.168.0.199:5511SIP/2.0
From: <sip:31010400002000000001 @ 3101040000>;tag = b05e7e60-ca00a8c0-1587-3a3-7fb52a44-3a3
To:<sip:31010403001370002272@192.168.0.199:5511>
Call-ID:b05e7e60-ca00a8c0-1587-3a3-2b297f29-3a3@3101040000
CSeq:1761796551 MESSAGE
Via:SIP/2.0/UDP192.168.0.202:5511;rport;branch=z9hG4bK-3a3-e3849-287ef646
Max-Forwards:70
Content-Type:application/MANSCDP+xml
Content-Length:159
<? xmlversion="1.0" ?>
<Notify>
<CmdType>Broadcast</CmdType>
<SN>992</SN>
<SourceID>31010400001360000001</SourceID>
<TargetID>31010403001370002272</TargetID>
</Notify>

b) 语音广播应答

MESSAGEsip:31010400002000000001@3101040000SIP/2.0
From:<sip:31010403001370002272@3101040300>;tag=b55b4cf8-c700a8c0-1587-a3-1ba9ac5-a3
To:<sip:31010400002000000000@3101040000>
Call-ID:b55b4cf8-c700a8c0-1587-a3-5eacf182-a3@3101040300
CSeq:1856483244 MESSAGE
Via:SIP/2.0/UDP192.168.0.199:5511;rport;branch=z9hG4bK-a3-27e0b-71dd2b33
Max-Forwards:70
Content-Type:application/MANSCDP+xml
<? xmlversion="1.0" ?>
<Response>
<CmdType>Broadcast</CmdType>
<SN>992</SN>
<DeviceID>31010403001370002272</DeviceID>
<Result>OK</Result>
</Response>

涉及到的SDP相关参数:

v=0
o=6401060000202000000100INIP4172.20.16.3
s=Play
c=INIP4172.20.16.3
t=00
m=audio8000RTP/AVP8 //标识语音媒体流内容
a=sendonly
a=rtpmap:8PCMA/8000 //RTP+音频流
y=0100000001
f=v/a/1/8/1 //音频参数描述

技术实现


本文以大牛直播SDK的Android平台基于Camera2的采集demo为例,如果需要注册到GB28181平台,点击页面的“启动GB28181”即可,有语音广播过来后,使能“GB28181语音广播”按钮,用于主动关闭语音广播之用。

a76c648885844838a51ace9363fdca6b.jpg

语音广播信令Listener如下:

package com.gb28181.ntsignalling;
public interface GBSIPAgentListener
{
    /*
    *收到语音广播通知
     */
    void ntsOnNotifyBroadcastCommand(String fromUserName, String fromUserNameAtDomain, String sn, String sourceID, String targetID);
    /*
    *需要准备接受语音广播的SDP内容
     */
    void ntsOnAudioBroadcast(String commandFromUserName, String commandFromUserNameAtDomain, String sourceID, String targetID);
    /*
    *音频广播, 发送Invite请求异常
     */
    void ntsOnInviteAudioBroadcastException(String sourceID, String targetID, String errorInfo);
    /*
    *音频广播, 等待Invite响应超时
     */
    void ntsOnInviteAudioBroadcastTimeout(String sourceID, String targetID);
    /*
    *音频广播, 收到Invite消息最终响应
     */
    void ntsOnInviteAudioBroadcastResponse(String sourceID, String targetID, int;
    /*
     * 音频广播, 收到BYE Message
     */
    void ntsOnByeAudioBroadcast(String sourceID, String targetID);
    /*
    * 不是在收到BYE Message情况下, 终止音频广播
     */
    void ntsOnTerminateAudioBroadcast(String sourceID, String targetID);
}

相关信令接口如下:

package com.gb28181.ntsignalling;
public interface GBSIPAgent {
    /*
     *语音广播应答
     */
    void respondBroadcastCommand(String fromUserName, String fromUserNameAtDomain, String sn, String sourceID, String targetID, boolean;
    /*
    *语音广播接收者发送Invite消息, rtp ssrc暂时由sdk生成
    *@param addressType: ipv4:"IP4", ipv6:"IP6", 其他不支持, 填充SDP用
    *@param localAddress: 本地IP地址, 填充SDP用
    *@param localPort: 本地端口, 填充SDP用
    *@param mediaTransportProtocol: 媒体传输协议, rtp over udp:"RTP/AVP", rtp over tcp:"TCP/RTP/AVP". 其他不支持, 填充SDP用
     */
    boolean inviteAudioBroadcast(String commandFromUserName, String commandFromUserNameAtDomain, String sourceID, String targetID,
                                 String addressType, String localAddress, int;
    /*
    *取消音频广播, 这个需要在invite收到临时响应之后,最终响应之前才能成功, 如果UAS已经发送过最终响应, UAS收到cancel不做处理, 具体参考RFC3261
     */
    boolean cancelAudioBroadcast(String sourceID, String targetID);
    /*
    *终止语音广播会话, 发送BYE消息
     */
    boolean byeAudioBroadcast(String sourceID, String targetID);
}

接下来就是收到RTP音频包和解码输出这块,我们直接在播放端做扩展即可,设计如下:

/*
 * SmartPlayerJniV2.java
 * SmartPlayerJniV2
 *
 * WebSite: https://daniusdk.com
 */
  /*++++++++++++++++++RTP Receiver++++++++++++++++++++++*/
  /*
   * 创建RTP Receiver
   *
   * @param reserve:保留参数传0
   *
   * @return RTP Receiver 句柄,0表示失败
   */
  public native long CreateRTPReceiver(int reserve);
  /**
   *设置 RTP Receiver传输协议
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param transport_protocol, 0:UDP, 1:TCP, 默认是UDP
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverTransportProtocol(long rtp_receiver_handle, int transport_protocol);
  /**
   *设置 RTP Receiver IP地址类型
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param ip_address_type, 0:IPV4, 1:IPV6, 默认是IPV4
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverIPAddressType(long rtp_receiver_handle, int ip_address_type);
  /**
   *设置 RTP Receiver RTP Socket本地端口
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param port, 必须是偶数,设置0的话SDK会自动分配, 默认值是0
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverLocalPort(long rtp_receiver_handle, int port);
  /**
   *设置 RTP Receiver SSRC
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverSSRC(long rtp_receiver_handle, String ssrc);
  /**
   *创建 RTP Receiver 会话
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param reserve, 保留值,目前传0
   *
   * @return {0} if successful
   */
  public native int CreateRTPReceiverSession(long rtp_receiver_handle, int reserve);
  /**
   *获取 RTP Receiver RTP Socket本地端口
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @return 失败返回0, 成功的话返回响应的端口, 请在CreateRTPReceiverSession返回成功之后调用
   */
  public native int GetRTPReceiverLocalPort(long rtp_receiver_handle);
  /**
   *设置 RTP Receiver Payload 相关信息
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @param payload_type, 请参考 RFC 3551
   *
   * @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 可能传null就好
   *
   * @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频
   *
   * @param clock_rate, 请参考 RFC 3551
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverPayloadType(long rtp_receiver_handle, int payload_type, String encoding_name, int media_type, int clock_rate);
  /**
   *设置 RTP Receiver 音频采样率
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param sampling_rate, 音频采样率
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverAudioSamplingRate(long rtp_receiver_handle, int sampling_rate);
  /**
   *设置 RTP Receiver 音频通道数
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param channels, 音频通道数
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverAudioChannels(long rtp_receiver_handle, int channels);
  /**
   *设置 RTP Receiver 远端地址
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   * @param address, IP地址
   * @param port, 端口
   *
   * @return {0} if successful
   */
  public native int SetRTPReceiverRemoteAddress(long rtp_receiver_handle, String address, int port);
  /**
   *初始化 RTP Receiver
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @return {0} if successful
   */
  public native int InitRTPReceiver(long rtp_receiver_handle);
  /**
   *UnInit RTP Receiver
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @return {0} if successful
   */
  public native int UnInitRTPReceiver(long rtp_receiver_handle);
  /**
   *Destory RTP Receiver Session
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @return {0} if successful
   */
  public native int DestoryRTPReceiverSession(long rtp_receiver_handle);
  /**
   *Destory RTP Receiver
   *
   * @param rtp_receiver_handle, CreateRTPReceiver
   *
   * @return {0} if successful
   */
  public native int DestoryRTPReceiver(long rtp_receiver_handle);
  /*++++++++++++++++++RTP Receiver++++++++++++++++++++++*/


以上是GB/T28181-2016规范关于语音广播和语音对讲的部分说明和Android端GB28181接入端针对语音广播的技术实现,感兴趣的开发者可酌情参考。

相关文章
|
12月前
|
监控 Android开发 数据安全/隐私保护
批量发送短信的平台,安卓群发短信工具插件脚本,批量群发短信软件【autojs版】
这个Auto.js脚本实现了完整的批量短信发送功能,包含联系人管理、短信内容编辑、发送状态监控等功能
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
10530 2
|
9月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1625 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
9月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1083 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
9月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1175 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
911 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
9月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
411 0
|
10月前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
1308 6
|
12月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
688 11
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
5363 77