19

This link has a tidy little example of how to use python's OpenCV library, cv2 to stream data from a camera into your python shell. I'm looking to do some experiments and would like to use the following YouTube video feed: https://www.youtube.com/watch?v=oCUqsPLvYBQ.

I've tried adapting the example as follows:

import numpy as np
import cv2

cap = cv2.VideoCapture('https://www.youtube.com/watch?v=oCUqsPLvYBQ')

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Display the resulting frame
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

Which produces the error:

WARNING: Couldn't read movie file https://www.youtube.com/watch?v=oCUqsPLvYBQ
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /tmp/opencv20160107-29960-t5glvv/opencv-2.4.12/modules/highgui/src/window.cpp, line 261

Is there a simple fix that would allow me to stream this video feed into my python shell via cv2? Not absolutely committed to cv2, either, if there are other libraries out there that will accomplish the same purpose.

aaron
  • 6,339
  • 12
  • 54
  • 80
  • 3
    I don't think it's possible to open `VideoCapture` like this. In openCV documentation on [videocapture](http://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html#a949d90b766ba42a6a93fe23a67785951) is written that the argument should be a file. But you can use [youtube-dl](https://rg3.github.io/youtube-dl/) in between. – Dimitri Podborski Jun 01 '16 at 16:42
  • @incBrain: this looks promising, thanks. will check it out ASAP and let you know. – aaron Jun 01 '16 at 18:11
  • 2
    @incBrain: `youtube-dl` was the way to go. Thanks for the tip! – aaron Jun 14 '16 at 22:37

5 Answers5

25

you need to have 2 things installed

  1. pafy (pip install pafy)
  2. youtube_dl (sudo pip install --upgrade youtube_dl)

after installing these two packages you can use the youtube url to play the streaming videos from youtube. Please refer the code below

url = 'https://youtu.be/W1yKqFZ34y4'
vPafy = pafy.new(url)
play = vPafy.getbest(preftype="webm")

#start the video
cap = cv2.VideoCapture(play.url)
while (True):
    ret,frame = cap.read()
    """
    your code here
    """
    cv2.imshow('frame',frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break    

cap.release()
cv2.destroyAllWindows()
Zeeshan Ali
  • 137
  • 1
  • 10
Vaibhav K
  • 2,762
  • 3
  • 21
  • 22
  • 1
    Right on, thanks. It's been ages since I asked this question. Could someone please test this and confirm that it works so that I can select the answer?? – aaron Jun 26 '18 at 00:06
  • It is working as I have pasted the working code from my script. you can also try it. – Vaibhav K Jun 26 '18 at 07:44
  • 9
    Not Working, using opencv 3.4.0 – Arjun Kava Jul 19 '18 at 11:46
  • @ArjunKava Do you found way to fix this issue? – wownis Apr 24 '19 at 15:00
  • Nope, @wownis. I had downloaded a video stream in the chunk and then used video capture. – Arjun Kava Apr 25 '19 at 13:15
  • How is this accepted as an answer VideoCapture() accepts only filenames according to documentation and any youtube stream url just returns nothing. – balalaika May 07 '19 at 10:07
  • 1
    IOError: ERROR: W1yKqFZ34y4: "token" parameter not in video info for unknown reason; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its com plete output. – Mustard Tiger May 30 '19 at 19:29
  • Traceback (most recent call last): File "test2.py", line 18, in cv2.imshow('frame',frame) cv2.error: OpenCV(3.4.2) /tmp/build/80754af9/opencv-suite_1535558553474/work/modules/highgui/src/window.cpp:356: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow' – CraigDavid Aug 09 '19 at 20:50
  • Check whether your pafy is working correctly or not. It should return a video stream (https://pythonhosted.org/Pafy/ ) also check the prefered type argument it can have different values as mentioned below : preftype (str) – Preferred type, set to mp4, webm, flv, 3gp or any – Vaibhav K Sep 03 '19 at 09:08
  • 1
    @ArjunKava the solution is to upgrade your openCV version :-) – Francis Gonzales Nov 27 '19 at 23:01
  • try play = vPafy.getbest(preftype="mp4") instead of play = vPafy.getbest(preftype="webm") – Dr Sheldon Apr 14 '21 at 05:19
3

it is possible with pafy (https://pypi.python.org/pypi/pafy)

import cv2, pafy

url = "https://www.youtube.com/watch?v=aKX8uaoy9c8"
videoPafy = pafy.new(url)
best = videoPafy.getbest(preftype="webm")

video=cv2.VideoCapture(best.url)
Sylwek
  • 685
  • 1
  • 7
  • 16
  • 6
    This doesn't work (at least with OpenCV 3.4.0). video.read() returns always (False, None). The url is valid, e.g. wget would download the video. – burny Feb 13 '18 at 13:18
  • @burny You found a way to fix it? – wownis Apr 24 '19 at 15:03
2

@incBrain's suggestion to download the youtube video to local mp4 was the way to go here. Here were the steps that I used to set up a remote server environment on EC2, with output piped into my local computer via X11 forwarding:

  • ssh -X -i "<ssh_key.pem>" ubuntu@<IP-address>.compute-1.amazonaws.com (Note the -X option is an important addition here. It's what we use to pass output from the EC-2 server to a local X11 client)
  • sudo pip install --upgrade youtube_dl (I know, sudo pip is bad. I blame the site instructions)
  • Download youtube video to local file: youtube-dl https://www.youtube.com/watch?v=VUjF1fRw9sA -o motocross.mp4
  • python demo_cv.py

X11 forwarding can be tricky. If you run into any hangups there this post might be helpful to you also.

Community
  • 1
  • 1
aaron
  • 6,339
  • 12
  • 54
  • 80
  • 2
    Is it possible to access it as a stream? Instead of having to wait for the file to download. – Anand C U Mar 22 '18 at 06:05
  • Also, we have legal constraints that disallows us from actually downloading the file and requires us to use streaming only. – burny Jul 31 '20 at 11:56
2

I've added Youtube URL source support in my VidGear Python Library that automatically pipelines YouTube Video into OpenCV by providing its URL only. Here is a complete python example:

For VidGear v0.1.9 below:

# import libraries
from vidgear.gears import CamGear
import cv2

stream = CamGear(source='https://youtu.be/dQw4w9WgXcQ', y_tube = 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()

For VidGear v0.2.0 and above: (y_tube changed to stream_mode)

# 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

abhiTronix
  • 1,248
  • 13
  • 17
  • I tried this and got None frame, same as I got with pafy. – ruckc Aug 24 '19 at 23:00
  • 2
    @ruckc This is an issue with the [`opencv-python`](https://github.com/skvark/opencv-python) library that doesn't support the `https` protocol due to lack of OpenSSL support in its FFmpeg build, more insight of this bug is [here](https://github.com/abhiTronix/vidgear/issues/14#issuecomment-494364397). The good news is that I recently pushed a [PR in opencv-python library](https://github.com/skvark/opencv-python/pull/229) that completely fixes this issue and has been merge by its author. So kindly wait few days when these bug-free binaries officially get available on PyPi to download. Goodluck. – abhiTronix Aug 25 '19 at 08:00
  • @ruckc This bug is now fixed. Kindly update to latest opencv-python. – abhiTronix Sep 05 '19 at 08:07
  • can you make this code switch to live...? I mean, whenever I use it for a live stream that has been playing on YouTube for 20 mins, this code always starts reading from 00.00. I want it to start from 20 mins – Mumbaikar007 Mar 01 '20 at 05:32
  • @Mumbaikar007 Raise this issue on our GitHub repo. [here](https://github.com/abhiTronix/vidgear/issues/new/choose), we will surely work on it. – abhiTronix Mar 08 '20 at 03:43
0
#pip install pafy
#sudo pip install --upgrade youtube_dl
import cv2, pafy

url   = "https://www.youtube.com/watch?v=qvyTx01ZcQQ"
video = pafy.new(url)
best  = video.getbest(preftype="mp4")
capture = cv2.VideoCapture(best.url)
while True:
    check, frame = capture.read()
    print (check, frame)

    cv2.imshow('frame',frame)
    cv2.waitKey(10)

capture.release()
cv2.destroyAllWindows()

Try this, works well on live streams too

Dr Sheldon
  • 176
  • 1
  • 14