鉴于其链接,我想捕获一个在线视频(例如来自YouTube),以便进一步处理而无需在磁盘上下载。我的意思是,我想尽可能将它直接加载到内存中。根据这些链接:
http://answers.opencv.org/question/24012/reading-video-stream-from-ip-camera-in-opencv-java/#24013
http://answers.opencv.org/question/24154/how-to-using-opencv-api-get-web-video-stream/#24156
http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/
https://pypi.org/project/pafy/
它应该是可行的。我的尝试看起来像这样:
import cv2
import pafy
vid = pafy.new("https://www.youtube.com/watch?v=QuELiw8tbx8")
vid_cap = cv2.VideoCapture()
vid_cap.open(vid.getbest(preftype="webm").url)
然而它失败并出现错误
(python:12925): GLib-GObject-CRITICAL **: 14:48:56.168: g_object_set: assertion 'G_IS_OBJECT (object)' failed
False
如何使用python实现我的目标?
答案 0 :(得分:2)
您可以使用youtube-dl
和ffmpeg
:
sudo pip install --upgrade youtube_dl
ffmpeg
。您可以。首先,我们获取此视频可用的格式列表:
youtube-dl --list-formats https://www.youtube.com/watch?v=HECa3bAFAYk
选择您选择的format code
。我想要 144p 分辨率,所以我选择 160 。
接下来,我们通过以下方式获取所选格式的视频网址:
youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk
efficient single-byte and unaligned stores without as much ECC overhead
最后,我们可以在ffplay
或vlc
中播放此视频网址。但是,我们可以在一个命令中执行此操作,而不是复制和粘贴:
ffplay -i $(youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk)
现在我们已确认youtube-dl
和ffmpeg
有效,我们可以编写一个Python脚本来处理OpenCV中的帧。有关更多Python选项,请参阅{{3}}。
import cv2
import numpy as np
import youtube_dl
if __name__ == '__main__':
video_url = 'https://www.youtube.com/watch?v=HECa3bAFAYkq'
ydl_opts = {}
# create youtube-dl object
ydl = youtube_dl.YoutubeDL(ydl_opts)
# set video url, extract video information
info_dict = ydl.extract_info(video_url, download=False)
# get video formats available
formats = info_dict.get('formats',None)
for f in formats:
# I want the lowest resolution, so I set resolution as 144p
if f.get('format_note',None) == '144p':
#get the video url
url = f.get('url',None)
# open url with opencv
cap = cv2.VideoCapture(url)
# check if url was opened
if not cap.isOpened():
print('video not opened')
exit(-1)
while True:
# read frame
ret, frame = cap.read()
# check if frame is empty
if not ret:
break
# display frame
cv2.imshow('frame', frame)
if cv2.waitKey(30)&0xFF == ord('q'):
break
# release VideoCapture
cap.release()
cv2.destroyAllWindows()
答案 1 :(得分:0)
首先使用命令pip install -U youtube-dl
更新youtube-dl
然后使用我的VidGear
Python库,然后仅使用其URL地址自动执行YouTube视频的流水线操作。这是一个完整的python示例:
# import libraries
from vidgear.gears import CamGear
import cv2
stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', y_tube =True, time_delay=1, 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
stream.stop()
# safely close video stream.
如果仍然出现错误,请在其GitHub存储库中提出一个issue here。
答案 2 :(得分:-1)
使用pafy,您可以找到更优雅的解决方案:
import cv2
import pafy
url = "https://www.youtube.com/watch?v=NKpuX_yzdYs"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
capture = cv2.VideoCapture()
capture.open(best.url)
success,image = capture.read()
while success:
cv2.imshow('frame', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
success,image = capture.read()
cv2.destroyAllWindows()
capture.release()
答案 3 :(得分:-1)
我想强调我在运行时遇到的问题是 open-cv 版本问题,我使用的是 OpenCV 3.4.x 并且视频源在被读入 while 循环之前退出,因此,我将我的 open cv 升级为“opencv-contrib-python== 4.2.0.34”。