7

I am using youtube-dl with a flask app to download a file and return the file. When I download the filename is changed slightly from the video title. Looking through the source code I thought I found it with the function encodeFilename in utils.py. However, this is still not a match and I can't return the file.

How could I get the filename, or alternatively change the filename that is downloaded?

This is my code at the moment:

def preferredencoding():
    try:
        pref = locale.getpreferredencoding()
        'TEST'.encode(pref)
    except Exception:
        pref = 'UTF-8'

    return pref


def get_subprocess_encoding():
    if sys.platform == 'win32' and sys.getwindowsversion()[0] >= 5:
        encoding = preferredencoding()
    else:
        encoding = sys.getfilesystemencoding()
    if encoding is None:
        encoding = 'utf-8'
    return encoding


@app.route('/api/v1/videos', methods=['GET'])
def api_id():
    if 'link' in request.args:
        link = request.args['link']
        print("Getting YouTube video")
        try:
            title = youtube_dl.YoutubeDL().extract_info(link, download=False)["title"]
            print(title.encode(get_subprocess_encoding(), 'ignore'))
            print(title)
            code=link.split('v=')[1]
            youtube_dl.YoutubeDL().download([link])
            return send_from_directory(r'C:\Users\User123', title+'-'+code+'.mp4')
        except:
            return "<h1>Error</h1>
davidism
  • 121,510
  • 29
  • 395
  • 339
GAP2002
  • 870
  • 4
  • 20

2 Answers2

6
class FilenameCollectorPP(youtube_dl.postprocessor.common.PostProcessor):
    def __init__(self):
        super(FilenameCollectorPP, self).__init__(None)
        self.filenames = []

    def run(self, information):
        self.filenames.append(information['filepath'])
        return [], information
    
filename_collector = FilenameCollectorPP()

my_youtube_dl = youtube_dl.YoutubeDL()
my_youtube_dl.add_post_processor(filename_collector)

# do some downloading, then look inside filename_collector.filenames

Inspired by https://github.com/ytdl-org/youtube-dl/issues/27192#issuecomment-738004623

user357269
  • 1,835
  • 14
  • 40
2

PostProcessor will not give you the file name in case ffmpeg crashes (or you kill the ffmpeg process to stop the download).
Instead we read the video/stream information from the website, extract the filename and then start the download.

import yt_dlp

file_path = ""
with yt_dlp.YoutubeDL() as ydl:
    info = ydl.extract_info(url, download=False)
    file_path = ydl.prepare_filename(info)

    ydl.process_info(info)  # starts the download

Keep in mind that in case ffmpeg crashes, the file will have a .part extension too.

user136036
  • 11,228
  • 6
  • 46
  • 46