1. 程式人生 > 其它 >TSINGSEE青犀視訊測試景區行人智慧檢測出現Failed to open rtsp的報錯排查

TSINGSEE青犀視訊測試景區行人智慧檢測出現Failed to open rtsp的報錯排查

前段時間我們一直在做景區人流量統計及智慧分析的功能,目前該功能已經進入了實際測試階段。在景區現場人流量統計測試中,有景區會出現攝像頭rtsp流斷開的情況,遠端使用VLC播放也播放不出來。

對該問題的出現,我們第一時間開始查詢原因,我們瞭解到在該景區中,在晚上攝像頭裝置會斷電,等早上工作人員來後再把裝置的電供應上。所以第二天早上會出現錯誤:Failed to open rtsp://xxxxxx。

我們開啟rtsp流錯誤,所以只能從程式碼中分析問題所在。首先要定位到是哪個地方輸入的rtsp流:

隨後找到在哪裡開啟的rtsp流:

LoadStreams進行了初始化,並輸入其中一個引數rtsp流:

for i, s in enumerate(sources):
    # Start the thread to read frames from the video stream
    print(f'{i + 1}/{n}: {s}... ', end='')
    cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)
    assert cap.isOpened(), f'Failed to open {s}'
    w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS) % 100

    _, self.imgs[i] = cap.read()  # guarantee first frame
    thread = Thread(target=self.update, args=([i, cap]), daemon=True)
    print(f' success ({w}x{h} at {fps:.2f} FPS).')
    thread.start()
print('')  # newline

剛開始執行程式會進行初始化開啟rtsp流,但是已經rtsp執行成功了,就不會進去初始化重新開啟rtsp流,所以還有個執行緒函式如下:

Thread = Thread(target=self.update, args=([i, cap]), daemon=True)

執行緒有個self.update函式,進去此方法,是rtsp斷開,隔一段時間重新連線:

def update(self, index, cap):
    # Read next stream frame in a daemon thread
    n = 0
    while cap.isOpened():
        n += 1
        # _, self.imgs[index] = cap.read()
        cap.grab()
        if n == 4:  # read every 4th frame
            success, im = cap.retrieve()
            self.imgs[index] = im if success else self.imgs[index] * 0
            n = 0
        time.sleep(0.01)  # wait time

知道問題所在,只需要修改執行緒中update函式方法即可。

首先檢視從rtsp能不能讀到影象,如果讀不到影象,說明rtsp流已經斷開連線,需要再次開啟rtsp流,延遲幾秒,再次開啟rtsp,一直重複此操作,一直到成功。

self.ret, self.imgs[self.index] = self.cap.read()
if not self.ret:
    print("Camera is disconnected!")
    time.sleep(5 * 60)
    n = len(self.my_sources)
    self.imgs = [None] * n
    self.sources = [clean_str(x) for x in self.my_sources]  # clean source names for later

    for i, s in enumerate(self.my_sources):
        # Start the thread to read frames from the video stream
        print(f'{i + 1}/{n}: {s}... ', end='')
        cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)
        if not cap.isOpened():
            continue
        assert cap.isOpened(), f'Failed to open {s}'
        print("rtsp success")
        self.index = i
        self.cap = cap
    continue