[유틸] 유튜브 다운로드 프로그램 만들기 공유 > 컴퓨터

컴퓨터

[유틸] 유튜브 다운로드 프로그램 만들기 공유 정보

[유틸] 유튜브 다운로드 프로그램 만들기 공유

본문

유튜브 다운로드 프로그램 만드는게 유행인듯 싶어서 관련자료 공유하고 갑니다.

 

ffmpeg-release-essentials.zip 파일을 다운로드 하세요..

바로링크  https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip

bin/ffmpeg.exe를 같은 폴더 복사

 

import tkinter as tk

from tkinter import ttk, filedialog, messagebox

import threading

import yt_dlp

import os

class YouTubeDownloader:

def __init__(self, root):

self.root = root

self.root.title("YouTube Downloader (카이루 v1.0)")

self.root.geometry("700x680")

self.root.resizable(False, False)

style = ttk.Style()

style.theme_use("clam") # clam, alt, default 등 선택 가능

style.configure("TLabel", font=("맑은 고딕", 11))

style.configure("TButton", font=("맑은 고딕", 11), padding=6)

style.configure("TEntry", padding=4)

# 제목

title = ttk.Label(root, text=" 카이루 유튜브 다운로드 2025 ", font=("맑은 고딕", 18, "bold"), foreground="#2c3e50")

title.pack(pady=15)

# URL 입력 프레임

url_frame = ttk.LabelFrame(root, text=" YouTube URL 입력 (최대 10개) ", padding=10)

url_frame.pack(padx=20, pady=10, fill="x")

self.url_entries = []

for i in range(10):

row_frame = ttk.Frame(url_frame)

row_frame.pack(fill="x", pady=2)

num_label = ttk.Label(row_frame, text=f"{i+1:02d}.", width=3, anchor="center")

num_label.pack(side="left")

entry = ttk.Entry(row_frame, width=80)

entry.pack(side="left", padx=5)

self.url_entries.append(entry)

# 저장 경로 선택

path_frame = ttk.Frame(root)

path_frame.pack(pady=10, fill="x")

ttk.Button(path_frame, text="? 저장 경로 선택", command=self.choose_directory).pack(side="left", padx=10)

self.save_dir = tk.StringVar(value=os.getcwd())

ttk.Label(path_frame, textvariable=self.save_dir, foreground="#2980b9").pack(side="left")

# 진행 상태 표시

progress_frame = ttk.Frame(root)

progress_frame.pack(pady=20)

self.progress_label = ttk.Label(progress_frame, text="대기 중...")

self.progress_label.pack()

self.progress_bar = ttk.Progressbar(progress_frame, length=500, mode="determinate")

self.progress_bar.pack(pady=10)

# 버튼 프레임

button_frame = ttk.Frame(root)

button_frame.pack(pady=20)

ttk.Button(button_frame, text="? MP3 다운로드", command=lambda: self.start_download("mp3")).grid(row=0, column=0, padx=15)

ttk.Button(button_frame, text="? 영상(720p)", command=lambda: self.start_download("video_720")).grid(row=0, column=1, padx=15)

ttk.Button(button_frame, text="? 영상(고화질)", command=lambda: self.start_download("video_hd")).grid(row=0, column=2, padx=15)

def choose_directory(self):

directory = filedialog.askdirectory()

if directory:

self.save_dir.set(directory)

def start_download(self, mode):

urls = [e.get().strip() for e in self.url_entries if e.get().strip()]

if not urls:

messagebox.showerror("에러", "최소 1개 이상의 URL을 입력하세요!")

return

self.progress_bar["value"] = 0

self.progress_bar["maximum"] = len(urls)

self.progress_label.config(text="다운로드 준비 중...")

threading.Thread(target=self._download_worker, args=(mode, urls, self.save_dir.get()), daemon=True).start()

def _download_worker(self, mode, urls, save_dir):

def progress_hook(d, idx, total):

if d['status'] == 'downloading':

percent = d.get('_percent_str', '0%').strip()

self.root.after(0, lambda: self.progress_label.config(

text=f"[{idx}/{total}] 다운로드 중... {percent}"))

elif d['status'] == 'finished':

self.root.after(0, lambda: self.progress_label.config(

text=f"[{idx}/{total}] 변환 중..."))

try:

total = len(urls)

for idx, url in enumerate(urls, start=1):

if mode == "mp3":

ydl_opts = {

"format": "bestaudio/best",

"outtmpl": os.path.join(save_dir, "%(title)s"),

"postprocessors": [{

"key": "FFmpegExtractAudio",

"preferredcodec": "mp3",

"preferredquality": "0",

}],

"progress_hooks": [lambda d, i=idx: progress_hook(d, i, total)],

"noplaylist": True,

}

elif mode == "video_720":

ydl_opts = {

"format": "bestvideo[height<=720]+bestaudio/best[height<=720]",

"merge_output_format": "mp4",

"outtmpl": os.path.join(save_dir, "%(title)s_[720p].mp4"),

"progress_hooks": [lambda d, i=idx: progress_hook(d, i, total)],

"noplaylist": True,

}

elif mode == "video_hd":

ydl_opts = {

"format": "bestvideo[height>=1080]+bestaudio/best",

"merge_output_format": "mp4",

"outtmpl": os.path.join(save_dir, "%(title)s_[1080p+].mp4"),

"progress_hooks": [lambda d, i=idx: progress_hook(d, i, total)],

"noplaylist": True,

}

with yt_dlp.YoutubeDL(ydl_opts) as ydl:

ydl.download([url])

self.root.after(0, lambda val=idx: self.progress_bar.config(value=val))

self.root.after(0, lambda: self.progress_label.config(text="✅ 전체 다운로드 완료"))

except Exception as e:

self.root.after(0, lambda: messagebox.showerror("다운로드 실패", str(e)))

if __name__ == "__main__":

root = tk.Tk()

app = YouTubeDownloader(root)

root.mainloop()

 

3731943363_1757462124.8957.png

 

 

공감
0
  • 복사

댓글 2개

© SIRSOFT
현재 페이지 제일 처음으로