我正在尝试使用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
这似乎是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()
编辑:
我绕过了VideoCapture并直接调用了ffmpeg,这好一点了,每当分段位于不同的主机上时,仍然会冻结,但仅持续约1秒钟。并且段没有丢失,ffmpeg打开新连接并获取它,打开连接只需要时间。
待定,我不知道该从哪里去。一种方法是手动处理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()