1

I'm trying to build a discord music bot and am using youtube_dl for downloading the songs. I want to save them in a directory so I won't have to download them again every time. But I want to change the songs name in the directory.

I know that I'll have to change something in the outtmpl but this is just giving me the youtube name of the song:

ydl_opts = {
            'outtmpl': f'./project/audio/%(title)s.%(ext)s', #Output directory
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',

            }],
        }

        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
             ydl.download([url])

When I replaced the outtmpl with: 'outtmpl': f'./project/audio/{songname}', it gave me the error message: DownloadError: ERROR: audio conversion failed: file:mp3: Invalid argument

Celltox
  • 127
  • 8
  • 1
    Does this answer your question? [Changing name of the video while downloading via youtube-dl](https://stackoverflow.com/questions/32784639/changing-name-of-the-video-while-downloading-via-youtube-dl) – Hossein Heydari Jan 21 '21 at 14:43
  • Doe this answer your question? [youtube-dl python script postprocessing error: FFMPEG codecs aren't being recognized](https://stackoverflow.com/questions/39665160/youtube-dl-python-script-postprocessing-error-ffmpeg-codecs-arent-being-recogn) – Anshul Sharma Jan 21 '21 at 14:49

3 Answers3

1

I know it's an old question but i am doing the same at the moment and doing like so:

import os
import youtube_dl

with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    info = ydl.extract_info(url, download=False)
    name = info.get('title')
    id = info.get('id')
    ydl.download([id])
    for file in os.listdir():
        if file.startswith(name) and file.endswith('.mp3'):
            os.rename(file, your_file_name)
        
BigAgg
  • 31
  • 4
0

For anyone else looking for an answer like me, here's what I came up with.

list = [
    {'title': 'foo', 'url': 'www.youtube.com/foo'}, 
    {'title': 'bar', 'url': 'www.youtube.com/bar'},
    #etc
]

i = 1
for d in list:
    ydl_opts = {
        'outtmpl': '~/AutoYouTube/' + f'{i:02d}' + '. ' + d['title'] + '.%(ext)s',
        'restrictfilenames': True
    }
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download([d['url']])
    i += 1

To me this feels "cleaner" than BigAgg's solution, since it gives files the desired name in the first place instead of renaming files after downloading. That said, there are probably some inefficiencies involved in calling ydl.download() repeatedly within a loop instead of passing a single list to the function, not the least of which is ydl's auto numbering breaks and has to be rebuilt using i incrementing.

Jordan Kizer
  • 167
  • 1
  • 2
  • 8
-1

Try to print your outtmpl to make sure it contains what you expect. The PEP recommends using {variable} instead of %(ext)s in f-strings.

f'./project/audio/{title}.{ext}'

Lukas Schmid
  • 1,895
  • 1
  • 6
  • 18
  • Those `%(...)` tokens are used by [youtube-dl itself](https://github.com/ytdl-org/youtube-dl/blob/master/README.md#configuration); `title` and `ext` likely won't be defined anywhere in OP's code. Their use of an f-string there is pointless, so this answer is irrelevant to the question. – ZeroKnight Jan 21 '21 at 23:00