Android平台GB28181执法记录仪技术方案

news2024/11/14 21:24:14

技术背景

我们在做Android平台GB28181设备接入模块的时候,对接过好多开发者,他们都是用于执法记录仪场景,执法记录仪是一种便携式设备,用于记录执法人员的行动和接触情况,通过实时回传音视频数据和实时位置信息给指挥中心,把现场的情况实时反馈给指挥中心,指挥中心可以通过语音广播和语音对讲,实现和前端执法人员的音视频通话。

GB28181执法记录仪由以下几个部分组成:

1. 硬件选型:选择符合GB28181标准的执法记录仪设备,具备高清晰度摄像、音频采集和存储的能力。设备应具备稳定的网络连接和数据传输能力。

2. 设备接入:执法记录仪通过网络接入到GB28181视频监控系统中。可以通过设备的唯一标识和密码完成设备的注册和鉴权,以便在系统中实现执法记录仪的统一管理和控制。

3. 视频和音频流配置:配置执法记录仪的视频和音频编码参数,如分辨率、帧率、比特率等。确保符合GB28181标准的音视频编码要求。

4. 流媒体传输:执法记录仪通过GB28181的媒体流传输协议(如RTP/RTCP)将视频和音频流上传到视频监控系统中。可以使用TCP或UDP作为传输协议,并通过相关配置确保流媒体传输的稳定性和实时性。

5. 存储和管理:执法记录仪设备应具备足够的存储容量,可将视频和音频数据保存在本地存储设备中。同时,支持对存储内容进行管理和检索,例如按时间、地点和事件等对存储的媒体数据进行分类和查询。

6. 控制和控制中心:通过GB28181的信令协议(如SIP)进行设备的远程控制。支持对执法记录仪的实时预览、录制、拍照和上传等操作。控制中心可以集中管理和控制多个执法记录仪设备,并对其进行配置和命令下发。

技术实现

针对Android平台GB28181执法记录仪场景,大牛直播SDK设计的功能如下:

  •  [视频格式]H.264/H.265(Android H.265硬编码);
  •  [音频格式]G.711 A律、AAC;
  •  [音量调节]Android平台采集端支持实时音量调节;
  •  [H.264硬编码]支持H.264特定机型硬编码;
  •  [H.265硬编码]支持H.265特定机型硬编码;
  •  [软硬编码参数配置]支持gop间隔、帧率、bit-rate设置;
  •  [软编码参数配置]支持软编码profile、软编码速度、可变码率设置;
  •  支持横屏、竖屏推流;
  •  Android平台支持后台service推送屏幕(推送屏幕需要5.0+版本);
  • 支持纯视频、音视频PS打包传输;
  • 支持RTP OVER UDP和RTP OVER TCP被动模式(TCP媒体流传输客户端);
  • 支持信令通道网络传输协议TCP/UDP设置;
  • 支持注册、注销,支持注册刷新及注册有效期设置;
  • 支持设备目录查询应答;
  • 支持心跳机制,支持心跳间隔、心跳检测次数设置;
  • 支持移动设备位置(MobilePosition)订阅和通知;
  •  适用国家标准:GB/T 28181—2016;
  • 支持语音广播;
  • 支持语音对讲;
  • 支持历史视音频文件检索;
  • 支持历史视音频文件下载;
  • 支持云台控制和预置位查询;
  •  [实时水印]支持动态文字水印、png水印;
  •  [镜像]Android平台支持前置摄像头实时镜像功能;
  •  [实时静音]支持实时静音/取消静音;
  •  [实时快照]支持实时快照;
  •  [降噪]支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD检测;
  •  [外部编码前视频数据对接]支持YUV数据对接;
  •  [外部编码前音频数据对接]支持PCM对接;
  •  [外部编码后视频数据对接]支持外部H.264数据对接;
  •  [外部编码后音频数据对接]外部AAC数据对接;
  •  [扩展录像功能]支持和录像模块组合使用,录像相关功能。

