如何减少在 raspberrypi 4b 中录制 rtsp 流时的延迟?

问题描述 投票:0回答:1

我有一个通过以太网使用rtsp协议的网络摄像机,解码格式是h.264。当我录制rtsp视频时,延迟约为1~2秒。

规格:raspberrypi 4b/RAM 8GB/SDcard 32GB A1 蟒蛇3.11.2/opencv 4.9.0 GPU内存=256

已尝试过:CAP_GStreamer延迟2.5秒

预期:录制rtsp,延迟300~500ms

当前方法

import cv2
import sys
import os
#need this line to be work
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"
# rtsp url
rtsp_url = "rtsp://192.168.144.25:8554/main.264"

# create viedoCapture
cap = cv2.VideoCapture(rtsp_url)

# check video is open or not
if not cap.isOpened():
    print("Error: Could not open RTSP stream.")
    sys.exit()

# get video info
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# use h.264 to encode video
fourcc = cv2.VideoWriter_fourcc(*'H264')
out = None
recording = False

# show and save video
while True:
    ret, frame = cap.read()

    if not ret:
        print("Error: Could not read frame.")
        break

    cv2.imshow('RTSP Stream', frame)

    # record mode
    if recording:
        if out is None:
            out = cv2.VideoWriter('output.mp4', fourcc, fps, (width, height))
        out.write(frame)

    key = cv2.waitKey(1) & 0xFF

    # press q to quit
    if key == ord('q'):
        break

    # press r to switch record mode
    elif key == ord('r'):
        recording = not recording
        if recording:
            print("Recording started.")
        else:
            print("Recording stopped.")
            if out is not None:
                out.release()
                out = None

    # press p to photo
    elif key == ord('p'):
        cv2.imwrite('photo.jpg', frame)
        print("Photo taken.")

# release source
cap.release()
if out is not None:
    out.release()
cv2.destroyAllWindows()

python opencv rtsp raspberry-pi4
1个回答
0
投票

问题已解决:以下代码可以解决录制时延迟查看的问题。
新问题:在ffplay或vlc上播放录制的视频已经从20秒减少到5秒,每次动作看起来都很快。我猜可能是写入数据时丢帧了。
猜测方法:我建议在开始录制时,队列需要采集一帧,并按队列写入数据。当录制停止时,队列停止收集帧。但我不知道该怎么做。

from threading import Thread
import imutils
import cv2, time
import sys
camlink1 = "rtsp://192.168.144.25:8554/main.264"


class VideoStreamWidget(object):
    def __init__(self, link, camname, src=0):
        self.capture = cv2.VideoCapture(link)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()
        
        self.threadRecord=Thread(target=self.record,args=())
        self.threadRecord.daemon=True
        
        self.camname = camname
        self.link = link
        self.recording=False
        self.out=None
        
        
        print(camname)
        print(link)

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            time.sleep(.01)

    def show_frame(self):

        # Display frames in main program
        #frame = imutils.resize(self.frame, width=400)
        cv2.imshow('Frame ' + self.camname, self.frame)
        
    def closewindow(self):
         self.capture.release()
         cv2.destroyAllWindows()
         sys.exit(0)
    def record(self):
        while True:
            
            fourcc = cv2.VideoWriter_fourcc(*'mp4v')
            fps = int(self.capture.get(cv2.CAP_PROP_FPS))
            width = int(self.capture.get(cv2.CAP_PROP_FRAME_WIDTH))
            height = int(self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
                           
            #self.recording=not self.recording
            if not self.recording:
                if self.out is not None:
                    self.out.release()
                    self.out = None
                return
    
            if self.recording:
                if self.out is None:
                    self.out = cv2.VideoWriter('output_test.mp4', fourcc, fps, (width, height))
                self.out.write(self.frame)
                time.sleep(1/fps)

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget(camlink1,"Cam1")

    while True:
        try:
            video_stream_widget.show_frame()
            key=cv2.waitKey(1)
            if key==ord('q'):
                video_stream_widget.closewindow()
            elif key==ord('r'):
                video_stream_widget.recording=not video_stream_widget.recording
                if not video_stream_widget.threadRecord.is_alive():
                   
                    video_stream_widget.threadRecord.start()
                      
        except AttributeError:
            pass

© www.soinside.com 2019 - 2024. All rights reserved.