首页 > 其他分享 >Android平台RTMP推送|轻量级RTSP服务能力封装代码实现

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

时间:2023-12-23 22:36:51浏览次数:32  
标签:handle false int RTSP _. RTMP return 轻量级 native

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

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

为此,我们分享下我们针对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服务技术诉求。


标签:handle,false,int,RTSP,_.,RTMP,return,轻量级,native
From: https://blog.51cto.com/daniusdk/8946741

相关文章

  • Hessian——轻量级远程调用方案
    Hessian——轻量级远程调用方案转载自:https://www.cnblogs.com/lyhero11/p/5277583.htmlHessian是caucho公司开发的一种基于二进制RPC协议(RemoteProcedureCallprotocol)的轻量级远程调用框架。具有多种语言的实现,但用的最多的当然是Java实现:)CreatingaHessianservi......
  • Android平台RTSP流如何添加动态水印后转推RTMP或轻量级RTSP服务
    技术背景我们在对接外部开发者的时候,遇到这样的技术诉求,客户用于地下管道检测场景,需要把摄像头的数据拉取过来,然后叠加上实时位置、施工单位、施工人员等信息,然后对外输出新的RTSP流,并本地录制一份带动态水印叠加后的数据。整个过程,因为摄像头位置一直在变化,所以需要整体尽可能的低......
  • 新手友好、轻量级的C#/.NET万能工具库
    前言今天分享一个基于MITLicense协议开源、免费、新手友好、轻量级的C#/.NET万能工具库、帮助类库(支持.NET和.NETCore,可以帮助开发者们减少常见重复功能方法查找,提高开发工作效率):Masuit.Tools。项目官方介绍全龄段友好的C#万能工具库,码数吐司库,包含一些常用的操作类,大都是......
  • RTSP流媒体视频平台LiteNVR播放HLS流,出现中断且无法自动恢复的原因排查
    有用户反映,在使用安防视频LiteNVR平台时,取平台分发的hls地址在移动端播放一段时间就会停止,且无法自动恢复播放。今天我们来介绍下该问题的排查与解决方法。LiteNVR是基于RTSP/Onvif协议推出的安防视频监控管理平台,它可实现设备接入、实时直播、录像、检索与回放、存储、视频分发......
  • Qt+FFmpeg仿VLC接收RTSP流并播放
    关键词:QtFFmpegC++RTSPRTPVLC内存泄漏摘要认证花屏源码UDP本系列原文地址。下载直接可运行的源码,在原文顶部。效果产生RTSP流比播放文件复杂一点是,为了接收RTSP流,我们需要产生RTSP流。简单搭建一个RTSP推流环境:用EasyDarwin开启RTSP服务作为RTSP服务器。用f......
  • (亲测)云原生之使用Docker部署Teedy轻量级文档管理系统
    一、Teedy介绍1.1Teedy简介Teedy是一个开源的、功能丰富、易于使用和自定义的文档管理工具,它能够帮助用户管理和组织文档,适用于个人、小组和组织使用。1.2Teedy特点创建和编辑文档:用户可以使用Markdown格式创建和编辑文档,还可以添加标签和注释。文件上传和管理:用户可以上传和管理......
  • python读取rtsp流,并消耗
    1.python读取rtsp流,并消耗(用线程)importosimportcv2importgcimporttimeimportthreadingimportnumpyasnpfromPILimportImagetop=100stack=[]#向共享缓冲栈中写入数据:defwrite(stack,cam,top:int)->None:  """  :paramcam:摄像头参数  :para......
  • Python实现RTSP流测试
    本文将详细介绍如何使用Python来测试RTSP流。首先,我们需要了解什么是RTSP。RTSP(RealTimeStreamingProtocol)是一种基于文本的IP协议,主要用于控制实时数据的传输,例如音频或视频。在本文中,我们将使用Python中的OpenCV库来测试RTSP流。一、安装OpenCV库在Python中使用OpenCV库需......
  • .NET 轻量级工作流引擎
    title:.NET轻量级工作流引擎updated:2023-09-1507:58:10Zcreated:2023-09-1507:58:10Zsource:https://mp.weixin.qq.com/s/Q3B8tUwqosNLcX6_5_Ka3Qtags:-dotnetframework.NET轻量级工作流引擎欢迎来到Dotnet工具箱!在这里,你可以发现各种令人惊喜的开源项。......
  • Qt/C++视频监控拉流显示/各种rtsp/rtmp/http视频流/摄像头采集/视频监控回放/录像存储
    一、前言本视频播放组件陆陆续续写了6年多,一直在持续更新迭代,视频监控行业客户端软件开发首要需求就是拉流显示,比如给定一个rtsp视频流地址,你需要在软件上显示实时画面,其次就是录像保存,再次就是一些周边的处理比如贴OSD,做图片分析等。拉流显示是第一步,如果有跨平台的需求,个人推荐......