• GB28181设备接入端如何实现校时?


    在探讨这个问题之前,我们先看看GB/T28181-2016官方文档怎么说的,9.10.1章节校时基本要求提到:

    联网内设备支持基于SIP方式或 NTP方式的网络校时功能,标准时间为北京时间。

    SIP方式校时见本节具体描述;NTP(见IETFRFC2030)协议的网络统一校时服务,网络校时设备分为时钟源和客户端,支持客户/服务器的工作模式,时钟源应支持 TCP/IP、UDP及 NTP协议,将输入的或是自身产生的时间信号以标准的 NTP信息包格式输出。

    系统运行时可根据配置使用具体校时方式。SIP校时在注册过程中完成

    具体流程如下:

    在注册成功情况下,注册流程的最后一个 SIP应答消息200 OK中的 Date头-域中携带时间信息。

    采用的格式为 XML标准格式:Date:yyyy-MM-dd'T'HH:mm:ss.SSS

    若SIP代理通过注册方式校时,其注册过期时间宜设置为小于SIP代理与 SIP服务器出现1s误差所经过的运行时间。

    例如:SIP代理与SIP服务器校时后,SIP代理运行10h后设备时间与SIP服务器时间相差大于1s,则宜将注册过期时间设置为10h(36000s),以保证SIP代理与SIP服务器之间时 间误差小于1s。

    废话不多说,以我们Android平台GB28181设备接入模块为例,先启动GB28181服务:

    1. class ButtonGB28181AgentListener implements View.OnClickListener {
    2. public void onClick(View v) {
    3. stopAudioPlayer();
    4. destoryRTPReceiver();
    5. gb_broadcast_source_id_ = null;
    6. gb_broadcast_target_id_ = null;
    7. btnGB28181AudioBroadcast.setText("GB28181语音广播");
    8. btnGB28181AudioBroadcast.setEnabled(false);
    9. stopGB28181Stream();
    10. destoryRTPSender();
    11. if (null == gb28181_agent_ ) {
    12. if( !initGB28181Agent() )
    13. return;
    14. }
    15. if (gb28181_agent_.isRunning()) {
    16. gb28181_agent_.terminateAllPlays(true);// 目前测试下来,发送BYE之后,有些服务器会立即发送INVITE,是否发送BYE根据实际情况看
    17. gb28181_agent_.stop();
    18. btnGB28181Agent.setText("启动GB28181");
    19. }
    20. else {
    21. if ( gb28181_agent_.start() ) {
    22. btnGB28181Agent.setText("停止GB28181");
    23. }
    24. }
    25. }
    26. }

    调用initGb28181Agent()实现如下:

    1. /*
    2. * MainActivity.java
    3. * initGB28181Agent
    4. * Github: https://github.com/daniulive/SmarterStreaming
    5. */
    6. private boolean initGB28181Agent() {
    7. if ( gb28181_agent_ != null )
    8. return true;
    9. getLocation(context_);
    10. String local_ip_addr = IPAddrUtils.getIpAddress(context_);
    11. Log.i(TAG, "initGB28181Agent local ip addr: " + local_ip_addr);
    12. if ( local_ip_addr == null || local_ip_addr.isEmpty() ) {
    13. Log.e(TAG, "initGB28181Agent local ip is empty");
    14. return false;
    15. }
    16. gb28181_agent_ = GBSIPAgentFactory.getInstance().create();
    17. if ( gb28181_agent_ == null ) {
    18. Log.e(TAG, "initGB28181Agent create agent failed");
    19. return false;
    20. }
    21. gb28181_agent_.addListener(this);
    22. gb28181_agent_.addPlayListener(this);
    23. gb28181_agent_.addAudioBroadcastListener(this);
    24. gb28181_agent_.addDeviceControlListener(this);
    25. // 必填信息
    26. gb28181_agent_.setLocalAddress(local_ip_addr);
    27. gb28181_agent_.setServerParameter(gb28181_sip_server_addr_, gb28181_sip_server_port_, gb28181_sip_server_id_, gb28181_sip_domain_);
    28. gb28181_agent_.setUserInfo(gb28181_sip_username_, gb28181_sip_password_);
    29. // 可选参数
    30. gb28181_agent_.setUserAgent(gb28181_sip_user_agent_filed_);
    31. gb28181_agent_.setTransportProtocol(gb28181_sip_trans_protocol_==0?"UDP":"TCP");
    32. // GB28181配置
    33. gb28181_agent_.config(gb28181_reg_expired_, gb28181_heartbeat_interval_, gb28181_heartbeat_count_);
    34. com.gb.ntsignalling.Device gb_device = new com.gb.ntsignalling.Device("34020000001380000001", "安卓测试设备", Build.MANUFACTURER, Build.MODEL,
    35. "宇宙","火星1","火星", true);
    36. if (mLongitude != null && mLatitude != null) {
    37. com.gb.ntsignalling.DevicePosition device_pos = new com.gb.ntsignalling.DevicePosition();
    38. device_pos.setTime(mLocationTime);
    39. device_pos.setLongitude(mLongitude);
    40. device_pos.setLatitude(mLatitude);
    41. gb_device.setPosition(device_pos);
    42. gb_device.setSupportMobilePosition(true); // 设置支持移动位置上报
    43. }
    44. gb28181_agent_.addDevice(gb_device);
    45. /*
    46. com.gb28181.ntsignalling.Device gb_device1 = new com.gb28181.ntsignalling.Device("34020000001380000002", "安卓测试设备2", Build.MANUFACTURER, Build.MODEL,
    47. "宇宙","火星1","火星", true);
    48. if (mLongitude != null && mLatitude != null) {
    49. com.gb28181.ntsignalling.DevicePosition device_pos = new com.gb28181.ntsignalling.DevicePosition();
    50. device_pos.setTime(mLocationTime);
    51. device_pos.setLongitude(mLongitude);
    52. device_pos.setLatitude(mLatitude);
    53. gb_device1.setPosition(device_pos);
    54. gb_device1.setSupportMobilePosition(true);
    55. }
    56. gb28181_agent_.addDevice(gb_device1);
    57. */
    58. if (!gb28181_agent_.createSipStack()) {
    59. gb28181_agent_ = null;
    60. Log.e(TAG, "initGB28181Agent gb28181_agent_.createSipStack failed.");
    61. return false;
    62. }
    63. boolean is_bind_local_port_ok = false;
    64. // 最多尝试5000个端口
    65. int try_end_port = gb28181_sip_local_port_base_ + 5000;
    66. try_end_port = try_end_port > 65536 ?65536: try_end_port;
    67. for (int i = gb28181_sip_local_port_base_; i < try_end_port; ++i) {
    68. if (gb28181_agent_.bindLocalPort(i)) {
    69. is_bind_local_port_ok = true;
    70. break;
    71. }
    72. }
    73. if (!is_bind_local_port_ok) {
    74. gb28181_agent_.releaseSipStack();
    75. gb28181_agent_ = null;
    76. Log.e(TAG, "initGB28181Agent gb28181_agent_.bindLocalPort failed.");
    77. return false;
    78. }
    79. if (!gb28181_agent_.initialize()) {
    80. gb28181_agent_.unBindLocalPort();
    81. gb28181_agent_.releaseSipStack();
    82. gb28181_agent_ = null;
    83. Log.e(TAG, "initGB28181Agent gb28181_agent_.initialize failed.");
    84. return false;
    85. }
    86. return true;
    87. }

    注册成功后,回调如下:

    1. @Override
    2. public void ntsRegisterOK(String dateString) {
    3. Log.i(TAG, "ntsRegisterOK Date: " + (dateString!= null? dateString : ""));
    4. }

    回上来的日志如下:

    2022-09-13 11:53:33.163 12889-13101/com.daniulive.smartpublisher I/NTGB28181: ntsRegisterOK Date: 2022-09-13T11:53:32.439

    以上就是GB28181国标设备接入端校时协议规范和相关实现流程,感兴趣的开发者可酌情参考。

  • 相关阅读:
    SHELL脚本学习(十三)初识 gawk 编辑器
    2022.9.25-----leetcode.788
    Clion如何添加头文件?
    小龙虾算法优化极限学习机实现乳腺癌诊断,(COA-ELM)数据分类
    【Linux】系统级文件操作&&文件系统的概念
    LibTorch实战二:MNIST的libtorch代码
    OAK 3D人工智能相机和RealSense系列相机的对比
    【YOLOv5】手把手教你使用LabVIEW ONNX Runtime部署 TensorRT加速,实现YOLOv5实时物体识别(含源码)
    MySQL 内置函数
    【问题记录】解决Git上传文件到GitHub时收到 “GH001: Large files detected” 错误信息!
  • 原文地址:https://blog.csdn.net/renhui1112/article/details/126944316