规范解读
GB28181-2016和GB28181-2022关于媒体保活机制这块,并无调整,平台、设备媒体流保活机制规定如下:
a)链路建立后,码流经过的各级平台应具备媒体流丢失监测能力,若监测到媒体流丢失,应释放该条媒体链路,并通过会话内Bye消息通知上下级平台;
b)上下级平台之间、平台与设备之间、平台与客户端之间应通过注册,状态信息报送等进行状态监测,若监测到媒体流接收方或媒体流发送方故障或离线,应主动释放媒体链路,停止媒体流的发送;
c)通过Subject标识进行已发送流的清理判断。上级平台向下级平台、平台向设备发送呼叫请求时,应携带Subject头域,Subject头域的“媒体流发送者ID:发送方媒体流序列号”用于对媒体源标识,此标识与请求的码流具有对应关系。下级平台,设备在接收到呼叫请求后,应判断是否在发送以此媒体源标识的码流,若已经在发送,则应释放现有媒体流发送链路并按照请求建立新的媒体流发送链路。
技术实现
本文以大牛直播SDK的Android平台GB28181设备接入模块为例,启动GB28181即注册到国标平台侧,并按照周期发送信条信令:
和心跳相关的参数设置如下:
private int gb28181_reg_expired_ = 3600; // 注册有效期时间最小3600秒 private int gb28181_heartbeat_interval_ = 20; // 心跳间隔GB28181默认是60, 目前调整到20秒 private int gb28181_heartbeat_count_ = 3; // 心跳间隔3次失败,表示和服务器断开了
InitGB28181Agent()的时候,设置下去:
// GB28181配置 gb28181_agent_.config(gb28181_reg_expired_, gb28181_heartbeat_interval_, gb28181_heartbeat_count_);
心跳异常处理如下:
//Author: daniusdk.com @Override public void ntsOnHeartBeatException(int exceptionCount, String lastExceptionInfo) { Log.e(TAG, "ntsOnHeartBeatException heart beat timeout count reached, count:" + exceptionCount+ ", exception info:" + (lastExceptionInfo!=null?lastExceptionInfo:"")); // 停止信令, 然后重启 handler_.postDelayed(new Runnable() { @Override public void run() { Log.i(TAG, "gb28281_heart_beart_timeout"); stopAudioPlayer(); destoryRTPReceiver(); if (gb_broadcast_source_id_ != null && gb_broadcast_target_id_ != null && gb28181_agent_ != null) gb28181_agent_.byeAudioBroadcast(gb_broadcast_source_id_, gb_broadcast_target_id_); gb_broadcast_source_id_ = null; gb_broadcast_target_id_ = null; btnGB28181AudioBroadcast.setText("GB28181语音广播"); btnGB28181AudioBroadcast.setEnabled(false); stopGB28181Stream(); destoryRTPSender(); if (gb28181_agent_ != null) { gb28181_agent_.terminateAllPlays(true); Log.i(TAG, "gb28281_heart_beart_timeout sip stop"); gb28181_agent_.stop(); String local_ip_addr = IPAddrUtils.getIpAddress(context_); if (local_ip_addr != null && !local_ip_addr.isEmpty() ) { Log.i(TAG, "gb28281_heart_beart_timeout get local ip addr: " + local_ip_addr); gb28181_agent_.setLocalAddress(local_ip_addr); } Log.i(TAG, "gb28281_heart_beart_timeout sip start"); gb28181_agent_.start(); } } },0); }
总结
GB28181媒体保活机制,相对比较清晰,不会有大的规范解读误区,感兴趣的开发者,可以参考实现。