GB28181标准制定多年,应用也逐渐广泛,从传统固定的摄像头到可移动的设备,对于前端设备的形态要求也十分多样化。比如单兵,车载等行业领域,传统的摄像头无法满足其便携性,以及丰富的功能接口要求。
单兵,车载,以及执法仪等使用场景,除了对设备端的便携性外,对于网络的布局基本都是4G/5G的环境,即设备都使用运营商提供的4G物联网卡,对于网络互联互通以及视音频的质量也提出了很高的要求。
对于GB28181在于公网的使用,除了GB28181-2016的完善外,其实对于技术的实现也是一个变革,如何在低带宽,不可靠的连接下实现流畅音视频交互是作为移动GB28181设备端很有意义的事情。
从数据流通信来讲,设备端与国标平台的交互主要是sip信令和媒体流(rtp/ps流),设备端做的人性化一点自然会提供web配置页面,那么对外也提供http的访问协议。所以其数据流图如下:
、
我们完整的实现了设备端全部的GB28181协议,这个协议比较多,因为我们的实现不仅仅是音视频,对讲,云台,录像,报警,位置定位 等功能模块都需要。
但是国标设备端是一个被动性的终端,几乎所有GB28181的业务发起都是被动的,被客户端发起的(比如被预览,对讲,都是受控于客户端的,无需设备端主动发起交互),所以功能很多,但是其实封装成sdk,接口反而很简单。主要是一些配置接口,比如设置对讲模式(可以使用默认模式,我们支持外网对讲),配置接口完成后,只需要注册接口注册到平台上之后就可以坐等奇迹的出现了,后面的业务都是接收平台的GB信令,进行对应的响应了。
将GB28181设备端实现封装成sdk后,接口如下:
//注册到国标平台
public int open(String serverip,String localip,int serverport,int localport,String serverid,String userid,String userpwd);
//退出注册
public void close();
//设置设备的经纬度位置
setPosition( double longitude,double latitude);
//开启采集音视流
public boolean start(int cameraId, SurfaceHolder surfaceHolder);
//停止采集音视频流
public void stop();
其实注册上平台后,就已经大功告成,调用代码如下:
public void startCapture() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String channelid = sharedPrefs.getString("channelID", "");
String localip = sharedPrefs.getString("localip", "");
int localport = PreferenceUtil.getPrefInt(sharedPrefs, "port", 5860);
int talkprotocol = PreferenceUtil.getPrefInt(sharedPrefs, "protocol", 3);
boolean isEnableTalk = PreferenceUtil.getPrefBoolean(sharedPrefs, "enabletalk", false);
GbtDeviceJni.gbtdevice_setTalkEnable(isEnableTalk);
//视频设置
int pix_index = PreferenceUtil.getPrefInt(sharedPrefs, "video_pix", 0);
int frame_rate = PreferenceUtil.getPrefInt(sharedPrefs, "video_framerate", 15);
int video_rate = PreferenceUtil.getPrefInt(sharedPrefs, "video_rate", 512);
int video_gop = PreferenceUtil.getPrefInt(sharedPrefs, "video_gop", 2);
int video_codec = PreferenceUtil.getPrefInt(sharedPrefs, "video_codec", 0);
int audio_codec = PreferenceUtil.getPrefInt(sharedPrefs, "audio_codec", 0);
int width = 640;
int height = 480;
if(pix_index == 0)
{
width = 640;
height = 480;
}
else if(pix_index == 1)
{
width = 1280;
height = 720;
}
else if(pix_index == 2)
{
width = 1920;
height = 1080;
}
else if(pix_index == 3)
{
width = 3840;
height = 2160;
}
MFormat fmt = new MFormat();
fmt.width = width;
fmt.height = height;
if(video_codec == 0)
fmt.codec = MediaType.MCODEC_H264;
else
fmt.codec = MediaType.MCODEC_H265;
fmt.fps = frame_rate;
fmt.gop = video_gop;
fmt.bitrate = 1024 * video_rate;
if(audio_codec == 1)
fmt.audioCodec = MediaType.MCODEC_G711U;
else if(audio_codec == 2)
fmt.audioCodec = MediaType.MCODEC_AAC;
else
fmt.audioCodec = MediaType.MCODEC_G711A;
fmt.channels = 1;
fmt.sampleRate = 8000;
gbtdevice = SYGbtDeviceApp.getInstance().gbtdevice;
gbtdevice.setFormat(fmt);
//字幕叠加
configOsd();
if(localip == null || localip.equals("") )
localip = NetUtil.getLocalAddr(this);
if(localip == null)
{
localip = "0.0.0.0";
showToast("请确认该设备网络是否已连接.");
}
int cameraId = 0;
String serverip = m_serverip.getText().toString();
String serverid = m_serverid.getText().toString();
String userid = m_userid.getText().toString();
String userpwd = m_userpwd.getText().toString();
int serverport = Integer.parseInt(m_serverport.getText().toString());
//注册成功回调
GbtTrack.setloginhandler(sthandler);
//采集画面和显示画面旋转90度
gbtdevice.setRotation(90);
gbtdevice.setDisplayOrientation(90);
//注册到GB平台
int ret = gbtdevice.open(serverip,localip,serverport,localport,serverid,userid,userpwd);
if (ret == 0) {
//打开音视频采集流
boolean isStart = gbtdevice.start(cameraId, surfaceView.getHolder());
if(isStart == false)
{
showToast("该设备的camera不支持该分辨率!");
gbtdevice.close();
gbtdevice = null;
return;
}
}
else if(ret == -1)
{
showToast("camera打开 失败.");
}
else if(ret == -2)
{
showToast("GB28181注册 失败.");
}
else
{
showToast("其他未知错误.");
}
//设置对讲模式,我们支持外网对讲
GbtDeviceJni.gbtdevice_setTalkMode(gbtdevice.GetDeviceHandle(), talkprotocol);
SharedPreferences settings = this.getSharedPreferences(this.getClass().getName(), 0);
Editor editor = settings.edit();
editor.putString("serveripd", m_serverip.getText().toString());
editor.putString("serverport", m_serverport.getText().toString());
editor.putString("serverid", m_serverid.getText().toString());
editor.putString("userid", m_userid.getText().toString());
editor.putString("userpwd", m_userpwd.getText().toString());
editor.commit();
}
调用的代码很简单,但是功能还是很丰富的,以上实现了全套的GB28181设备端的协议,对于一些公网使用情况并进行了优化和扩展,比如支持外网的持续对讲,对讲时支持回声消除。
下载测试:http://www.founu.com/a/product/gb28181/30.html
主要功能:
1.H264/H265 多分辨率码率的音视频预览
2.4G外网的双向对讲,回声消除
3.录像回放和录像下载
4.报警上报
5.位置信息订阅
通过以上代码函数,就可以实现注册到GB28181平台,然后可以进行呼叫和对讲了。如下图:
更多信息
e-mail: yujesoft@163.com
tel: 13971177602
web:www.founu.com