接口详解

以Android平台Camera2对接为例,信令部分需要实现如下标红接口:

public class MainActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener, Camera2Listener,
        GBSIPAgentListener, GBSIPAgentPlayListener, GBSIPAgentAudioBroadcastListener,
        GBSIPAgentDeviceControlListener, GBSIPAgentQueryCommandListener, GBSIPAgentTalkListener{
}

媒体数据处理接口,可参照SmartPublisherJniV2.java,如需语音广播或语音对讲,可参照SmartPlayerJniV2.java。

信令处理

GBSIPAgentListener主要系GB28181注册、心跳、DevicePosition等,如注册成功、注册超时、注册网络传输层错误、心跳异常、设备位置请求处理:

public interface GBSIPAgentListener
{
    /*注册成功
    * @param dateString: 服务器日期,用来校准设备端时间,用户自行决定是否校准设备时间
    */
    void ntsRegisterOK(String dateString);

    /*
    *注册超时
    */
    void ntsRegisterTimeout();

    /*
    *注册网络传输层异常
    */
    void ntsRegisterTransportError(String errorInfo);

    /*
    *心跳达到异常次数
    */
    void ntsOnHeartBeatException(int exceptionCount, String lastExceptionInfo);

    /*
     * 设备位置请求, 这个主要用在移动设备位置订阅上
     * @param interval 请求间隔, 单位是毫秒
     */
    void ntsOnDevicePositionRequest(String deviceId, int interval);
}

GBSIPAgentPlayListener主要系GB28181的Invite、Ack、Bye等处理:

public interface GBSIPAgentPlayListener {

    /*
     *收到s=Play的实时视音频点播
     */
    void ntsOnInvitePlay(String deviceId, SessionDescription sessionDescription);

    /*
     *发送play invite response 异常
     */
    void ntsOnPlayInviteResponseException(String deviceId, int statusCode, String errorInfo);

    /*
     * 收到CANCEL play INVITE请求
     */
    void ntsOnCancelPlay(String deviceId);

    /*
     * 收到Ack
     */
    void ntsOnAckPlay(String deviceId);

    /*
     * 收到Bye
     */
    void ntsOnByePlay(String deviceId);

    /*
     * 不是在收到BYE Message情况下, 终止Play
     */
    void ntsOnTerminatePlay(String deviceId);

    /*
     * Play会话对应的对话终止, 一般不会出发这个回调,目前只有在响应了200K, 但在64*T1时间后还没收到ACK,才可能会出发
    收到这个, 请做相关清理处理
    */
    void ntsOnPlayDialogTerminated(String deviceId);
}

GBSIPAgentAudioBroadcastListener主要系GB28181语音广播处理相关,如有语音广播相关需求,可参照demo实例实现:

public interface GBSIPAgentAudioBroadcastListener {

    /*
     *收到语音广播通知
     */
    void ntsOnNotifyBroadcastCommand(String fromUserName, String fromUserNameAtDomain, String sn, String sourceID, String targetID);

    /*
     *需要准备接受语音广播的SDP内容
     */
    void ntsOnAudioBroadcast(String commandFromUserName, String commandFromUserNameAtDomain, String sourceID, String targetID);

    /*
     *音频广播, 发送Invite请求异常
     */
    void ntsOnInviteAudioBroadcastException(String sourceID, String targetID, String errorInfo);

    /*
     *音频广播, 等待Invite响应超时
     */
    void ntsOnInviteAudioBroadcastTimeout(String sourceID, String targetID);

    /*
     *音频广播, 收到Invite消息最终响应
     */
    void ntsOnInviteAudioBroadcastResponse(String sourceID, String targetID, int statusCode, SessionDescription sessionDescription);

    /*
     * 音频广播, 收到BYE Message
     */
    void ntsOnByeAudioBroadcast(String sourceID, String targetID);


