规范解读
GB28181-2016和GB28181-2022关于媒体保活机制这块,并无调整,平台、设备媒体流保活机制规定如下:
a)链路建立后,码流经过的各级平台应具备媒体流丢失监测能力,若监测到媒体流丢失,应释放该条媒体链路,并通过会话内Bye消息通知上下级平台;
b)上下级平台之间、平台与设备之间、平台与客户端之间应通过注册,状态信息报送等进行状态监测,若监测到媒体流接收方或媒体流发送方故障或离线,应主动释放媒体链路,停止媒体流的发送;
c)通过Subject标识进行已发送流的清理判断。上级平台向下级平台、平台向设备发送呼叫请求时,应携带Subject头域,Subject头域的“媒体流发送者ID:发送方媒体流序列号”用于对媒体源标识,此标识与请求的码流具有对应关系。下级平台,设备在接收到呼叫请求后,应判断是否在发送以此媒体源标识的码流,若已经在发送,则应释放现有媒体流发送链路并按照请求建立新的媒体流发送链路。
技术实现
本文以大牛直播SDK的Android平台GB28181设备接入模块为例,启动GB28181即注册到国标平台侧,并按照周期发送信条信令:
和心跳相关的参数设置如下:
代码语言:javascript复制private int gb28181_reg_expired_ = 3600; // 注册有效期时间最小3600秒
private int gb28181_heartbeat_interval_ = 20; // 心跳间隔GB28181默认是60, 目前调整到20秒
private int gb28181_heartbeat_count_ = 3; // 心跳间隔3次失败,表示和服务器断开了
InitGB28181Agent()的时候,设置下去:
代码语言:javascript复制// GB28181配置
gb28181_agent_.config(gb28181_reg_expired_, gb28181_heartbeat_interval_, gb28181_heartbeat_count_);
心跳异常处理如下:
代码语言:javascript复制//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媒体保活机制,相对比较清晰,不会有大的规范解读误区,感兴趣的开发者,可以参考实现。