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接入端针对语音广播的技术实现,感兴趣的开发者可酌情参考。

相关文章
|
6天前
|
机器学习/深度学习 传感器 vr&ar
探索安卓与iOS平台下的虚拟现实技术发展
随着移动设备的普及和技术的不断进步,安卓和iOS平台上的虚拟现实(VR)技术发展迅速。本文将探讨安卓与iOS平台下虚拟现实技术的最新进展,包括技术特点、应用场景以及未来发展趋势。
11 0
|
6天前
|
机器学习/深度学习 人工智能 安全
探索Android与iOS平台的安全性:一场永无止境的较量
【5月更文挑战第31天】在数字时代,移动操作系统的安全性成为了全球用户关注的焦点。本文将深入探讨Android和iOS这两大主流平台的安全机制,分析它们的安全特性、面临的挑战以及未来的发展趋势。通过比较研究,我们将揭示这两个系统在保护用户数据和隐私方面的不同策略和成效。
|
12天前
|
API vr&ar 开发工具
构建未来:安卓平台上的AR应用开发全解析
【5月更文挑战第25天】随着增强现实(AR)技术的不断成熟,安卓平台上的AR应用开发正吸引着越来越多的关注。本文深入剖析了在安卓系统上开发AR应用的核心技术和流程,探讨了ARCore SDK的使用、3D渲染技术、用户交互设计以及性能优化等关键要素。通过实例演示和代码分析,揭示了创建高效、沉浸式AR体验的策略和最佳实践,为开发者提供指引,同时对未来AR应用的发展趋势做出展望。
|
机器学习/深度学习 监控 前端开发
|
JavaScript 前端开发 Java
|
物联网 大数据 Android开发