好多开发者或厂商,对Android平台GB28181接入模块的定位,大多是IPC国标流程打通模拟,基于这个目的,很难按照标准SPEC规范实现Android平台GB28181设备接入,我们在跟第三方国标平台厂商对接时发现,部分公司,尽管参与了标准的制定或审校,自身实现,细节仍不尽人意。
除了作为IPC国标模拟工具,Android平台GB28181设备接入没有实现价值吗?实际上,Android平台GB28181设备接入的用途非常广泛,通过实现不具备国标音视频能力的 Android终端,平台注册接入到现有的GB/T28181—2016服务,可用于如智能监控、智慧零售、智慧教育、远程办公、生产运输、智慧交通、车载或执法记录仪等场景。
Android平台GB28181接入终端除支持常规的音视频数据接入外,还需要支持移动设备位置(MobilePosition)订阅和通知、语音广播和语音对讲。
我们在实现Android平台GB28181设备接入端的时候,有个选项是设置本地SIP端口:
代码语言:javascript复制GBSIPAgent gb28181_agent_ = null;
private int gb28181_sip_local_port_base_ = 5060;
private String gb28181_sip_server_id_ = "34020000002000000001";
private String gb28181_sip_domain_ = "3402000000";
private String gb28181_sip_server_addr_ = "192.168.2.154";
private int gb28181_sip_server_port_ = 15060;
private String gb28181_sip_user_agent_filed_ = "DN(daniusdk.com) GB28181 User Agent V1.3";
private String gb28181_sip_username_ = "31011500991320000078";
private String gb28181_sip_password_ = "12345678";
private int gb28181_reg_expired_ = 3600; // 注册有效期时间最小3600秒
private int gb28181_heartbeat_interval_ = 20; // 心跳间隔GB28181默认是60, 目前调整到20秒
private int gb28181_heartbeat_count_ = 3; // 心跳间隔3次失败,表示和服务器断开了
private int gb28181_sip_trans_protocol_ = 0; // 0表示信令用UDP传输, 1表示信令用TCP传输
private long gb28181_rtp_sender_handle_ = 0;
private int gb28181_rtp_payload_type_ = 96;
private String gb28181_rtp_encoding_name_ = "PS";
设置本地SIP端口的时候,SIP端口有可能被占用(比如大多都是设置5060)或被网络屏蔽,网上常规的做法是设置个看似不常用的端口,比如5061、5062等,虽然能解决绝大多数场景的问题,作为个通用的模块来说,未免过于粗糙,或者说治标不治本。
我们的做法是:设置本地SIP端口的时候,设置个base_local_port, 然后,根据设定的端口,在有效端口范围内,做绑定尝试,如果成功,提示bind local port OK, 然后做其他操作即可,这样可以最大限度的规避端口分配失败。
具体代码如下:
代码语言:javascript复制int try_end_port = gb28181_sip_local_port_base_ 5000;
try_end_port = try_end_port > 65536 ?65536: try_end_port;
for (int i = gb28181_sip_local_port_base_; i < try_end_port; i) {
if (gb28181_agent_.bindLocalPort(i)) {
is_bind_local_port_ok = true;
break;
}
}
if (!is_bind_local_port_ok) {
gb28181_agent_.releaseSipStack();
gb28181_agent_ = null;
Log.e(TAG, "initGB28181Agent gb28181_agent_.bindLocalPort failed.");
return false;
}
感兴趣的开发者,可以做下尝试。