    /*
     * 不是在收到BYE Message情况下, 终止音频广播
     */
    void ntsOnTerminateAudioBroadcast(String sourceID, String targetID);
}

GBSIPAgentDeviceControlListener主要系GB28181设备控制相关,比如远程启动、云台控制:

public interface GBSIPAgentDeviceControlListener {

    /*
     * 收到远程启动控制命令
     */
    void ntsOnDeviceControlTeleBootCommand(String deviceId, String teleBootValue);

    /*
    * 云台控制
     */
    void ntsOnDeviceControlPTZCmd(String deviceId, String typeValue);
}

GBSIPAgentQueryCommandListener主要系GB28181查询命令,如预置位查询:

public interface GBSIPAgentQueryCommandListener {

    /*
     * 设备预置位查询
     */
    void ntsOnDevicePresetQueryCommand(String fromUserName, String fromUserNameAtDomain, String sn, String deviceId);
}

GBSIPAgentTalkListener主要系GB28181语音对讲相关处理:

public interface GBSIPAgentTalkListener {
    /*
     *收到s=Talk 语音对讲
     */
    void ntsOnInviteTalk(String deviceId, SessionDescription sessionDescription);

    /*
     *发送talk invite response 异常
     */
    void ntsOnTalkInviteResponseException(String deviceId, int statusCode, String errorInfo);

    /*
     * 收到CANCEL Talk INVITE请求
     */
    void ntsOnCancelTalk(String deviceId);

    /*
     * 收到Ack
     */
    void ntsOnAckTalk(String deviceId);

    /*
     * 收到Bye
     */
    void ntsOnByeTalk(String deviceId);

    /*
     * 不是在收到BYE Message情况下, 终止Talk
     */
    void ntsOnTerminateTalk(String deviceId);

    /*
     * Talk会话对应的对话终止, 一般不会出发这个回调,目前只有在响应了200K, 但在64*T1时间后还没收到ACK,才可能会出发
    收到这个, 请做相关清理处理
    */
    void ntsOnTalkDialogTerminated(String deviceId);
}

媒体数据处理

RTP数据发送

RTP Sender(SmartPublisherJniV2.java)相关接口设计:

/*
 * SmartPublisherJniV2.java
 * Author: https://daniusdk.com
 */
/*
 * 创建RTP Sender实例
 *
 * @param reserve:保留参数传0
 *
 * @return RTP Sender 句柄,0表示失败
 */
public native long CreateRTPSender(int reserve);

/**
 *设置 RTP Sender传输协议
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param transport_protocol, 0:UDP, 1:TCP, 默认是UDP
 *
 * @return {0} if successful
 */
public native int SetRTPSenderTransportProtocol(long rtp_sender_handle, int transport_protocol);

/**
 *设置 RTP Sender IP地址类型
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param ip_address_type, 0:IPV4, 1:IPV6, 默认是IPV4, 当前仅支持IPV4
 *
 * @return {0} if successful
 */
public native int SetRTPSenderIPAddressType(long rtp_sender_handle, int ip_address_type);

/**
 *设置 RTP Sender RTP Socket本地端口
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param port, 必须是偶数,设置0的话SDK会自动分配, 默认值是0
 *
 * @return {0} if successful
 */
public native int SetRTPSenderLocalPort(long rtp_sender_handle, int port);

/**
 *设置 RTP Sender SSRC
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败
 *
 * @return {0} if successful
 */
public native int SetRTPSenderSSRC(long rtp_sender_handle, String ssrc);

/**
 *设置 RTP Sender RTP socket 发送Buffer大小
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param buffer_size, 必须大于0, 默认是512*1024, 当前仅对UDP socket有效, 根据视频码率考虑设置合适的值
 *
 * @return {0} if successful
 */
public native int SetRTPSenderSocketSendBuffer(long rtp_sender_handle, int buffer_size);

/**
 *设置 RTP Sender RTP时间戳时钟频率
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param clock_rate, 必须大于0, 对于GB28181 PS规定是90kHz, 也就是90000
 *
 * @return {0} if successful
 */
