Android平台RTMP推送|轻量级RTSP服务能力封装代码实现

news2025/3/11 0:04:13

好多开发者问我们,有没有针对Android平台RTMP直播推送、轻量级RTSP服务模块的进一步封装,可以更便捷的调用大牛直播SDK接口。

为此,我们分享下我们针对Android平台SmartPublisher做的二次封装代码:

package com.daniulive.smartpublisher;

import android.util.Log;

import java.nio.ByteBuffer;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class LibPublisherWrapper {
    private static String TAG = "NTLogLibPBW";
    private static final int OK = 0;

    private final ReadWriteLock rw_lock_ = new ReentrantReadWriteLock(true);
    private final java.util.concurrent.locks.Lock write_lock_ = rw_lock_.writeLock();
    private final java.util.concurrent.locks.Lock read_lock_ = rw_lock_.readLock();

    private SmartPublisherJniV2 lib_publisher_;
    private volatile long native_handle_;

    private volatile boolean is_rtmp_publishing_;
    private volatile boolean is_recording_;
    private volatile boolean is_rtsp_publishing_;
    private volatile boolean is_gb_stream_publishing_;

    private void clear_all_publishing_flags() {
        this.is_rtmp_publishing_ = false;
        this.is_recording_ = false;
        this.is_rtsp_publishing_ = false;
        this.is_gb_stream_publishing_ = false;
    }

    public void set(SmartPublisherJniV2 lib_publisher, long handle) {
        if (!empty())
            throw new IllegalStateException("it is not empty");

        if (handle != 0) {
            if (null == lib_publisher)
                throw new NullPointerException("lib_publisher is null");
        }

        write_lock_.lock();
        try {
            clear_all_publishing_flags();
            this.lib_publisher_ = lib_publisher;
            this.native_handle_ = handle;
        } finally {
            write_lock_.unlock();
        }

        Log.i(TAG, "set native_handle:" + handle);
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (check_native_handle()) {
                if(is_rtmp_publishing()) {
                    lib_publisher_.SmartPublisherStopPublisher(get());
                    this.is_rtmp_publishing_ = false;
                }

                if(is_recording()) {
                    lib_publisher_.SmartPublisherStopRecorder(get());
                    this.is_recording_ = false;
                }

                if (is_rtsp_publishing()) {
                    lib_publisher_.StopRtspStream(get());
                    this.is_rtsp_publishing_ = false;
                }

                if (is_gb_stream_publishing()) {
                    lib_publisher_.StopGB28181MediaStream(get());
                    this.is_gb_stream_publishing_ = false;
                }

                lib_publisher_.SmartPublisherClose(this.native_handle_);
                Log.i(TAG, "finalize close handle:" + this.native_handle_);
                this.native_handle_ = 0;
            }
        }catch (Exception e) {

        }

        super.finalize();
    }

    public void release() {
        if (empty())
            return;

        if(is_rtmp_publishing())
            StopPublisher();

        if (is_recording())
            StopRecorder();

        if (is_rtsp_publishing())
            StopRtspStream();

        if (is_gb_stream_publishing())
            StopGB28181MediaStream();

        long handle;
        write_lock_.lock();
        try {
            handle = this.native_handle_;
            this.native_handle_ = 0;
            clear_all_publishing_flags();
        } finally {
            write_lock_.unlock();
        }

        if (lib_publisher_ != null && handle != 0)
            lib_publisher_.SmartPublisherClose(handle);
    }

    public boolean try_release() {
        if (empty())
            return false;

        if (is_publishing()) {
            Log.i(TAG, "try_release it is publishing, native_handle:" + get());
            return false;
        }

        long handle;
        write_lock_.lock();
        try {
            if (is_publishing())
                return false;

            handle = this.native_handle_;
            this.native_handle_ = 0;
        } finally {
            write_lock_.unlock();
        }

        if (lib_publisher_ != null && handle != 0)
            lib_publisher_.SmartPublisherClose(handle);

        return true;
    }

    public final boolean empty() { return 0 == this.native_handle_; }

    private final long get() { return this.native_handle_; }

    private final boolean check_native_handle() {
        return this.lib_publisher_ != null && this.native_handle_ != 0;
    }

    public final boolean is_rtmp_publishing() { return is_rtmp_publishing_; }

    public final boolean is_recording() { return is_recording_; }

    public final boolean is_rtsp_publishing() { return is_rtsp_publishing_; }

    public final boolean is_gb_stream_publishing() { return is_gb_stream_publishing_; }

    public final boolean is_publishing() { return is_gb_stream_publishing_ || is_rtmp_publishing_ || is_rtsp_publishing_ || is_recording_; }

    public boolean SetMute(boolean is_mute) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetMute(get(), is_mute? 1 : 0);
    }

    public boolean SetInputAudioVolume(int index, float volume) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetInputAudioVolume(get(), index , volume);
    }

    public boolean SetMirror(boolean is_mirror) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetMirror(get(), is_mirror?1:0);
    }

    public boolean SetRecorderDirectory(String path) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetRecorderDirectory(get(), path);
    }

    public boolean SetRecorderFileMaxSize(int size) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetRecorderFileMaxSize(get(), size);
    }

    public boolean CaptureImage(int compress_format, int quality, String file_name, String user_data_string) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.CaptureImage(get(), compress_format, quality, file_name, user_data_string);
    }

    public boolean SetURL(String url) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SmartPublisherSetURL(get(), url);
    }

    public boolean StartPublisher() {
        if (!check_native_handle())
            return false;

        if (is_rtmp_publishing()) {
            Log.e(TAG, "already publishing rtmp, native_handle:" + get());
            return false;
        }

        int ret = lib_publisher_.SmartPublisherStartPublisher(get());
        if (ret != OK) {
            Log.e(TAG, "call SmartPublisherStartPublisher failed, native_handle:" + get() + ", ret:" + ret);
            return false;
        }

        write_lock_.lock();
        try {
            this.is_rtmp_publishing_ = true;
        } finally {
            write_lock_.unlock();
        }

        Log.i(TAG, "call SmartPublisherStartPublisher OK, native_handle:" + get());
        return true;
    }

    public boolean StopPublisher() {
        if (!check_native_handle())
            return false;

        if (!is_rtmp_publishing()) {
            Log.w(TAG, "it's not publishing rtmp, native_handle:" + get());
            return false;
        }

        boolean is_need_call = false;
        write_lock_.lock();
        try {
            if (this.is_rtmp_publishing_) {
                this.is_rtmp_publishing_ = false;
                is_need_call = true;
            }
        } finally {
            write_lock_.unlock();
        }

        if (is_need_call)
            lib_publisher_.SmartPublisherStopPublisher(get());

        return true;
    }

    public boolean StartRecorder() {
        if (!check_native_handle())
            return false;

        if (is_recording()) {
            Log.e(TAG, "already recording, native_handle:" + get());
            return false;
        }

        int ret = lib_publisher_.SmartPublisherStartRecorder(get());
        if (ret != OK) {
            Log.e(TAG, "call SmartPublisherStartRecorder failed, native_handle:" + get() + ", ret:" + ret);
            return false;
        }

        write_lock_.lock();
        try {
            this.is_recording_ = true;
        } finally {
            write_lock_.unlock();
        }

        Log.i(TAG, "call SmartPublisherStartRecorder OK, native_handle:" + get());
        return true;
    }

    public boolean PauseRecorder(boolean is_pause) {
        if (!check_native_handle())
            return false;

        if (!is_recording()) {
            Log.e(TAG, "it's not recording, native_handle:" + get());
            return false;
        }

        return OK == lib_publisher_.SmartPublisherPauseRecorder(get(), is_pause?1:0);
    }

    public boolean StopRecorder() {
        if (!check_native_handle())
            return false;

        if (!is_recording()) {
            Log.w(TAG, "it's not recording, native_handle:" + get());
            return false;
        }

        boolean is_need_call = false;
        write_lock_.lock();
        try {
            if (this.is_recording_) {
                this.is_recording_ = false;
                is_need_call = true;
            }
        } finally {
            write_lock_.unlock();
        }

        if (is_need_call)
            lib_publisher_.SmartPublisherStopRecorder(get());

        return true;
    }

    public boolean SetRtspStreamName(String stream_name) {
        if (is_null_or_empty(stream_name))
            return false;

        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SetRtspStreamName(get(), stream_name);
    }

    public boolean AddRtspStreamServer(long rtsp_server_handle) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.AddRtspStreamServer(get(), rtsp_server_handle, 0);
    }

    public boolean ClearRtspStreamServer() {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.ClearRtspStreamServer(get());
    }

    public boolean StartRtspStream() {
        if (!check_native_handle())
            return false;

        if (is_rtsp_publishing()) {
            Log.e(TAG, "already publishing rtsp stream, native_handle:" + get());
            return false;
        }

        int ret = lib_publisher_.StartRtspStream(get(), 0);
        if (ret != OK) {
            Log.e(TAG, "call StartRtspStream failed, native_handle:" + get() + ", ret:" + ret);
            return false;
        }

        write_lock_.lock();
        try {
            this.is_rtsp_publishing_ = true;
        } finally {
            write_lock_.unlock();
        }

        Log.i(TAG, "call StartRtspStream OK, native_handle:" + get());
        return true;
    }

    public boolean StopRtspStream() {
        if (!check_native_handle())
            return false;

        if (!is_rtsp_publishing()) {
            Log.w(TAG, "it's not publishing rtsp stream, native_handle:" + get());
            return false;
        }

        boolean is_need_call = false;
        write_lock_.lock();
        try {
            if (this.is_rtsp_publishing_) {
                this.is_rtsp_publishing_ = false;
                is_need_call = true;
            }
        } finally {
            write_lock_.unlock();
        }

        if (is_need_call)
            lib_publisher_.StopRtspStream(get());

        return true;
    }

    public boolean SetGB28181RTPSender(long rtp_sender_handle, int rtp_payload_type, String encoding_name) {
        if (!check_native_handle())
            return false;

        return OK == lib_publisher_.SetGB28181RTPSender(get(), rtp_sender_handle, rtp_payload_type, encoding_name);
    }

    public boolean StartGB28181MediaStream() {
        if (!check_native_handle())
            return false;

        if (is_gb_stream_publishing()) {
            Log.e(TAG, "already publishing gb media stream, native_handle:" + get());
            return false;
        }

        int ret = lib_publisher_.StartGB28181MediaStream(get());
        if (ret != OK) {
            Log.e(TAG, "call StartGB28181MediaStream failed, native_handle:" + get() + ", ret:" + ret);
            return false;
        }

        write_lock_.lock();
        try {
            this.is_gb_stream_publishing_ = true;
        } finally {
            write_lock_.unlock();
        }

        Log.i(TAG, "call StartGB28181MediaStream OK,native_handle:" + get());

        return true;
    }

    public boolean StopGB28181MediaStream() {
        if (!check_native_handle())
            return false;

        if (!is_gb_stream_publishing()) {
            Log.w(TAG, "it's not publishing gb stream, native_handle:" + get());
            return false;
        }

        boolean is_need_call = false;
        write_lock_.lock();
        try {
            if (this.is_gb_stream_publishing_) {
                this.is_gb_stream_publishing_ = false;
                is_need_call = true;
            }
        } finally {
            write_lock_.unlock();
        }

        if (is_need_call)
            lib_publisher_.StopGB28181MediaStream(get());

        return true;
    }

    public boolean OnPCMData(ByteBuffer pcm_data, int size, int sample_rate, int channel, int per_channel_sample_number) {
        if (!check_native_handle() || !is_publishing())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle() || !is_publishing())
                return false;

            return OK == lib_publisher_.SmartPublisherOnPCMData(get(), pcm_data, size, sample_rate, channel, per_channel_sample_number);
        } catch (Exception e) {
            Log.e(TAG, "OnPCMData Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean OnFarEndPCMData(ByteBuffer pcm_data, int sample_rate, int channel, int per_channel_sample_number, int is_low_latency) {
        if (!check_native_handle() || !is_publishing())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle() || !is_publishing())
                return false;

            return OK == lib_publisher_.SmartPublisherOnFarEndPCMData(get(), pcm_data, sample_rate, channel, per_channel_sample_number, is_low_latency);
        } catch (Exception e) {
            Log.e(TAG, "OnFarEndPCMData Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostUserUTF8StringData(String utf8_string) {
        if (is_null_or_empty(utf8_string))
            return false;

        if (!check_native_handle() || !is_publishing())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle() || !is_publishing())
                return false;

            return OK == lib_publisher_.SmartPublisherPostUserUTF8StringData(get(), utf8_string, 0);
        } catch (Exception e) {
            Log.e(TAG, "PostUserUTF8StringData Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean OnCaptureVideoData(byte[] data, int len, int cameraType, int curOrg) {
        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.SmartPublisherOnCaptureVideoData(get(), data, len, cameraType, curOrg);
        } catch (Exception e) {
            Log.e(TAG, "OnCaptureVideoData Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean EnableLayer(int index, boolean is_enable) {
        if (index < 1)
            return false;

        if (!check_native_handle())
            return false;

        read_lock_.lock();

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.EnableLayer(get(), index, is_enable?1:0);
        } catch (Exception e) {
            Log.e(TAG, "EnableLayer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean RemoveLayer(int index) {
        if (index < 1)
            return false;

        if (!check_native_handle())
            return false;

        read_lock_.lock();

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.RemoveLayer(get(), index);
        } catch (Exception e) {
            Log.e(TAG, "RemoveLayer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostLayerImageNV21ByteArray(int index, int left, int top,
                                               byte[] y_plane, int y_offset, int y_row_stride,
                                               byte[] uv_plane, int uv_offset, int uv_row_stride,
                                               int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                                               int scale_width,  int scale_height, int scale_filter_mode,
                                               int rotation_degree) {
        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.PostLayerImageNV21ByteArray(get(), index, left, top, y_plane, y_offset, y_row_stride,
                    uv_plane, uv_offset, uv_row_stride, width, height, is_vertical_flip, is_horizontal_flip,
                    scale_width, scale_height, scale_filter_mode, rotation_degree);
        } catch (Exception e) {
            Log.e(TAG, "PostLayerImageNV21ByteArray Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostLayerImageRGBA8888ByteBuffer(int index, int left, int top,
                                                    ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
                                                    int is_vertical_flip,  int is_horizontal_flip,
                                                    int scale_width,  int scale_height, int scale_filter_mode,
                                                    int rotation_degree) {

        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.PostLayerImageRGBA8888ByteBuffer(get(), index, left, top,
                    rgba_plane, offset, row_stride, width, height, is_vertical_flip, is_horizontal_flip,
                    scale_width, scale_height, scale_filter_mode, rotation_degree);

        } catch (Exception e) {
            Log.e(TAG, "PostLayerImageRGBA8888ByteBuffer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostLayerImageI420ByteBuffer(int index, int left, int top,
                                                ByteBuffer y_plane, int y_offset, int y_row_stride,
                                                ByteBuffer u_plane, int u_offset, int u_row_stride,
                                                ByteBuffer v_plane, int v_offset, int v_row_stride,
                                                int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                                                int scale_width,  int scale_height, int scale_filter_mode,
                                                int rotation_degree) {
        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.PostLayerImageI420ByteBuffer(get(), index, left, top,
                    y_plane, y_offset, y_row_stride,
                    u_plane, u_offset, u_row_stride,
                    v_plane, v_offset, v_row_stride,
                    width, height, is_vertical_flip, is_horizontal_flip,
                    scale_width, scale_height, scale_filter_mode,
                    rotation_degree);

        } catch (Exception e) {
            Log.e(TAG, "PostLayerImageI420ByteBuffer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostLayerImageYUV420888ByteBuffer(int index, int left, int top,
                                                     ByteBuffer y_plane, int y_offset, int y_row_stride,
                                                     ByteBuffer u_plane, int u_offset, int u_row_stride,
                                                     ByteBuffer v_plane, int v_offset, int v_row_stride, int uv_pixel_stride,
                                                     int width, int height, int is_vertical_flip,  int is_horizontal_flip,
                                                     int scale_width,  int scale_height, int scale_filter_mode,
                                                     int rotation_degree) {
        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.PostLayerImageYUV420888ByteBuffer(get(), index, left, top, y_plane, y_offset, y_row_stride,
             u_plane, u_offset, u_row_stride, v_plane, v_offset, v_row_stride, uv_pixel_stride,
             width, height, is_vertical_flip, is_horizontal_flip, scale_width, scale_height, scale_filter_mode, rotation_degree);

        } catch (Exception e) {
            Log.e(TAG, "PostLayerImageYUV420888ByteBuffer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    public boolean PostAudioEncodedData(int codec_id, ByteBuffer data, int size, int is_key_frame,
                                                      long timestamp,ByteBuffer parameter_info, int parameter_info_size) {
        if (!check_native_handle())
            return false;

        if (!read_lock_.tryLock())
            return false;

        try {
            if (!check_native_handle())
                return false;

            return OK == lib_publisher_.SmartPublisherPostAudioEncodedData(get(), codec_id, data, size, is_key_frame, timestamp, parameter_info, parameter_info_size);

        } catch (Exception e) {
            Log.e(TAG, "PostLayerImageYUV420888ByteBuffer Exception:", e);
            return false;
        } finally {
            read_lock_.unlock();
        }
    }

    private static boolean is_null_or_empty(String val) {
        return null == val || val.isEmpty();
    }

    //估计硬编码码率, 可以根据实际机型调整
    public static int estimate_video_hardware_kbps(int width, int height, int fps, boolean is_h264) {
        int kbps;
        int area = width * height;
        if (area <= (320 * 300))
            kbps = is_h264?350:280;
        else if (area <= (370 * 320))
            kbps = is_h264?470:400;
         else if (area <= (640 * 360))
            kbps = is_h264?850:650;
       else if (area <= (640 * 480))
            kbps = is_h264?1200:800;
        else if (area <= (800 * 600))
            kbps = is_h264?1300:950;
        else if (area <= (900 * 700))
            kbps = is_h264?1600:1100;
        else if (area <= (1280 * 720))
            kbps = is_h264?2100:1500;
         else if (area <= (1366 * 768))
            kbps = is_h264?2300:1900;
         else if (area <= (1600 * 900))
            kbps = is_h264?2800:2300;
        else if (area <= (1600 * 1050))
            kbps =is_h264?3100:2500;
         else if (area <= (1920 * 1088))
            kbps = is_h264?4200:2800;
        else
            kbps = is_h264?4500:3500;

        kbps = (int)(kbps*fps*1.0/25.0 + 0.5);
        return kbps;
    }

    public static int estimate_video_software_quality(int width, int height, boolean is_h264) {
        int area = width*height;
        int quality;
        if ( area <= (320 * 240) )
            quality = is_h264? 23 : 27;
        else if ( area <= (640 * 360) )
            quality = is_h264? 25 : 28;
        else if ( area <= (640 * 480) )
            quality = is_h264? 26 : 28;
        else if ( area <= (960 * 600) )
            quality = is_h264? 26 : 28;
        else if ( area <= (1280 * 720) )
            quality = is_h264? 27 : 29;
        else if ( area <= (1600 * 900) )
            quality = is_h264 ? 28 : 30;
        else if ( area <= (1920 * 1088) )
            quality = is_h264 ? 29 : 31;
        else
            quality = is_h264 ? 30 : 32;

        return quality;
    }

    public static int estimate_video_vbr_max_kbps(int width, int height, int fps) {
        int kbps;
        int area = width*height;
        if (area <= (320 * 300))
            kbps = 320;
        else if (area <= (360 * 320))
            kbps = 400;
        else if (area <= (640 * 360))
            kbps = 700;
        else if (area <= (640 * 480))
            kbps = 800;
        else if (area <= (800 * 600))
            kbps = 900;
        else if (area <= (900 * 700))
            kbps = 1100;
        else if (area <= (1280 * 720))
            kbps = 1700;
        else if (area <= (1366 * 768))
            kbps = 1800;
        else if (area <= (1600 * 900))
            kbps = 2500;
        else if (area <= (1600 * 1050))
            kbps = 2700;
        else if (area <= (1920 * 1088))
            kbps = 3100;
        else
            kbps = 3500;

        kbps = (int)(kbps*fps*1.0/25.0 + 0.5);

        return kbps;
    }
}

封装后的LibPublisherWrapper类,逻辑分离更彻底,调用更方便,几乎不要花心思了解接口用法,就可以非常高效的实现RTMP推送或轻量级RTSP服务技术诉求。

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

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

相关文章

OpenCV | 告别人工目检:深度学习技术引领工业品缺陷检测新时代

文章目录 机器视觉缺陷检测工业上常见缺陷检测方法内容简介作者简介目录读者对象如何阅读本书获取方式 机器视觉 机器视觉是使用各种工业相机&#xff0c;结合传感器跟电气信号实现替代传统人工&#xff0c;完成对象识别、计数、测量、缺陷检测、引导定位与抓取等任务。其中工…

用BEVformer来卷自动驾驶-1

之所以是-1,是因为大概率1篇文章写不完,但是又不知道应该用几篇来说事,先写着看 按照惯例,上论文地址:2203.17270v1.pdf (arxiv.org) 什么是BEV, Birds -Eye-View的意思,就是鸟瞰 比如稍微传统一些的自动驾驶,大部分的实现。如果靠纯CV的方案的话,那么基本…

electron使用electron-builder进行MacOS的 打包、签名、公证、上架、自动更新

一、前言 由于electron在macOS下的坑太多&#xff0c;本文不可能把所有的问题都列出来&#xff0c;也不可能把所有的解决方案贴出来&#xff1b;本文也不太会讲解每一个配置点为什么要这么设置的原因&#xff0c;因为有些点我也说不清&#xff0c;我尽可能会说明的。所以&…

【排序算法】C语言实现选择排序与冒泡排序

文章目录 &#x1f680;前言&#x1f680;冒泡排序✈️冒泡排序的逻辑✈️冒泡排序coding &#x1f680;选择排序✈️选择排序的逻辑✈️选择排序coding &#x1f680;前言 这里是阿辉算法与数据结构专栏的第一篇文章&#xff0c;咱们就从排序算法开始讲起&#xff0c;排序算法…

【python】进阶--->网络编程(二)

一、分层模型 OSI/RM(开放系统互联参考模型) 是由国际标准化组织提出来的一种网络互联模型,成为所有的销售商都能实现的开放网络模型.(OSI模型提供我们理解网络协议的内部运作) OSI模型将网络通信工作分为7层,每一层为上一层服务,并为上一层提供一个访问的接口或者界面. 越下…

【数字图像处理】实验一 图像基本运算

图像基本运算 一、实验内容&#xff1a; 1&#xff0e; 熟悉和掌握利用Matlab工具进行数字图像的读、写、显示等数字图像处理基本步骤。 2&#xff0e; 熟练掌握各种图像点运算的基本原理及方法。 3&#xff0e; 能够从深刻理解点运算&#xff0c;并能够思考拓展到一定的应用领…

【爬虫软件】孔夫子二手书采集

项目演示 孔网爬取图书信息 目录结构 [ |-- api-ms-win-core-synch-l1-2-0.dll, |-- api-ms-win-core-sysinfo-l1-1-0.dll, |-- api-ms-win-core-timezone-l1-1-0.dll, |-- api-ms-win-core-util-l1-1-0.dll, |-- api-ms-win-crt-conio-l1-1-0.dll, |-- api…

【matlab】绘制横状双组渐变柱状图

【matlab】绘制横状双组渐变柱状图

Frida07 - dexdump核心源码分析

项目地址 https://github.com/hluwa/frida-dexdump 代码解析 项目中的核心函数是 searchDex&#xff1a; function searchDex(deepSearch) {var result [];Process.enumerateRanges(r--).forEach(function (range) {try {....} catch (e) {}});return result; }里面用了一…

OpenCV-Python(19):Canny边缘检测

目录 学习目标 Canny 边缘检测原理 1.噪声抑制(噪声去除) 2.梯度计算 3.非极大值抑制 4.双阈值检测(滞后阈值) 5.边缘连接 Canny 边缘检测步骤 Canny 边缘检测的OpenCV实现 不同阈值的边缘检测效果 学习目标 了解Canny边缘检测的概念学习掌握函数cv2.Canny()的用法 …

Django(二)

1.django框架 1.1 安装 pip install django3.21.2 命令行 创建项目 cd 指定目录 django-admin startproject 项目名mysite ├── manage.py [项目的管理工具] └── mysite├── __init__.py├── settings.py 【配置文件&#xff0c;只有一部分…

电子科大软件测试~第三次作业

第三次作业 第一题 采用JUnit软件测试框架进行测试程序编程&#xff0c;实现对下面java程序进行单元测试&#xff0c;找出其中缺陷。然后修改缺陷&#xff0c;直到通过单元测试&#xff0c;给出测试程序脚本和运行结果界面。 public class getMax {public int get_max(int x…

Redis实现日榜|直播间榜单|排行榜|Redis实现日榜01

前言 直播间贡献榜是一种常见的直播平台功能&#xff0c;用于展示观众在直播过程中的贡献情况。它可以根据观众的互动行为和贡献值进行排名&#xff0c;并实时更新&#xff0c;以鼓励观众积极参与直播活动。 在直播间贡献榜中&#xff0c;每个观众都有一个对应的贡献值&#…

这样使用云渲染又快又省钱

我们都知道使用云渲染是要钱的&#xff0c;而且渲染的时间越久&#xff0c;需要的渲染费越多&#xff0c;哪么如何又快又省钱的拿到效果图呢&#xff1f;用炫云的渲染质量&#xff0c;保准让你使用云渲染渲染效果图又快又省钱。 我们使用炫云的时候&#xff0c;根据自己的需求…

输入框获取焦点

Entry Component struct Test {build() {Row() {Column({ space: 5 }) {//Text("自定义样式").customStyles(20,Color.Yellow).backgroundColor("#36D").padding(10).borderRadius(30)TextInput({placeholder: "获取焦点"}).borderColor(Color.Y…

LLM微调(四)| 微调Llama 2实现Text-to-SQL,并使用LlamaIndex在数据库上进行推理

Llama 2是开源LLM发展的一个巨大里程碑。最大模型及其经过微调的变体位居Hugging Face Open LLM排行榜&#xff08;https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard&#xff09;前列。多个基准测试表明&#xff0c;就性能而言&#xff0c;它正在接近GPT-3.5…

图灵日记之java奇妙历险记--数据类型与变量运算符

目录 数据类型与变量字面常量数据类型变量语法格式整型变量浮点型变量字符型变量希尔型变量类型转换自动类型转换(隐式)强制类型转换(显式) 类型提升不同数据类型的运算小于4字节数据类型的运算 字符串类型 运算符算术运算符关系运算符逻辑运算符逻辑与&&逻辑或||逻辑非…

案例125:基于微信小程序的个人健康数据管理系统的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【论文阅读】FreeU: Free Lunch in Diffusion U-Net

FreeU: 无需训练直接提升扩散模型生成效果。 paper&#xff1a;https://arxiv.org/abs/2309.11497 code&#xff1a;GitHub - ChenyangSi/FreeU: FreeU: Free Lunch in Diffusion U-Net 1. 介绍 贡献&#xff1a; •研究并揭示了U-Net架构在扩散模型中去噪的潜力&#xff0…

目标检测入门体验,技术选型,加载数据集、构建机器学习模型、训练并评估

Hi, I’m Shendi 1、目标检测入门体验&#xff0c;技术选型&#xff0c;加载数据集、构建机器学习模型、训练并评估 在最近有了个物体识别的需求&#xff0c;于是开始学习 在一番比较与询问后&#xff0c;最终选择 TensorFlow。 对于编程语言&#xff0c;我比较偏向Java或nod…