본문 바로가기
공부용/연습장

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

by alpakaka 2025. 2. 13.

오늘은 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)

 

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

'공부용 > 연습장' 카테고리의 다른 글

[리트코드] 12일차  (0) 2025.02.16
리트코드 11일차  (0) 2025.02.14
[리트코드] 10일차  (0) 2025.02.12
[리트코드] 9일차 + python radon 사용해보기  (0) 2025.02.10
[리트코드] 3문제풀기  (0) 2025.02.06