Advertisement
yclee126

YouTube to .mp3 downloader

Nov 12th, 2022
843
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.75 KB | None | 0 0
  1. # YouTube url -> .mp3 with tags downloader
  2. # require FFmpeg in PATH or in the same folder
  3. # no support for private or premium videos
  4.  
  5. import music_tag
  6. from pytube import YouTube
  7. import requests
  8. from dataclasses import dataclass
  9. import subprocess
  10. import os
  11. from pathvalidate import sanitize_filename
  12.  
  13. @dataclass
  14. class AudioSpec:
  15.     subtype: str
  16.     bitrate: str
  17.  
  18. audio_precedence = (
  19.     AudioSpec('webm', '160kbps'),
  20.     AudioSpec('mp4', '128kbps'),
  21.     AudioSpec('webm', '70kbps'),
  22.     AudioSpec('webm', '50kbps'),
  23.     AudioSpec('mp4', '48kbps'),
  24. )
  25.  
  26.  
  27. def main(url, output_path='.'):
  28.     # set-up dict
  29.     video_info = {'url':url}
  30.  
  31.     # get YouTube instance
  32.     tube = YouTube(video_info['url'])
  33.  
  34.     # get infos
  35.     video_info['author'] = tube.author
  36.     video_info['title'] = tube.title
  37.     print('Title:', video_info['title'])
  38.  
  39.     thumbnail_response = requests.get(tube.thumbnail_url)
  40.     video_info['thumbnail'] = thumbnail_response.content
  41.  
  42.     # get audio stream -- try according to the precedence
  43.     audio_streams = tube.streams.filter(only_audio=True)
  44.     audio_stream = None # Stream instance
  45.     audio_type = None # webm or mp4
  46.  
  47.     for spec in audio_precedence:
  48.         filtered = audio_streams.filter(subtype=spec.subtype, bitrate=spec.bitrate)
  49.         if len(filtered) != 0:
  50.             audio_stream = filtered[0]
  51.             audio_type = spec.subtype
  52.             print('Stream: ', audio_stream)
  53.             break
  54.     else:
  55.         raise Exception('Error: No usable audio found')
  56.  
  57.     # prepare output dir
  58.     if not os.path.isdir(output_path):
  59.         os.mkdir(output_path)
  60.  
  61.     # download into mp3 file
  62.     sanitized_title = sanitize_filename(video_info['title']) # external library to make the pain to go away
  63.     audio_temp = sanitized_title + '.' + audio_type
  64.     audio_final = None
  65.  
  66.     if audio_type != 'mp3':
  67.         audio_final = output_path + '/' + sanitized_title + '.mp3'
  68.  
  69.         # convert to mp3
  70.         audio_stream.download(filename=audio_temp)
  71.         subprocess.run(['ffmpeg', '-y', '-i', audio_temp, '-b:a', '192k', '-vn', audio_final])
  72.  
  73.         # delete old file
  74.         os.remove(audio_temp)
  75.  
  76.     else:
  77.         audio_final = output_path+'/'+audio_temp
  78.         audio_stream.download(filename=audio_final)
  79.  
  80.     # set tags
  81.     tag = music_tag.load_file(audio_final)
  82.    
  83.     tag['artwork'] = video_info['thumbnail']
  84.     tag['title'] = video_info['title']
  85.     tag['artist'] = video_info['url']
  86.     tag['album'] = video_info['author'] # same album = same channel
  87.    
  88.     tag.save()
  89.  
  90.  
  91. if __name__ == '__main__':
  92.     url = input('Enter a YouTube URL: ')
  93.     try:
  94.         main(url, 'downloaded')
  95.     except Exception as e:
  96.         print('Error:', e)
  97.         input('Press enter to exit..')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement