YouTube video Downloader python

482 Views Asked by At

I made a youtube video download Manager. It download a video but i am facing one issue when i download same video, it doesn't download it again. how can i download it again with same title like pic.png and send pic1.png. How can i do that?

def Download(self):
    video_url = self.lineEdit.text()
    save_location = self.lineEdit_2.text()
    if video_url == '' or save_location == '':
        QMessageBox.warning(self, "Data Error", "Provide a Valid Video URL or save Location")

    else:
        video = pafy.new(video_url)
        video_stream = video.streams
        video_quality = self.comboBox.currentIndex()

        download = video_stream[video_quality].download(filepath=save_location, callback=self.Handel_Progress, )
1

There are 1 best solutions below

3
On

Ok, this one is interesting.

The real problem begins here.

    download = video_stream[video_quality].download(filepath=save_location, callback=self.Handel_Progress, )

Here, you are calling download function of video_stream object which takes filepath as an argument for file location but does not take the filename, because, obviously, the file would be saved with the actual name.

Root Cause of your problem:

If you look into the definition of download function, you would find that if a file exists with the same name, it would not download the file at all.

Now comes the part, how do you make sure it downloads, no matter what:

There are two things you need to do:

  1. Check if a file with same name exists or not, and if does, then add 1 in the end of the file name just before the extension. So if abc.mp4 exists, then save abc1.mp4. [I will tell you how to handle the scenario when abc.mp4, abc1.mp4 and so on exists, but for now, let's get back to the problem.]

  2. How to pass the file name (abc1.mp4) to the download method?

Following piece of code would handle both. I have added comments for your understanding.

import os
import re

import pafy
from pafy.util import xenc


# this function is used by pafy to generate file name while saving,
# so im using the same function to get the file name which I will use to check
# if file exists or not
# DO NOT CHANGE IT
def generate_filename(title, extension):
    max_length = 251

    """ Generate filename. """
    ok = re.compile(r'[^/]')

    if os.name == "nt":
        ok = re.compile(r'[^\\/:*?"<>|]')

    filename = "".join(x if ok.match(x) else "_" for x in title)

    if max_length:
        max_length = max_length + 1 + len(extension)
        if len(filename) > max_length:
            filename = filename[:max_length - 3] + '...'

    filename += "." + extension
    return xenc(filename)


def get_file_name_for_saving(save_location, full_name):
    file_path_with_name = os.path.join(save_location, full_name)

    # file exists, add 1 in the end, otherwise return filename as it is
    if os.path.exists(file_path_with_name):
        split = file_path_with_name.split(".")
        file_path_with_name = ".".join(split[:-1]) + "1." + split[-1]

    return file_path_with_name


def Download(self):
    video_url = self.lineEdit.text()
    save_location = self.lineEdit_2.text()
    if video_url == '' or save_location == '':
        QMessageBox.warning(self, "Data Error", "Provide a Valid Video URL or save Location")

    else:
        # video file
        video = pafy.new(video_url)

        # available video streams
        video_stream = video.streams
        video_quality = self.comboBox.currentIndex()

        # video title/name
        video_name = video.title

        # take out the extension of the file from video stream
        extension = video_stream[video_quality].extension

        # fullname with extension
        full_name = generate_filename(video_name, extension)

        final_path_with_file_name = get_file_name_for_saving(save_location, full_name)

        download = video_stream[video_quality].download(filepath=final_path_with_file_name,
                                                        callback=self.Handel_Progress, )

Let me know if you face any issues.