如何使用 openCV python 阅读 Youtube 直播?
Posted
技术标签:
【中文标题】如何使用 openCV python 阅读 Youtube 直播?【英文标题】:How to read Youtube live stream using openCV python? 【发布时间】:2017-08-19 07:40:39 【问题描述】:我想从 youtube 读取实时流来执行一些基本的 CV 操作,可能我们必须以某种方式剥离 youtube URL 以将其转换为 openCV 可以读取的格式,例如?:
cap = cv2.VideoCapture('https://www.youtube.com/watch?v=_9OBhtLA9Ig')
有人做过吗?
【问题讨论】:
尝试使用urllib
见THIS PAGE
【参考方案1】:
我相信你现在已经知道答案了,但我会为其他搜索相同主题的人回答。您可以使用Pafy(可能与youtube_dl 一起使用)来做到这一点。
import pafy
import cv2
url = "https://www.youtube.com/watch?v=_9OBhtLA9Ig"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
capture = cv2.VideoCapture(best.url)
while True:
grabbed, frame = capture.read()
# ...
应该就是这样。
【讨论】:
它适用于视频。但是我正在为实时流媒体尝试相同的方法,并且 VideoCapture 读取方法在大约 40 或 50 帧后卡住了。有什么想法吗? @Guillem 这似乎也适用于直播。也许是特定的流? @Guillem 尝试垃圾回收 这是我要找的,谢谢【参考方案2】:在 100-120 帧之后,@lee hannigan 的回答让我在 youtube 上进行了直播。
我与 Pafy 一起制定了一种方法,只需抓取 x 个帧并将它们拼接在一起。然而,这最终将这些块拼接在一起很糟糕,并给出了不稳定的结果。 Pafy 可能不是为直播而设计的,我找不到将帧无缝拼接在一起的方法。
最终起作用的方法如下,根据guttentag_liu 在this post 上的回答稍作修改。它需要更多的包,而且很长,但是可以。因为文件是活动的,所以它需要分块,因此保存到临时文件中。您可能可以对每个块进行 openCV 工作,然后最后保存到文件中,而不是重新打开。
# pip install urllib
# pip install m3u8
# pip install streamlink
from datetime import datetime, timedelta, timezone
import urllib
import m3u8
import streamlink
import cv2 #openCV
def get_stream(url):
"""
Get upload chunk url
input: youtube URL
output: m3u8 object segment
"""
#Try this line tries number of times, if it doesn't work,
# then show the exception on the last attempt
# Credit, theherk, https://***.com/questions/2083987/how-to-retry-after-exception
tries = 10
for i in range(tries):
try:
streams = streamlink.streams(url)
except:
if i < tries - 1: # i is zero indexed
print(f"Attempt i+1 of tries")
time.sleep(0.1) #Wait half a second, avoid overload
continue
else:
raise
break
stream_url = streams["best"] #Alternate, use '360p'
m3u8_obj = m3u8.load(stream_url.args['url'])
return m3u8_obj.segments[0] #Parsed stream
def dl_stream(url, filename, chunks):
"""
Download each chunk to file
input: url, filename, and number of chunks (int)
output: saves file at filename location
returns none.
"""
pre_time_stamp = datetime(1, 1, 1, 0, 0, tzinfo=timezone.utc)
#Repeat for each chunk
#Needs to be in chunks because
# 1) it's live
# 2) it won't let you leave the stream open forever
i=1
while i <= chunks:
#Open stream
stream_segment = get_stream(url)
#Get current time on video
cur_time_stamp = stream_segment.program_date_time
#Only get next time step, wait if it's not new yet
if cur_time_stamp <= pre_time_stamp:
#Don't increment counter until we have a new chunk
print("NO pre: ",pre_time_stamp, "curr:",cur_time_stamp)
time.sleep(0.5) #Wait half a sec
pass
else:
print("YES: pre: ",pre_time_stamp, "curr:",cur_time_stamp)
print(f'#i at time cur_time_stamp')
#Open file for writing stream
file = open(filename, 'ab+') #ab+ means keep adding to file
#Write stream to file
with urllib.request.urlopen(stream_segment.uri) as response:
html = response.read()
file.write(html)
#Update time stamp
pre_time_stamp = cur_time_stamp
time.sleep(stream_segment.duration) #Wait duration time - 1
i += 1 #only increment if we got a new chunk
return None
def openCVProcessing(saved_video_file):
'''View saved video with openCV
Add your other steps here'''
capture = cv2.VideoCapture(saved_video_file)
while capture.isOpened():
grabbed, frame = capture.read() #read in single frame
if grabbed == False:
break
#openCV processing goes here
#
cv2.imshow('frame',frame) #Show the frame
#Shown in a new window, To exit, push q on the keyboard
if cv2.waitKey(20) & 0xFF == ord('q'):
break
capture.release()
cv2.destroyAllWindows() #close the windows automatically
tempFile = "temp.ts" #files are format ts, open cv can view them
videoURL = "https://www.youtube.com/watch?v=_9OBhtLA9Ig"
dl_stream(videoURL, tempFile, 3)
openCVProcessing(tempFile)
【讨论】:
嘿杰夫!做得好!我已经尝试过了,但它对我的工作不一致。有时,它很棒并且按预期工作,有时,我得到一个“插件错误,如下所示:”插件错误:无法打开 URL:youtube.com/get_video_info(404 客户端错误:未找到 url:youtube.com/…)我假设这与我经常尝试访问该页面有关。不确定。有什么想法吗? @user2813606 我现在得到了相同的 pluginError 和 HTTPError(我以前没有)。如果您转到列出的错误 url,它会给出以下错误消息:status=fail&errorcode=2&reason=Invalid+parameters。我在上面的答案中添加了一个循环重试几次,并等待该段的持续时间以避免系统过载。如果你喜欢这个答案,请点赞:)【参考方案3】:我在 VidGear Python 库中添加了 Youtube URL 源支持,该库仅通过提供其 URL 来自动将 YouTube 视频通过管道传输到 OpenCV。这是一个完整的python示例:
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', stream_mode = True, logging=True).start() # YouTube Video URL as input
# infinite loop
while True:
frame = stream.read()
# read frames
# check if frame is None
if frame is None:
#if True break the infinite loop
break
# do something with frame here
cv2.imshow("Output Frame", frame)
# Show output window
key = cv2.waitKey(1) & 0xFF
# check for 'q' key-press
if key == ord("q"):
#if 'q' key-pressed break out
break
cv2.destroyAllWindows()
# close output window
# safely close video stream.
stream.stop()
Code Source
【讨论】:
以上是关于如何使用 openCV python 阅读 Youtube 直播?的主要内容,如果未能解决你的问题,请参考以下文章
如何在python中使用opencv模块(我正在使用pycharm)[重复]