OpenCV captura el video en línea para su posterior procesamiento sin descargar el archivo con Python

Dado su enlace, me gustaría capturar un video en línea (por ejemplo, de YouTube) para su posterior procesamiento sin descargarlo en el disco . Lo que quiero decir con esto es que me gustaría cargarlo directamente en la memoria siempre que sea posible. Según estos enlaces:
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/
debería ser factible Mi bash se ve así:

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) 

Sin embargo falla con un error

 (python:12925): GLib-GObject-CRITICAL **: 14:48:56.168: g_object_set: assertion 'G_IS_OBJECT (object)' failed False 

¿Cómo puedo lograr mi objective usando python?

Puedes lograr esto usando youtube-dl y ffmpeg :

  • Instala la última versión de youtube-dl .
  • Luego, sudo pip install --upgrade youtube_dl
  • Construye ffmpeg con soporte HTTPS. Puedes hacerlo activando la opción --enable-gnutls .

Una vez que las instalaciones están completas, es hora de probar el youtube-dl en la terminal. Usaremos este video de youtube para realizar pruebas.

Primero obtenemos la lista de formatos disponibles para este video:

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

Seleccione un format code de format code de su elección. Quiero la resolución de 144p así que selecciono 160 .

imagen

A continuación obtenemos la url de video para nuestro formato de elección por:

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

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 y Xtags = tx% 3D9486108 y itag = 160 & MIME = vídeo% 2Fmp4 y mt = 1529091799 & ms = au% 2Conr y ei = XxckW-73GNCogQfqrryQAg y expire = 1529113535 y mm = 31% 2C26 & c = WEB & keepalive = yes & id = o-AJExEG49WtIUkrF7OikaaGBCfKntDl75xCoO5_9cL-eP y ip = 95.91.202.147 y sparams = aitags% 2Cclen% 2Cdur% 2Cei % 2Cgir% 2Cid% 2Cinitcwndbps% 2Cip% 2Cmm% Pág. 1155000 & ipbits = 0 & ratebypass = yes

Finalmente, podemos reproducir este video url en ffplay o vlc . Pero en lugar de copiar y pegar, podemos hacer esto en un solo comando:

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

Ahora que hemos confirmado que youtube-dl y ffmpeg funcionan, podemos escribir un script de Python para procesar los marcos en OpenCV. Vea este enlace para más opciones de Python.

 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() 

Usando pafy puedes tener una solución más elegante:

 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()