Getting the file name of downloaded video using yt-dlp
Asked Answered
R

3

10

I'm intending to use yt-dlp to download a video and then cut the video down afterward using ffmpeg. But to be able to use ffmpeg I am going to have to know the name of the file that yt-dlp produces. I have read through their documentation but I can't seem to find a way of getting the file name back into my program.

Rumpf answered 21/10, 2022 at 18:38 Comment(3)
the docs describe how to pull the filenames or set your ownColettecoleus
@Colettecoleus I've tried to set my own file name but it still still appends .f399 or another number to the end, I can't work out what this number is though? As for how to pull the file name, would you mind sending a small extract so I can try and find the section you are talking about. I've looked through but I seem to be missing itRumpf
You can get it from an event.. but you have to extract it from a string, I'm using this regex: /^[\s]*Merging formats into "(.+)"$/ I'm surprised this is not more straightforward.Antonelli
C
7

here are the doc examples

the numbers you mentioned (like .f399) I believe are temp only and are eventually removed when the final file is merged.

if you want to get the filename:

import subprocess
someFilename = subprocess.getoutput('yt-dlp --print filename https://www.youtube.com/something')
# then pass someFilename to FFmpeg

to use your own filename:

subprocess.run('yt-dlp -o thisIsMyName https://www.youtube.com/something')
# this will likely download a file named thisIsMyName.webm

but if you are not sure of the file type/extension beforehand and just want to get that:

someFileType = subprocess.getoutput('yt-dlp --print filename -o "%(ext)s" https://www.youtube.com/something')
print(someFileType)

it's not very efficient but to help explain it:

import subprocess

someFileType = subprocess.getoutput('yt-dlp --print filename -o "%(ext)s" https://www.youtube.com/something')
subprocess.run('yt-dlp -o "myFileName.%(ext)s" https://www.youtube.com/something')
subprocess.run(f'ffmpeg -i "myFileName.{someFileType}" outputFile.mp4')
Colettecoleus answered 21/10, 2022 at 20:25 Comment(0)
U
8

According to the docs, you should be able to pass a progress hook and retrieve the filename there. It should be accessible with the filename attribute, but I have seen instances where it appends the .f399 and/or changes over time. I think it has to do with downloading videos in parts and is actually the temporary filename.

I found that by capturing the whole info_dict dictionary, there is a _filename key that appears to have the final filename.

Here is essentially what I did:

import yt_dlp

final_filename = None

def yt_dlp_monitor(self, d):
    final_filename  = d.get('info_dict').get('_filename')
    # You could also just assign `d` here to access it and see all the data or even `print(d)` as it updates frequently

ydl_opts = {
    "outtmpl": '/whatever/directory/%(uploader)s_%(title)s.%(ext)s',  # this is where you can edit how you'd like the filenames to be formatted
    "progress_hooks": [yt_dlp_monitor]  # here's the function we just defined
    }
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info("http://youtu.be/whatever_video)

Now final_filename will just keep updating with the filename every time that hook is called. You could have it only update on d['status'] == 'finished' if you like.

Unrivalled answered 3/11, 2022 at 14:56 Comment(1)
Caveat: this method won't get processed files, as they have been processed. This case cause problems if you want to get all filenames while some of them have been downloaded. To deal with this, use subprocess to invoke yt-dlp would save your life.Clip
C
7

here are the doc examples

the numbers you mentioned (like .f399) I believe are temp only and are eventually removed when the final file is merged.

if you want to get the filename:

import subprocess
someFilename = subprocess.getoutput('yt-dlp --print filename https://www.youtube.com/something')
# then pass someFilename to FFmpeg

to use your own filename:

subprocess.run('yt-dlp -o thisIsMyName https://www.youtube.com/something')
# this will likely download a file named thisIsMyName.webm

but if you are not sure of the file type/extension beforehand and just want to get that:

someFileType = subprocess.getoutput('yt-dlp --print filename -o "%(ext)s" https://www.youtube.com/something')
print(someFileType)

it's not very efficient but to help explain it:

import subprocess

someFileType = subprocess.getoutput('yt-dlp --print filename -o "%(ext)s" https://www.youtube.com/something')
subprocess.run('yt-dlp -o "myFileName.%(ext)s" https://www.youtube.com/something')
subprocess.run(f'ffmpeg -i "myFileName.{someFileType}" outputFile.mp4')
Colettecoleus answered 21/10, 2022 at 20:25 Comment(0)
S
1

you can use code like this

from yt_dlp import YoutubeDL

url_to_process = 'https://youtu.be/_sample_hash_'


with YoutubeDL() as ydl:
    info_dict = ydl.extract_info(url_to_process, download=True)
    output_filename = ydl.prepare_filename(info_dict)
    print(f"downloaded {output_filename}")

Shibboleth answered 5/9 at 23:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.