public native int SetRTPSenderClockRate(long rtp_sender_handle, int clock_rate);

/**
 *设置 RTP Sender 目的IP地址, 注意当前用在GB2818推送上,只设置一个地址,将来扩展如果用在其他地方,可能要设置多个目的地址,到时候接口可能会调整
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param address, IP地址
 * @param port, 端口
 *
 * @return {0} if successful
 */
public native int SetRTPSenderDestination(long rtp_sender_handle, String address, int port);

/**
 * 设置是否开启 RTP Receiver
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param is_enable, 0表示不收RTP包, 1表示收RTP包, SDK默认值为0.
 * @return
 */
public native int EnableRTPSenderReceive(long rtp_sender_handle, int is_enable);

/**
 *设置RTP Receiver SSRC
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败
 *
 * @return {0} if successful
 */
public native int SetRTPSenderReceiveSSRC(long rtp_sender_handle, String ssrc);

/**
 *设置RTP Receiver Payload 相关信息
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @param payload_type, 请参考 RFC 3551
 *
 * @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 可能传null就好
 *
 * @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频
 *
 * @param clock_rate, 请参考 RFC 3551
 *
 * @return {0} if successful
 */
public native int SetRTPSenderReceivePayloadType(long rtp_sender_handle, int payload_type, String encoding_name, int media_type, int clock_rate);

/**
 *设置RTP Receiver PS的pts和dts clock frequency
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @param ps_clock_frequency, 默认是90000, 一些特殊场景需要设置
 *
 * @return {0} if successful
 */
public native int SetRTPSenderReceivePSClockFrequency(long rtp_sender_handle, int ps_clock_frequency);

/**
 *设置 RTP Receiver 音频采样率
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param sampling_rate, 音频采样率
 *
 * @return {0} if successful
 */
public native int SetRTPSenderReceiveAudioSamplingRate(long rtp_sender_handle, int sampling_rate);

/**
 *设置 RTP Receiver 音频通道数
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param channels, 音频通道数
 *
 * @return {0} if successful
 */
public native int SetRTPSenderReceiveAudioChannels(long rtp_sender_handle, int channels);

/**
 *初始化RTP Sender, 初始化之前先调用上面的接口配置相关参数
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @return {0} if successful
 */
public native int InitRTPSender(long rtp_sender_handle);

/**
 *获取RTP Sender RTP Socket本地端口
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @return 失败返回0, 成功的话返回响应的端口, 请在InitRTPSender返回成功之后调用
 */
public native int GetRTPSenderLocalPort(long rtp_sender_handle);

/**
 * UnInit RTP Sender
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @return {0} if successful
 */
public native int UnInitRTPSender(long rtp_sender_handle);

/**
 * 释放RTP Sender, 释放之后rtp_sender_handle就无效了,请不要再使用
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 *
 * @return {0} if successful
 */
public native int DestoryRTPSender(long rtp_sender_handle);

RTP数据接收

对应RTP Receiver(SmartPlayerJniV2.java)相关接口设计,如无语音广播或语音对讲相关技术需求,这部分可忽略:

/*
 * SmartPlayerJniV2.java
 * Author: https://daniusdk.com
 */
/*
 * 创建RTP Receiver
 *
 * @param reserve:保留参数传0
 *
 * @return RTP Receiver 句柄,0表示失败
 */
public native long CreateRTPReceiver(int reserve);


/**
 *设置 RTP Receiver传输协议
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param transport_protocol, 0:UDP, 1:TCP, 默认是UDP
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverTransportProtocol(long rtp_receiver_handle, int transport_protocol);


/**
 *设置 RTP Receiver IP地址类型
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param ip_address_type, 0:IPV4, 1:IPV6, 默认是IPV4
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverIPAddressType(long rtp_receiver_handle, int ip_address_type);


/**
 *设置 RTP Receiver RTP Socket本地端口
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param port, 必须是偶数,设置0的话SDK会自动分配, 默认值是0
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverLocalPort(long rtp_receiver_handle, int port);


/**
 *设置 RTP Receiver SSRC
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param ssrc, 如果设置的话,这个字符串要能转换成uint32类型, 否则设置失败
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverSSRC(long rtp_receiver_handle, String ssrc);


/**
 *创建 RTP Receiver 会话
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param reserve, 保留值,目前传0
 *
 * @return {0} if successful
 */
