首页 > 其他分享 >Android平台GB28181接入端语音广播和语音对讲规范解读和技术实现

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

时间:2022-10-16 21:00:45浏览次数:55  
标签:handle String GB28181 param int rtp 语音 receiver Android

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

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

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

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

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

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

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

消息示例如下:

a) 语音广播通知

MESSAGE sip:[email protected]:5511SIP/2.0
From: <sip:31010400002000000001 @ 3101040000>;tag = b05e7e60-ca00a8c0-1587-3a3-7fb52a44-3a3
To:<sip:[email protected]: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语音广播”按钮,用于主动关闭语音广播之用。

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

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

标签:handle,String,GB28181,param,int,rtp,语音,receiver,Android
From: https://blog.51cto.com/daniusdk/5760538

相关文章

  • 基于kaldi的语音识别:chain模型的finetune通用步骤
    前记:先说下模型训练的背景。正如一般的机器学习的模型训练那样,首先会用较大的数据集训练生成一个较大的模型,然后在这个模型基础上进行调优,也就是finetune。 我这边基于k......
  • Android平台RTSP、RTMP播放端如何实现YUV或ARGB数据按设定角度旋转
    做音视频RTSP或RTMP直播播放器的时候,不免会遇到这样的诉求,实时播放或快照的时候,由于前端摄像头安装角度不一定是正向,导致播放或快照的时候,视频view显示的画面是呈90°180°......
  • Android studio
    LinuxAny64-bitLinuxdistributionthatsupportsGnome,KDE,orUnityDE;GNUCLibrary(glibc)2.31orlater.x86_64CPUarchitecture;2ndgenerationIntel......
  • Android 编译系统初探
    零.从HelloWorld.cpp说起下面是一个最简单的C++程序,我们通过它来引入我们今天要讲解的Android编译系统/****************************************************************......
  • 实现Android深度加固:代码、资源、so库加密隐藏。兼容unity引擎和各种机型
    1.为什么做加固因为不想辛辛苦苦做的东西,被别人拿去改成各种版,半路摘我的桃子。2.怎么加固2.1简单的加固三方加固,有些三方会有免费版本的加固服务比如腾讯加固2.2......
  • android:加载PDF几种方法汇总对比
    在安卓项目中,加载PDF文件,是一个比较常见的需求。又分为两大类,1.加载网络PDF2.加载一个本地静态PDF。查阅资料,纵观网上在安卓中打开PDF的各种方式,大致可以分为以下几类......
  • Android加载PDF方案(pdf.js,支持缩放)
    都知道,Android本身的webview是不支持pdf加载的(比不上iOS的webview,谁让人家NB呢),因此通过连接Google的一个服务器转换成功后返回给WebView显示。但是,但是,但是呢,大家都懂的,天......
  • Android root 原理
    0x00关于rootlinux和类Unix系统的最初设计都是针对多用户的操作系统,对于用户权限的管理很非常严格的,而root用户(超级用户)就是整个系统的唯一管理员,拥有等同于操作系统的所有......
  • VMware虚拟机安装Android系统(转)
    一、首先我们先要准备好虚拟机和android系统安装包1、VMware下载:https://www.vmware.com/go/getworkstation-win激活码:ZF3R0-FHED2-M80TY-8QYGC-NPKYF2、Android系统下......
  • 竞赛获奖系统解读:VPC2022语音隐私保护赛NWPU-ASLP说话人匿名化系统
    https://blog.csdn.net/weixin_48827824/article/details/127207248?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166567862316782412578074%2522%252C%2522......