Search code examples
pythonpython-3.xyoutube-apipytube

How to download a youtube video without audio with PyTube (mp4, good quality)


I have been troubleshooting on this for an hour or two now, sometimes guessing with certain parameters and their values with the streams.filter() method. I want to fetch a mp4 video without its audio attached. You'd think this may be easy, but it isn't, at least for me.

The streams filter parameters, are listed and present some ones that stick out for what I want to achieve. only_video, mime_type, or maybe res and fps. You can read their descriptions to get an idea of what they will do.

Now, applying parameters together basically means you well, are filtering your available options based on your filter. The options will specify the above objects and more as it's is own download preset if you will. To actually pick one, you can use first(), last(), get_highest_resolution(), etc, to settle on your desired download.

I have tried several parameters some of them listed above, to get a silent video that isn't 5 seconds long with this:

yt = YouTube(query)
t = yt.streams.filter(only_video=True).first()
print(t)
t.download(self.path, filename_prefix="Scout_")

With this output, it looks promising, however, using first() is common and it recommended to get the job done. As said, "the first result of this query". I needed to switch the order up, so I tried using last() instead, and it work. But, it was a 140p webm file. After stumbling across this code structure, I am tinkering with it to see if I can grab a good quality mp4 without sound, whereas I am having a bit of trouble now, which brings me to writing this post.

Yes, I am printing the stream/query results that I am using with my parameters to look at my options. I really need some insight on this, whether I should fix this with pytube, or default to using ffmpeg. I don't want to be picky, but if its possible and not totally irreverent, I want get this no audio file using pytube itself.

Any thoughts as to how I can achieve this!


Solution

  • ANSWER or EXPLANATION

    After fiddling with this some more. Using only_video=True doesn't seem to be compatible with certain methods that are appealing to include for a good video. However, it seems as of now only using pytube, you can get a full length video that isn't corrupted but only in 360p.

    t = yt.streams.filter(only_video=True).get_by_itag(itag=134)
    print(t)
    t.download(self.path, filename_prefix="Scout_")
    

    This takes an itag (which I believe doesn't change for anyone and videos) thats silent video at 360p. I tried going to 480p and up and got 5 second videos. I printed that list here.

    t = yt.streams.filter(only_video=True).all()
    print(t)
    

    I am sticking with this method for now, I will come across a better method in the future. Hope this helps anyone!