Skip to content Skip to sidebar Skip to footer

Capture Youtube Video For Further Processing Without Downloading The Video

Given its link, I'd like to capture an online video (say from YouTube) for further processing without downloading it on the disk. What I mean by this is that I'd like to load it di

Solution 1:

You can achieve this by using youtube-dl and ffmpeg:

Once the installations are complete, it's time to test the youtube-dl in terminal. We'll be using this youtube video for testing.

First we get the list of formats available for this video:

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

Select a format code of your choice. I want the 144p resolution so I select 160.

image

Next we get the video url for our format of choice by:

youtube-dl--format160--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&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

Finally we can play this video url in either ffplay or vlc. But instead of copying and pasting, we can do this in one command:

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

Now that we have confirmed that youtube-dl and ffmpeg works, we can write a Python script to process the frames in OpenCV. See this link for more Python options.

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 144pif 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 openedifnot cap.isOpened():
                print('video not opened')
                exit(-1)

            whileTrue:
                # read frame
                ret, frame = cap.read()

                # check if frame is emptyifnot ret:
                    break# display frame
                cv2.imshow('frame', frame)

                if cv2.waitKey(30)&0xFF == ord('q'):
                    break# release VideoCapture
            cap.release()

    cv2.destroyAllWindows()

Solution 2:

First of all Update youtube-dl using the command pip install -U youtube-dl

Then use my VidGear Python Library, then automates the pipelining of YouTube Video using its URL address only. Here's a complete python example:

For VidGear v0.1.9 below:

# import librariesfrom 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 loopwhileTrue:
    
    frame = stream.read()
    # read frames# check if frame is Noneif frame isNone:
        #if True break the infinite loopbreak# do something with frame here
    
    cv2.imshow("Output Frame", frame)
    # Show output window

    key = cv2.waitKey(1) & 0xFF# check for 'q' key-pressif key == ord("q"):
        #if 'q' key-pressed break outbreak

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 librariesfrom 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 loopwhileTrue:
    
    frame = stream.read()
    # read frames# check if frame is Noneif frame isNone:
        #if True break the infinite loopbreak# do something with frame here
    
    cv2.imshow("Output Frame", frame)
    # Show output window

    key = cv2.waitKey(1) & 0xFF# check for 'q' key-pressif key == ord("q"):
        #if 'q' key-pressed break outbreak

cv2.destroyAllWindows()
# close output window# safely close video stream.
stream.stop()

Code Source

If still get some error, raise an issue here in its GitHub repo.

Solution 3:

Using pafy you can have a more elegant solution:

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

Solution 4:

I want to highlight the issue I faced while running was a open-cv version problem, I was using OpenCV 3.4.x and the video feed was exiting before being read into the while loop, so, i upgraded my open cv to "opencv-contrib-python== 4.2.0.34".

Post a Comment for "Capture Youtube Video For Further Processing Without Downloading The Video"