일상용/연습장

python 으로 mp3 다운로드 프로그램 작성하기

alpakaka 2025. 2. 13. 23:10

오늘은 python으로 mp3 다운로드 받는 간단한 프로그램을 만들어보려고한다.

요즘 빠진 노래가 있는데 youtube로 들으면 데이터가 나가기도 하고..

원래 개인적으로 사용하던 앱이 있긴 했는데 그 앱이 뭔가 악성코드가 의심되는 문구가 있어서 무서워서 지워버린겸

사용해보려고한다.

 

일단 간단하게 gpt 와 작성해봤다.

import os

import ffmpeg
import pytube


def download_youtube_mp3(url, output_folder="downloads"):
    os.makedirs(output_folder, exist_ok=True)

    youtube_link = pytube.YouTube(url)
    print(f"Downloading: {youtube_link.title}")

    audio_stream = youtube_link.streams.filter(only_audio=True).first()
    audio_file = audio_stream.download(output_folder)

    base, ext = os.path.splitext(audio_file)
    mp3_file = f"{base}.mp3"

    print(f"Converting to mp3: {mp3_file}")
    ffmpeg.input(audio_file).output(mp3_file, format="mp3", loglevel="quiet").run(
        overwire_output=True
    )

    os.remove(audio_file)

    print(f"Downloaded and converted: {mp3_file}")
    return mp3_file


if __name__ == "__main__":
    video_url = input("Enter the YouTube video URL: ")
    download_youtube_mp3(video_url)

이런식으로 하라고 하는데 일단 추가하고 싶은 것은 노래 제목을 입력하면 알아서 official 링크를 쉽게 찾아주면 좋겠다. 추가해보자

 

일단 가수명과 제목을 입력하면 알아서 찾도록 만들어보자

import os

import ffmpeg
import yt_dlp


def search_and_download(song_name, artist, output_folder="downloads"):
    """Search for a song on YouTube, download it, and convert to MP3."""

    # Ensure output directory exists
    os.makedirs(output_folder, exist_ok=True)

    # Construct search query
    query = f"{artist} {song_name}"
    print(f"Searching for: {query}")

    # Use yt-dlp to search YouTube
    ydl_opts = {
        "quiet": True,
        "default_search": "ytsearch1",  # Search for one result
        "format": "bestaudio/best",  # Get the best audio format
        "noplaylist": True,
        "extract_flat": False,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(query, download=False)  # Get search results
        if "entries" in info and len(info["entries"]) > 0:
            video_url = info["entries"][0]["url"]  # Get first video URL
        else:
            print("No results found!")
            return

    print(f"Found: {video_url}")

    # Download audio
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": os.path.join(output_folder, f"{artist} - {song_name}.%(ext)s"),
        "noplaylist": True,
        "quiet": True,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([video_url])

    # Convert to MP3
    downloaded_file = os.path.join(output_folder, f"{artist} - {song_name}.webm")
    mp3_file = os.path.join(output_folder, f"{artist} - {song_name}.mp3")

    print(f"Converting {downloaded_file} to MP3...")
    ffmpeg.input(downloaded_file).output(mp3_file, format="mp3", loglevel="quiet").run(
        overwrite_output=True
    )

    # Remove original file
    os.remove(downloaded_file)

    print(f"Download complete! Saved as: {mp3_file}")
    return mp3_file


if __name__ == "__main__":
    artist = input("Enter artist name: ")
    song_name = input("Enter song title: ")
    search_and_download(song_name, artist)

이렇게 유튜브 링크를 찾을 수 있도록 수정했다. 이제 official audio 를 추가적으로 할 수 있도록 query 문을 수정해보자

 

그런데 코드를 작성하다가 의문점이 발견되었다. 이거 그냥 조회수가 높은 거로 하면 official audio 가 안될 것 같다.

그러니 채널명과 제목을 보고 사용자가 선택할 수 있도록 코드를 수정해본다.

 

import os

import ffmpeg
import yt_dlp


def download_youtube_link(url, output_folder="downloads"):
    """Downloads a YouTube video as an MP3 file using yt-dlp."""

    # Ensure output directory exists
    os.makedirs(output_folder, exist_ok=True)

    # yt-dlp 옵션 설정 (최고 음질 다운로드)
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": os.path.join(output_folder, "%(title)s.%(ext)s"),
        "noplaylist": True,
        "quiet": True,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info_dict = ydl.extract_info(url, download=True)
        downloaded_file = ydl.prepare_filename(info_dict)  # 파일명 가져오기

    # Convert to MP3
    base, ext = os.path.splitext(downloaded_file)
    mp3_file = f"{base}.mp3"

    print(f"Converting {downloaded_file} to MP3...")
    ffmpeg.input(downloaded_file).output(mp3_file, format="mp3", loglevel="quiet").run(
        overwrite_output=True
    )

    # 원본 파일 삭제
    os.remove(downloaded_file)

    print(f"Download complete! Saved as: {mp3_file}")
    return mp3_file


def search_and_download(song_name, artist, output_folder="downloads"):
    """Search for a song on YouTube, download it, and convert to MP3."""

    # Ensure output directory exists
    os.makedirs(output_folder, exist_ok=True)

    # Construct search query
    query = f"{artist} {song_name} official audio"
    print(f"Searching for: {query}")

    # Use yt-dlp to search YouTube
    ydl_opts = {
        "quiet": True,
        "default_search": "ytsearch5",  # Search for five result
        "format": "bestaudio/best",  # Get the best audio format
        "noplaylist": True,
        "extract_flat": False,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(query, download=False)  # Get search results
        if "entries" in info and len(info["entries"]) > 0:
            video_url = info["entries"][0]["url"]  # Get first video URL
        else:
            print("No results found!")
            return

    print(f"Found: {video_url}")

    # Download audio
    ydl_opts = {
        "format": "bestaudio/best",
        "outtmpl": os.path.join(output_folder, f"{artist} - {song_name}.%(ext)s"),
        "noplaylist": True,
        "quiet": True,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([video_url])

    # Convert to MP3
    downloaded_file = os.path.join(output_folder, f"{artist} - {song_name}.webm")
    mp3_file = os.path.join(output_folder, f"{artist} - {song_name}.mp3")

    print(f"Converting {downloaded_file} to MP3...")
    ffmpeg.input(downloaded_file).output(mp3_file, format="mp3", loglevel="quiet").run(
        overwrite_output=True
    )

    # Remove original file
    os.remove(downloaded_file)

    print(f"Download complete! Saved as: {mp3_file}")
    return mp3_file


if __name__ == "__main__":
    print(
        "Welcome to the YouTube MP3 Downloader!\nif you want to download with link, please enter the number 1"
    )
    print(
        "if you want to download with artist and song name, please enter the number 2"
    )
    choice = input("Enter your choice: ")
    if choice == "1":
        link = input("Enter the link: ")
        download_youtube_link(link)
    elif choice == "2":
        artist = input("Enter artist name: ")
        song_name = input("Enter song title: ")
        search_and_download(song_name, artist)

 

저장이 잘 되는 것은 확인했는데 조금 이것저것 더 손봐야하긴 할 것 같다.