我正在尝试使用 openCV 捕获 YouTube 直播。
使用pafy我从youtube获取m3u8播放列表(尚未研究播放列表更新),但是播放列表上的片段在多个主机上分散,这似乎导致与第一个主机不同的主机上的片段冻结,然后出现如下错误:
Cannot reuse HTTP connection for different host: r5---sn-x2pm-f5fs.googlevideo.com:-1 != r4---sn-x2pm-f5fs.googlevideo.com:-1
Run Code Online (Sandbox Code Playgroud)
这似乎是 ffmpeg 问题,但也许我错过了一些解决方法?
我的代码:
mPafy = pafy.new('VQOzkTEPCMw')
mStream = mPafy.getbest(preftype="mp4")
capture = cv2.VideoCapture(mStream.url)
while(True):
ret, frame = capture.read()
cv2.imshow('yt', frame)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
编辑:
我绕过VideoCapture并直接调用ffmpeg,它好一点,每当片段位于不同主机上时仍然会冻结,但只持续约1秒。并且段没有丢失,ffmpeg打开新连接并抓取它,只是打开连接需要时间。
TBF 我不知道我应该从哪里开始。一种方法是手动处理 m3u8 播放列表并提供 ffmpeg 数据流进行解码,但这感觉有点矫枉过正。无论如何,这是我当前的代码:
import pafy
from cv2 import cv2
import subprocess as sp
import numpy as np
mPafy = pafy.new('VQOzkTEPCMw')
mStream = mPafy.getbest(preftype='mp4')
frameSize = 3*mStream.dimensions[0]*mStream.dimensions[1]
pipe = sp.Popen(['./ffmpeg.exe', '-i', mStream.url, '-f', 'image2pipe', '-pix_fmt', 'bgr24',
'-vcodec', 'rawvideo', '-'],
stdin=sp.PIPE, stdout=sp.PIPE, bufsize=frameSize)
while(True):
raw = pipe.stdout.read(frameSize)
frame = np.fromstring(raw, dtype='uint8').reshape(
mStream.dimensions[1], mStream.dimensions[0], 3)
cv2.imshow('yt', frame)
if cv2.waitKey(16) & 0xFF == ord('q'):
break
pipe.terminate()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)