public native int CreateRTPReceiverSession(long rtp_receiver_handle, int reserve);


/**
 *获取 RTP Receiver RTP Socket本地端口
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @return 失败返回0, 成功的话返回响应的端口, 请在CreateRTPReceiverSession返回成功之后调用
 */
public native int GetRTPReceiverLocalPort(long rtp_receiver_handle);


/**
 *设置 RTP Receiver Payload 相关信息
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @param payload_type, 请参考 RFC 3551
 *
 * @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 可能传null就好
 *
 * @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频
 *
 * @param clock_rate, 请参考 RFC 3551
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverPayloadType(long rtp_receiver_handle, int payload_type, String encoding_name, int media_type, int clock_rate);


/**
 *设置 RTP Receiver 音频采样率
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param sampling_rate, 音频采样率
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverAudioSamplingRate(long rtp_receiver_handle, int sampling_rate);

/**
 *设置 RTP Receiver 音频通道数
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param channels, 音频通道数
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverAudioChannels(long rtp_receiver_handle, int channels);


/**
 *设置 RTP Receiver 远端地址
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 * @param address, IP地址
 * @param port, 端口
 *
 * @return {0} if successful
 */
public native int SetRTPReceiverRemoteAddress(long rtp_receiver_handle, String address, int port);

/**
 *初始化 RTP Receiver
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @return {0} if successful
 */
public native int InitRTPReceiver(long rtp_receiver_handle);

/**
 *UnInit RTP Receiver
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @return {0} if successful
 */
public native int UnInitRTPReceiver(long rtp_receiver_handle);


/**
 *Destory RTP Receiver Session
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @return {0} if successful
 */
public native int DestoryRTPReceiverSession(long rtp_receiver_handle);


/**
 *Destory RTP Receiver
 *
 * @param rtp_receiver_handle, CreateRTPReceiver
 *
 * @return {0} if successful
 */
public native int DestoryRTPReceiver(long rtp_receiver_handle);

PostAudioPacket(SmartPlayerJniV2.java),投递音频包给外部Live source,目前仅于语音对讲使用:

/*
 * SmartPlayerJniV2.java
 * Author: https://daniusdk.com
 */
/**
 * 投递音频包给外部Live source, 注意ByteBuffer对象必须是DirectBuffer
 *
 * @param handle: return value from SmartPlayerOpen()
 *
 * @return {0} if successful
 */
public native int PostAudioPacket(long handle, int codec_id,
                          java.nio.ByteBuffer packet, int offset, int size, long pts, boolean is_pts_discontinuity,
                          java.nio.ByteBuffer extra_data, int extra_data_offset, int extra_data_size, int sample_rate, int channels);

GB28181接口调用

对应GB28181相关接口调用相关设计如下:

/*
 * SmartPublisherJniV2.java
 * Author: https://daniusdk.com
 */
/**
 * 设置GB28181 RTP Sender
 *
 * @param rtp_sender_handle, CreateRTPSender返回值
 * @param rtp_payload_type, 对于GB28181 PS, 协议定义是96, 具体以SDP为准,  RFC 3551有定义
 * @param encoding_name, 编码名, 请参考 RFC 3551, 当前仅支持: "PS", 其他值返回失败
 * @return {0} if successful
 */
public native int SetGB28181RTPSender(long handle, long rtp_sender_handle, int rtp_payload_type, String encoding_name);

/**
 * 设置GB28181 RTP 收到的音频包回调
 * @param handle
 * @param audio_packet_callback
 * @return
 */
