OpenCV捕获在线视频以便进一步处理,无需使用Python下载文件

时间:2018-06-15 13:07:54

标签: python opencv

鉴于其链接,我想捕获一个在线视频(例如来自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实现我的目标?

4 个答案:

答案 0 :(得分:2)

您可以使用youtube-dlffmpeg

来实现这一目标
  • 安装最新版本的this youtube video
  • 然后执行sudo pip install --upgrade youtube_dl
  • 使用HTTPS支持构建ffmpeg。您可以image
  • 执行此操作

安装完成后,是时候测试终端中的youtube-dl了。我们将使用https://r3---sn-4g5e6nz7.googlevideo.com/videoplayback?clen=184077&aitags=133%2C134%2C160%2C242%2C243%2C278&fvip=3&requiressl=yes&signature=5D21FFD906226C7680B26ACEF996B78B6A31F7C9.31B1115DB13F096AA5968DB2838E22A0D6A2EDCB&source=youtube&mn=sn-4g5e6nz7%2Csn-h0jeen7y&xtags=tx%3D9486108&itag=160&mime=video%2Fmp4&mt=1529091799&ms=au%2Conr&ei=XxckW-73GNCogQfqrryQAg&expire=1529113535&mm=31%2C26&c=WEB&keepalive=yes&id=o-AJExEG49WtIUkrF7OikaaGBCfKntDl75xCoO5_9cL-eP&ip=95.91.202.147&sparams=aitags%2Cclen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cxtags%2Cexpire&key=yt6&lmt=1526699176943888&dur=25.375&pl=22&gir=yes&mv=m&initcwndbps=1155000&ipbits=0&ratebypass=yes进行测试。

首先,我们获取此视频可用的格式列表:

youtube-dl --list-formats https://www.youtube.com/watch?v=HECa3bAFAYk

选择您选择的format code。我想要 144p 分辨率,所以我选择 160

this link

接下来,我们通过以下方式获取所选格式的视频网址:

youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk
  

efficient single-byte and unaligned stores without as much ECC overhead

最后,我们可以在ffplayvlc中播放此视频网址。但是,我们可以在一个命令中执行此操作,而不是复制和粘贴:

ffplay -i $(youtube-dl --format 160 --get-url https://www.youtube.com/watch?v=HECa3bAFAYk)

现在我们已确认youtube-dlffmpeg有效,我们可以编写一个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.

来源:https://github.com/abhiTronix/vidgear/wiki/CamGear-Class#2-camgear-class-with-live-youtube-piplineing-using-video-url

如果仍然出现错误,请在其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”。