Unverified 提交 683cefea authored 作者: Glenn Jocher's avatar Glenn Jocher 提交者: GitHub

YouTube stream ending fix (#3277)

* YouTube stream ending fix Properly terminates YouTube streams on video end. Should resolve issues #2769 and #3220. * Update datasets.py
上级 f3402353
...@@ -270,7 +270,7 @@ class LoadStreams: # multiple IP or RTSP cameras ...@@ -270,7 +270,7 @@ class LoadStreams: # multiple IP or RTSP cameras
sources = [sources] sources = [sources]
n = len(sources) n = len(sources)
self.imgs = [None] * n self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n
self.sources = [clean_str(x) for x in sources] # clean source names for later self.sources = [clean_str(x) for x in sources] # clean source names for later
for i, s in enumerate(sources): # index, source for i, s in enumerate(sources): # index, source
# Start thread to read frames from video stream # Start thread to read frames from video stream
...@@ -284,13 +284,13 @@ class LoadStreams: # multiple IP or RTSP cameras ...@@ -284,13 +284,13 @@ class LoadStreams: # multiple IP or RTSP cameras
assert cap.isOpened(), f'Failed to open {s}' assert cap.isOpened(), f'Failed to open {s}'
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.fps = (cap.get(cv2.CAP_PROP_FPS) % 100) or 30.0 # assume 30 FPS if cap gets 0 FPS self.fps[i] = (cap.get(cv2.CAP_PROP_FPS) % 100) or 30.0 # assume 30 FPS if cap gets 0 FPS
self.frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) self.frames[i] = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) or float('inf') # assume infinite stream if 0 len
_, self.imgs[i] = cap.read() # guarantee first frame _, self.imgs[i] = cap.read() # guarantee first frame
thread = Thread(target=self.update, args=([i, cap]), daemon=True) self.threads[i] = Thread(target=self.update, args=([i, cap]), daemon=True)
print(f" success ({f'{self.frames} frames ' if self.frames else ''}{w}x{h} at {self.fps:.2f} FPS).") print(f" success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)")
thread.start() self.threads[i].start()
print('') # newline print('') # newline
# check for common shapes # check for common shapes
...@@ -299,18 +299,17 @@ class LoadStreams: # multiple IP or RTSP cameras ...@@ -299,18 +299,17 @@ class LoadStreams: # multiple IP or RTSP cameras
if not self.rect: if not self.rect:
print('WARNING: Different stream shapes detected. For optimal performance supply similarly-shaped streams.') print('WARNING: Different stream shapes detected. For optimal performance supply similarly-shaped streams.')
def update(self, index, cap): def update(self, i, cap):
# Read next stream frame in a daemon thread # Read stream `i` frames in daemon thread
n = 0 n, f = 0, self.frames[i]
while cap.isOpened(): while cap.isOpened() and n < f:
n += 1 n += 1
# _, self.imgs[index] = cap.read() # _, self.imgs[index] = cap.read()
cap.grab() cap.grab()
if n == 4: # read every 4th frame if n % 4: # read every 4th frame
success, im = cap.retrieve() success, im = cap.retrieve()
self.imgs[index] = im if success else self.imgs[index] * 0 self.imgs[i] = im if success else self.imgs[i] * 0
n = 0 time.sleep(1 / self.fps[i]) # wait time
time.sleep(1 / self.fps) # wait time
def __iter__(self): def __iter__(self):
self.count = -1 self.count = -1
...@@ -318,12 +317,12 @@ class LoadStreams: # multiple IP or RTSP cameras ...@@ -318,12 +317,12 @@ class LoadStreams: # multiple IP or RTSP cameras
def __next__(self): def __next__(self):
self.count += 1 self.count += 1
img0 = self.imgs.copy() if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit
if cv2.waitKey(1) == ord('q'): # q to quit
cv2.destroyAllWindows() cv2.destroyAllWindows()
raise StopIteration raise StopIteration
# Letterbox # Letterbox
img0 = self.imgs.copy()
img = [letterbox(x, self.img_size, auto=self.rect, stride=self.stride)[0] for x in img0] img = [letterbox(x, self.img_size, auto=self.rect, stride=self.stride)[0] for x in img0]
# Stack # Stack
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论