public native int SetGB28181ReceiveAudioPacketCallback(long handle, NTAudioPacketCallback audio_packet_callback);

/**
 * 启动 GB28181 媒体流
 *
 * @return {0} if successful
 */
public native int StartGB28181MediaStream(long handle);

/**
 * 停止 GB28181 媒体流
 *
 * @return {0} if successful
 */
public native int StopGB28181MediaStream(long handle);

总结

以上是大牛直播SDK关于Android平台GB28181设备接入模块执法记录仪相关技术方案,除了基础功能外,GB28181模块还可以实现实时音量调节、实时快照、按需录像、历史视音频下载、历史视音频回放等,感兴趣的开发者可以尝试看看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023 MathorCup(妈妈杯) 数学建模挑战赛B题完整解题思路+模型+代码

2023妈妈杯数学建模B题完整版思路、模型代码已出!!! 云顶数模最新完整版解题思路、模型代码,供大家参考~~ B题目 解题思路 详细模型解析:

RGB-T Salient Object Detection via Fusing Multi-Level CNN Features

ADFC means ‘adjacent-depth feature combination’,MGF means ‘multi-branch group fusion’,JCSA means ‘joint channel-spatial attention’,JABMP means ‘joint attention guided bi-directional message passing’ 作者未提供代…

Sprint Cloud Stream整合RocketMq和websocket实现消息发布订阅

1.引入RocketMQ依赖&#xff1a;首先&#xff0c;在pom.xml文件中添加RocketMQ的依赖&#xff1a; <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.0</versi…

JVM虚拟机:运行时数据区详解

本文重点 我们前面已经将类的加载过程进行了全面的了解和学习,按照如下所示的JVM架架构图,接下来我们应该学习运行时数据区了。 运行时数据区 如上图所示,灰色的标识线程私有,基本不存在垃圾回收。而非灰色的是线程共享的,存在垃圾回收。 PC计数器 每个线程都有一个程序…

【java】建筑施工一体化智慧工地信息管理系统源码

智慧工地系统是一种利用人工智能和物联网技术来监测和管理建筑工地的系统。它可以通过感知设备、数据处理和分析、智能控制等技术手段&#xff0c;实现对工地施工、设备状态、人员安全等方面的实时监控和管理。 一、智慧工地让工程施工智能化 1、内容全面&#xff0c;多维度数…

简化geojson策略

1、删除无用的属性&#xff0c;也就是字段&#xff0c;在shp的时候就给删了 用arcgis等等软件都可以做到 2、简化坐标的小数位数 &#xff08;1&#xff09;网上推荐的办法&#xff0c;俺不会Python… github.com/perrygeo/geojson-precision &#xff08;2&#xff09;曲线…

【C++项目】高并发内存池第五讲内存回收释放过程介绍

