back to index

YouTube Downloader

Locally hosted youtube downloader for mp3 and mp4s

repo: https://github.com/EricSpencer00/youtubeDL


A localhost webapp that downloads mp3s and mp4s from YouTube, for the case where a song or video is not available on iTunes.

A screenshot of the script hosted locally and served via Flask: youtube-dl

Without the webapp, the script alone does the same job:


import os
import re
import yt_dlp
from textblob import TextBlob

def clean_title(title):
    """Removes unnecessary characters from title"""
    return re.sub(r'[<>:"/\\|?*]', '', title)

def extract_metadata(title):
    """Uses NLP to guess the artist and song title"""
    parts = title.split("-")
    if len(parts) == 2:
        artist, song = parts[0].strip(), parts[1].strip()
    else:
        blob = TextBlob(title)
        words = blob.words
        if len(words) > 2:
            artist, song = words[0], " ".join(words[1:])
        else:
            artist, song = "Unknown", title
    return artist, song

def download_video(youtube_url, format_choice):
    """Downloads the YouTube video as MP3 or MP4"""
    
    download_path = os.path.expanduser('~/Downloads')  # Save to ~/Downloads
    
    if format_choice == 'mp3':
        ydl_opts = {
            'format': 'bestaudio/best',
            'extract_audio': True,
            'audio_format': 'mp3',
            'outtmpl': os.path.join(download_path, '%(title)s.%(ext)s'),
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
        }
    elif format_choice == 'mp4':
        ydl_opts = {
            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]',
            'outtmpl': os.path.join(download_path, '%(title)s.%(ext)s'),
            'merge_output_format': 'mp4',  # Ensures MP4 output
        }
    else:
        print("⚠️ Invalid format choice. Please enter 'mp3' or 'mp4'.")
        return

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(youtube_url, download=True)
        title = clean_title(info['title'])  # Get the video title
        filename = os.path.join(download_path, f"{title}.mp4" if format_choice == 'mp4' else f"{title}.mp3")
        
        print(f"✅ File saved as: {filename}")

if __name__ == "__main__":
    youtube_url = input("🎥 Enter YouTube URL: ")
    format_choice = input("🎵 Download as MP3 or 🎬 MP4? (mp3/mp4): ").strip().lower()
    download_video(youtube_url, format_choice)

It does not work on internet-hosted Python interpreters, because YouTube blocks IP addresses belonging to data centers. Running it on pythonanywhere.com produces logs saying that none of the requests to Google were accepted.

The yt-dlp library is updated constantly to keep pace with Google's attempts to prevent this kind of downloading, so the pip environment needs updating regularly.