大家都知道,无人机巡检系统,有效解决了传统巡查工作空间和时间局限问题,降低人力工作成本,有效替代人工巡检工作模式。智能巡检系统通过人工智能技术和机械智能技术完美结合,在工业等场景下,应用非常广泛。本文旨在讲如何实现无人机(如大疆无人机)数据到GB28181平台(如海康、大华、宇视等国标平台)。

本文以Android平台接入大疆无人机为例,首先,无人机可以通过厂商提供的接口,回调编码后的H.264/H.265数据,需要注意的是,由于GB/T28181-2016,官方规范,仅对H.264做过描述,考虑到系统通用性和尽可能的规避转码带来的性能或使用体验问题,一般建议H.264编码。

无人机的数据会上来后,可以通过编码后的数据接口,投递到JNI层,把视音频数据封装成PS包,让把PS包以负载的方式封装成RTP包,完成媒体数据的上传即可。

本文以转发的模块为例说明,无图无真相:

具体实现:APP启动后,我们先点击启动GB28181按钮,完成到国标平台的注册,并通过心跳机制,保持和国标平台端的通信。

当国标平台端,需要查看无人机的实时画面时,可以发送Invite,请求无人机画面,Android平台GB28181接入模块,这时启动拉取无人机回调数据,并完成数据投递,和H.264到PS到RTP的打包上传即可。