内存回收 1.ThreadCache2.CentralCache3.PageCache 1.ThreadCache void ThreadCache::Deallocate(void* ptr, size_t size) {assert(ptr);assert(size < MAX_BYTES);//计算在哪号桶中&#xff0c;然后插入进去size_t index SizeClass::Index(size);_freeLists[index].Push…

HCIP笔记——数据链路层协议

网络类型 根据二层&#xff08;数据链路层&#xff09;所使用的协议来进行区分。 MA——多点接入网络 BMA——广播型多点接入网络——以太网 NBMA——非广播型多点接入网络 P2P——点到点的网络 以太网协议 MAC地址——区分和标识不同的设备 以太网中独有的一种地址——MAC地址…

基于华为云 IoT 物联网平台实现家居环境实时监控

01 智能家居环境监测 智能家居环境监测采用 Ruff 开发板作为主控&#xff0c;串口线连接温湿度传感器 DHT11 和空气质量传感器 SDS011&#xff0c;每5分钟采集一次数据&#xff0c;通过 MQTT 协议发送到华为云 IoT 物联网平台&#xff0c;并基于数据分析服务实时计算出整个家庭…

大数据Doris(十三):创建用户和创建数据库并赋予权限

文章目录 创建用户和创建数据库并赋予权限 一、创建用户

Python算法练习 10.28

leetcode 700 二叉搜索树中的搜索 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 示例 1: 输入&#xff1a;root [4,2,7,1,…

springboot web项目中 Set-Cookie 失败 办法

1. 背景 目前有个项目 线上环境 使用spring session管理的登录 项目中有两个接口 一个用来登录的 登录成功后会设置cookie 后续请求就会使用该cookie &#xff08;cookie的键值就是session Id 和 登录后的信息 例如菜单&#xff0c;权限等&#xff09; 一个用来检查是否登录…

听GPT 讲Rust源代码--library/std(5)

File: rust/library/std/src/sys/unsupported/time.rs 在Rust源代码中&#xff0c;rust/library/std/src/sys/unsupported/time.rs文件的作用是提供对于时间的支持&#xff0c;特别是在不支持的操作系统上。 该文件中包含了两个结构体定义&#xff0c;分别是Instant和SystemTim…

confluence

confluence PS&#xff1a;此文档全部由docker部署 1.准备挂载目录 1.给mysql创建data volume卷 [rooti-1-17 ~]# docker volume create confluence-mysql 2.给mysql创建配置文件 [rooti-1-17 ~]# mkdir -p /u01/confluence/mysql/ [rooti-1-17 ~]# cd /u01/confluence/my…

linux--

一、crond 任务调度 1、原理示意图 2、crontab 进行定时任务的设置 2.1. 概述 任务调度&#xff0c;是指系统在某个时间执行的特定的命令或程序。任务调度分类&#xff1a; 系统工作: 有些重要的工作必须周而复始地执行。如病毒扫描等 个别用户工作:个别用户可能希望执行某些…

springboot心理咨询管理系统

springboot心理咨询管理系统&#xff0c;java心理咨询管理系统&#xff0c;心理咨询管理系统 运行环境&#xff1a; JAVA版本&#xff1a;JDK1.8 IDE类型&#xff1a;IDEA、Eclipse都可运行 数据库类型&#xff1a;MySql&#xff08;8.x版本都可&#xff09; 硬件环境&#xf…

基于Qt串口Serial Port配置纯代码实现(桌面和嵌入式平台)

## Serial Port Qt 提供了串口类,可以直接对串口访问。我们可以直接使用 Qt 的串口类编程即可,十分方便。Qt 串口类不仅在 Windows 能用,还能在 Linux 下用,虽然串口编程不是什么新鲜事儿,既然 Qt 提供了这方面的接口,我们就充分利用起来,这将会使我们的开发十分方便!…

力扣刷题 day57:10-27

1.将数组划分成相等数对 给你一个整数数组 nums &#xff0c;它包含 2 * n 个整数。 你需要将 nums 划分成 n 个数对&#xff0c;满足&#xff1a; 每个元素 只属于一个 数对。 同一数对中的元素 相等 。 如果可以将 nums 划分成 n 个数对&#xff0c;请你返回 true &#x…

Java面试八股文之暑假合集

八股文暑假合集 基础篇二分查找 java基础篇7月12号面向对象和面向过程的区别重载和重写String 7月13号自动装箱和拆箱静态方法构造方法成员变量和局部变量对象引用和对象实例返回值 与equals(重要)hashcode()和equals()HashMap 7月16号线程&#xff0c;进程和程序final关键字的…

fastadmin分类下拉(多级分类)使用教程

效果图1&#xff1a; 在后台分类管理中&#xff0c;添加需要的分类数据 效果图2&#xff1a; 在后台添加页面&#xff0c;点击下拉即可出现分类多级下拉数据 以上就是效果图。 分类下拉实现步骤&#xff1a; 1.更改控制器 找到需要修改的控制器&#xff0c;修改公共方法 _i…