我正在尝试使用 OpenCV 从 IP 摄像机捕获 RTSP 视频,代码片段如下
cam = cv2.VideoCapture(RTSP_URL)
while True:
ret, frame = cam.read()
if not ret:
cam = cv2.VideoCapture(RTSP_URL)
这可行,但在某些时间帧由于未知原因丢失后,尽管有最后一行,但似乎无法重新连接到 RTSP 流。使用 VLC,RTSP 流可以稳定播放。 有没有更强大的方法来捕获 RTSP 流?
我建议使用 pyav 来代替,因为错误处理更好,并且你可以更好地控制它。 (https://pyav.org/docs/develop/api/error.html)
这是一个未经测试的示例,但应该给你一个方法。
import av
import time
import threading
class RTSPStream:
def __init__(self, rtsp_url, reconnect_interval=10):
self.rtsp_url = rtsp_url
self.reconnect_interval = reconnect_interval
self.container = None
self.should_stop = threading.Event()
def open_stream(self):
try:
self.container = av.open(self.rtsp_url)
except av.AVError as e:
print("Error opening RTSP stream:", e)
def process_frames(self):
while not self.should_stop.is_set():
try:
for frame in self.container.decode(video=0):
print("Frame timestamp:", frame.time)
except av.AVError as e:
print("AVError:", e)
if e.errno in (av.AVERROR_EXIT, av.AVERROR_EOF):
print("Stream ended.")
break
elif e.errno == av.AVERROR_TIMEOUT:
print("Read timeout. Reconnecting in", self.reconnect_interval, "seconds.")
elif e.errno == av.AVERROR_INVALIDDATA:
print("Invalid data received. Skipping frame.")
elif e.errno == 401:
print("Unauthorized: Check your RTSP credentials.")
break
elif e.errno == 404:
print("RTSP stream not found (404).")
break
else:
print("Unknown AVError:", e)
break
// TODO: call this not an all errors
time.sleep(self.reconnect_interval)
self.open_stream()
def start(self):
while not self.should_stop.is_set():
if self.container is None:
self.open_stream()
if self.container is not None:
self.process_frames()
def stop(self):
self.should_stop.set()
if __name__ == "__main__":
rtsp_url = "rtsp://your_rtsp_stream_url"
stream = RTSPStream(rtsp_url)
streaming_thread = threading.Thread(target=stream.start)
streaming_thread.start()
time.sleep(60)
stream.stop()
streaming_thread.join()