/*
* MainActivity.java
* GitHub: https://github.com/daniulive/SmarterStreaming
*/
class ButtonGB28181AgentListener implements OnClickListener {public void onClick(View v) {stopGB28181Stream();destoryRTPSender();if (null == gb28181_agent_ ) {if( !initGB28181Agent() )return;}if (gb28181_agent_.isRunning()) {gb28181_agent_.terminateAllPlays(true);// 目前测试下来,发送BYE之后,有些服务器会立即发送INVITE,是否发送BYE根据实际情况看gb28181_agent_.stop();btnGB28181Agent.setText("启动GB28181");}else {if ( gb28181_agent_.start() ) {btnGB28181Agent.setText("停止GB28181");}}}
}//停止GB28181 媒体流
private void stopGB28181Stream() {if(!isGB28181StreamRunning)return;if (libPublisher != null) {libPublisher.StopGB28181MediaStream(publisherHandle);}if (!isRecording && !isRTSPPublisherRunning && !isPushing) {if (publisherHandle != 0) {if (libPublisher != null) {libPublisher.SmartPublisherClose(publisherHandle);publisherHandle = 0;}}}isGB28181StreamRunning = false;
}

开放的video数据投递接口如下:

/*** 设置编码后视频数据(H.264)** @param codec_id, H.264对应 1** @param data 编码后的video数据** @param size data length** @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0.** @param timestamp video timestamp** @param pts Presentation Time Stamp, 显示时间戳** @return {0} if successful*/
public native int SmartPublisherPostVideoEncodedData(long handle, int codec_id, ByteBuffer data, int size, int is_key_frame, long timestamp, long pts);

如果还有audio的话,audio数据接口如下:

/*** 设置音频数据(AAC/PCMA/PCMU/SPEEX)** @param codec_id:**  NT_MEDIA_CODEC_ID_AUDIO_BASE = 0x10000,* NT_MEDIA_CODEC_ID_PCMA = NT_MEDIA_CODEC_ID_AUDIO_BASE,* NT_MEDIA_CODEC_ID_PCMU,* NT_MEDIA_CODEC_ID_AAC,* NT_MEDIA_CODEC_ID_SPEEX,* NT_MEDIA_CODEC_ID_SPEEX_NB,* NT_MEDIA_CODEC_ID_SPEEX_WB,* NT_MEDIA_CODEC_ID_SPEEX_UWB,** @param data audio数据** @param size data length** @param is_key_frame 是否I帧, if with key frame, please set 1, otherwise, set 0, audio忽略** @param timestamp video timestamp** @param parameter_info 用于AAC special config信息填充** @param parameter_info_size parameter info size** @return {0} if successful*/
public native int SmartPublisherPostAudioEncodedData(long handle, int codec_id, ByteBuffer data, int size, int is_key_frame, long timestamp,ByteBuffer parameter_info, int parameter_info_size);

其他信令交互流程前面提到很多次了,本文不再赘述,这里主要看看Invite和Ack的处理:

先看Invite处理:

@Overridepublic void ntsOnInvitePlay(String deviceId, PlaySessionDescription session_des) {handler_.postDelayed(new Runnable() {@Overridepublic void run() {MediaSessionDescription video_des = session_des_.getVideoDescription();SDPRtpMapAttribute ps_rtpmap_attr = video_des.getPSRtpMapAttribute();Log.i(TAG,"ntsInviteReceived, device_id:" +device_id_+", is_tcp:" + video_des.isRTPOverTCP()+ " rtp_port:" + video_des.getPort() + " ssrc:" + video_des.getSSRC()+ " address_type:" + video_des.getAddressType() + " address:" + video_des.getAddress());// 可以先给信令服务器发送临时振铃响应//sip_stack_android.respondPlayInvite(180, device_id_);long rtp_sender_handle = libPublisher.CreateRTPSender(0);if ( rtp_sender_handle == 0 ) {gb28181_agent_.respondPlayInvite(488, device_id_);Log.i(TAG, "ntsInviteReceived CreateRTPSender failed, response 488, device_id:" + device_id_);return;}gb28181_rtp_payload_type_  = ps_rtpmap_attr.getPayloadType();gb28181_rtp_encoding_name_ =  ps_rtpmap_attr.getEncodingName();libPublisher.SetRTPSenderTransportProtocol(rtp_sender_handle, video_des.isRTPOverUDP()?0:1);libPublisher.SetRTPSenderIPAddressType(rtp_sender_handle, video_des.isIPv4()?0:1);libPublisher.SetRTPSenderLocalPort(rtp_sender_handle, 0);libPublisher.SetRTPSenderSSRC(rtp_sender_handle, video_des.getSSRC());libPublisher.SetRTPSenderSocketSendBuffer(rtp_sender_handle, 2*1024*1024); // 设置到2MlibPublisher.SetRTPSenderClockRate(rtp_sender_handle, ps_rtpmap_attr.getClockRate());libPublisher.SetRTPSenderDestination(rtp_sender_handle, video_des.getAddress(), video_des.getPort());if ( libPublisher.InitRTPSender(rtp_sender_handle) != 0 ) {gb28181_agent_.respondPlayInvite(488, device_id_);libPublisher.DestoryRTPSender(rtp_sender_handle);return;}int local_port = libPublisher.GetRTPSenderLocalPort(rtp_sender_handle);if (local_port == 0) {gb28181_agent_.respondPlayInvite(488, device_id_);libPublisher.DestoryRTPSender(rtp_sender_handle);return;}Log.i(TAG,"get local_port:" + local_port);String local_ip_addr = IPAddrUtils.getIpAddress(context_);gb28181_agent_.respondPlayInviteOK(device_id_,local_ip_addr, local_port);gb28181_rtp_sender_handle_ = rtp_sender_handle;}private String device_id_;private PlaySessionDescription session_des_;public Runnable set(String device_id, PlaySessionDescription session_des) {this.device_id_ = device_id;this.session_des_ = session_des;return this;}}.set(deviceId, session_des),0);}@Overridepublic void ntsOnCancelPlay(String deviceId) {// 这里取消Play会话handler_.postDelayed(new Runnable() {@Overridepublic void run() {Log.i(TAG, "ntsOnCancelPlay, deviceId=" + device_id_);destoryRTPSender();}private String device_id_;public Runnable set(String device_id) {this.device_id_ = device_id;return this;}}.set(deviceId),0);}

Ack后调用StartGB28181MediaStream(),开始发送大疆无人机编码后的数据到国标平台端。

@Override
public void ntsOnAckPlay(String deviceId) {handler_.postDelayed(new Runnable() {@Overridepublic void run() {Log.i(TAG,"ntsOnACKPlay, device_id:" +device_id_);if (!isRecording && !isRTSPPublisherRunning && !isPushing) {OpenPushHandle();}libPublisher.SetGB28181RTPSender(publisherHandle, gb28181_rtp_sender_handle_, gb28181_rtp_payload_type_, gb28181_rtp_encoding_name_);int startRet = libPublisher.StartGB28181MediaStream(publisherHandle);if (startRet != 0) {if (!isRecording && !isRTSPPublisherRunning && !isPushing) {if (publisherHandle != 0) {libPublisher.SmartPublisherClose(publisherHandle);publisherHandle = 0;}}destoryRTPSender();Log.e(TAG, "Failed to start GB28181 service..");return;}isGB28181StreamRunning = true;}private String device_id_;public Runnable set(String device_id) {this.device_id_ = device_id;return this;}}.set(deviceId),0);
}

需要注意的是,可以在国标平台端发起Invite请求,到Ack完成后,才开始调用大疆无人机的接口回调H.264数据,有些型号的无人机,也可以回调编码前的yuv/nv12等格式数据,这种我们也可以处理,自己编码即可。

由于无人机的特殊性,携带经纬度信息,也可以通过GB28181位置订阅(MobilePosition)实现无人机实时位置的更新。

GB28181平台如何接入无人机实现智能巡检?相关推荐

  1. 【解决方案】国标GB28181平台EasyGBS级联EasyCVR视频智能分析搭建“蓝天卫士”网络视频监控系统技术方案

    一.背景分析 当前,现代工农业的迅速发展在为社会创造了丰富的物质财富的同时,也对自然环境和人类健康造成了日益严重的危害,并导致了资源短缺.环境污染.生态破坏.随着中国经济环境的改善和能源环境结构调整, ...

  2. 无人机工程安全巡检具体如何实践?

    无人机技术的快速发展使得其在各行各业都得到了广泛的应用,其中无人机工程安全巡检也成为了重要的应用场景.本文将为大家介绍无人机工程安全巡检的具体实践指南,以确保无人机工程安全巡检工作的顺利进行. 一.无 ...

  3. 基于机智云平台的泵站智能巡检系统

    本文是由开发者设计开发的一款泵站智能巡检系统.该系统改变了常规的专人值守的工作模式,实现泵站运行状态的远程智能巡检工作,达到自动监测.故障报警.提前预测等功能. 随着我国水利事业不断发展,泵站在水利调 ...

  4. 无人机智能巡检系统及功能介绍

    目前,矿区的日常巡检内容主要包括巡查矿区周边是否存在盗采.滥采.周围地形地貌条件等.矿区的日常巡检是整个矿区管理中十分重要的一个环节,但现阶段的巡检管理方式还存在一些难点.在面临恶劣天气和环境时,人工 ...

  5. 【解决方案】电力巡检进入智能化时代,无人机+EasyDSS开启智能巡检新模式

    一.方案背景 随着国家的发展和社会的进步,人们的日常生活越来越不能离开电力,而我国电网建设在速度和规模上都已经飞速发展,这使得我国的电网规模跃居到了世界首位.国电建设除了规模和发展速度超前之外,还要保 ...

  6. 加快无人机智能巡检规模化应用,福建电力输电运检智能化建设提速

    如今,无人机辅助人工巡检.图像抓拍摄像头等手段已在线路巡视中起到重要支撑作用. 出品 | 常言道 作者 | 丁常彦 小暑过,三伏至.我国一年中最热的时节,已经悄然开启.连日来,福建省大部分地区出现超过 ...

  7. 【解决方案】基于国标GB28181协议/HIKSDK/Ehome协议EasyCVR智能融合分析平台在智慧校园人脸识别中的应用

    一.建设背景 随着社会的发展,学校规模不断扩大,给校园的安全和科学管理带来了非常大的挑战:随着学校的开放性管理,特别是高校,进出人员复杂,给学校的人员财产安全管理,带来了非常大的挑战.学校安保工作越来 ...

  8. 无人机智能巡检软件设计

    无人机智能巡检软件设计 研究生期间做的一个项目,第一次接触Android应用开发,自学了Java和Android,也学习了计算机网络相关的知识,过程虽然曲折总的来说收获满满,下面就总结一下. 1.项目 ...

  9. 无人机智能巡检系统的功能有哪些?

    目前,矿区的日常巡检工作主要包括巡查矿区周边是否存在盗采.滥采.周围地形地貌条件等内容.矿区的日常巡检是整个矿区管理中十分重要的部分,但现阶段的巡检管理方式还存在一些问题.在面临恶劣天气和环境时,人工 ...

最新文章

  1. 一文理解微服务架构下的系统可用性如何保证?
  2. Activiti工作流入门
  3. 数据结构稀疏矩阵的加法十字链表_学习数据结构和算法的框架思维
  4. Drupal 通过API动态的加入样式文件
  5. JavaScript异步
  6. iOS 11 正式版发布,都有哪些新内容?
  7. android 版本更新下载进度框,Android版本更新(Service下载 Notification进度条)
  8. 算法设计与分析期末复习题(史上最详细)
  9. 逆向四、JEB的使用
  10. 一些时间日期函数,转自华软
  11. 含论文基于JAVA户籍信息管理系统【数据库设计、论文、源码、开题报告】
  12. 【Linux】scp命令基本使用
  13. 【FPGA】十一、I2C通信回环
  14. zabbix主动监控和被动监控
  15. proxifier 代理bluestack
  16. 不狠狠逼一下自己,永远不知道自己有多么强大
  17. 处理RAW格式的图像,需要什么软件?
  18. GPRSsim800c
  19. Facebook首席产品官和WhatsApp副总裁即将离职
  20. 什么是TE,MT,ME

热门文章

  1. 浏览器 unload beforunload事件不触发
  2. 如何使用miniconda(小白入门版)
  3. JavaScript 获取当前日期——JS 中的今天日期
  4. 端口渗透—23端口Telnet
  5. css弹性盒模型详解----flex-direction
  6. 【HTML】表单隐藏域hidden
  7. DAT NAT SAN FCoE
  8. 单片机IO口悬空,高阻态究竟是什么意思?
  9. 【树莓派4B深度学习 垃圾分类】Chap.3 树莓派安装opencv并测试视频接口实时视频流的垃圾分类【深度学习 招式篇】
  10. SAP 更改登录界面图片