[python] 유튜브 다운로더
유튜브 다운로더 만들기
실행파일 http://naver.me/5hEuvUHI
# _*_ coding: utf-8 _*_
from tkinter import *
import tkinter.messagebox
from tkinter import ttk
from threading import *
from pytube import YouTube
from moviepy.video.io.VideoFileClip import VideoFileClip
import os, sys, ctypes, subprocess
import pygame
window_size_width = 450
window_size_height = 310
save_folder = "youtube"
pause_flag = 0 # pause or unpause flag
music = ""
n = 0 # listbox - music list index
pygame.init()
pygame.mixer.init()
MUSIC_END = pygame.USEREVENT+1
pygame.mixer.music.set_endevent(MUSIC_END)
def resource_path(relative_path) :
try :
base_path = sys._MEIPASS
except Exception :
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def check_event() :
for event in pygame.event.get() :
if event.type == MUSIC_END:
print("종료")
next()
root.after(100, check_event)
def prev() :
global n, music
if n > 0 :
n = n - 1
print("--", n)
music = f_list.get(n)
f_list.selection_clear(0, END)
f_list.selection_set(n)
f_list.activate(n)
f_list.see(n)
play()
else :
pass
def next() :
global n, music
if n < f_list.size() - 1 :
n = n + 1
print("--", n)
music = f_list.get(n)
f_list.selection_clear(0, END)
f_list.selection_set(n)
f_list.activate(n)
f_list.see(n)
play()
else :
pass
def pause() :
global pause_flag
if pause_flag == 0 :
pygame.mixer.music.pause()
btn_pause.config(text="UNPAUSE", foreground="red")
pause_flag = 1
btn_prev['state'] = 'disable'
btn_next['state'] = 'disable'
else :
pygame.mixer.music.unpause()
btn_pause.config(text="PAUSE", foreground="black")
pause_flag = 0
btn_prev['state'] = 'active'
btn_next['state'] = 'active'
def music_select(event) :
global music, n, play
selection = f_list.curselection()
n = selection[0]
print(n)
music = f_list.get(n)
print(music)
#stop()
btn_play['state'] = "active"
btn_prev['state'] = 'disable'
btn_next['state'] = 'disable'
play()
def play() :
global music
path= f"./youtube/{music}"
print(path)
pygame.mixer.music.load(path)
pygame.mixer.music.play()
btn_play.config(foreground="gray")
btn_play["state"] = "disable"
btn_stop.config(foreground="black")
btn_stop["state"] = "active"
btn_pause.config(foreground="black")
btn_pause["state"] = "active"
btn_prev.config(foreground="black")
btn_prev["state"] = "active"
btn_next.config(foreground="black")
btn_next["state"] = "active"
def stop() :
global n
pygame.mixer.music.stop()
n=f_list.size()-1
f_list.selection_clear(0, END)
f_list.selection_set(n)
f_list.activate(n)
f_list.see(n)
btn_stop.config(foreground="black")
btn_stop["state"] = "disable"
btn_play.config(foreground="black")
btn_play["state"] = "disable"
btn_pause.config(foreground="gray", text="PAUSE")
btn_pause["state"] = "disable"
btn_prev['state'] = 'disable'
btn_next['state'] = 'disable'
def file_list() :
if not os.path.exists(save_folder) :
os.mkdir(save_folder)
else :
pass
f_list.delete(0,END)
file_lst = os.listdir(save_folder)
index = 0
f_list.activate(index)
f_list.select_set(index)
f_list.select_anchor(index)
for file in file_lst :
if file.endswith(".mp3") :
f_list.insert(index, str(file))
index += 1
def threading() :
btn_download_thread = Thread(target=youtubu_download)
btn_download_thread.start()
def progress_complete(self, file_path) :
global file_list
#url_entry.delete(0,END)
if (radio_value.get() == "mp3"):
try :
btn_download.config(text="변환중..")
#print(file_path)
mp4 = VideoFileClip(file_path)
mp4.audio.write_audiofile(file_path[:-3]+"mp3")
mp4.close()
os.remove(file_path)
btn_download.config(text="다운로드")
except Exception as e:
tkinter.messagebox.showinfo("error", e)
file_list()
btn_download['state'] = "active"
def progress_callback(stream, chunk, bytes_remaining) :
value = ((stream.filesize - bytes_remaining) / stream.filesize) * 100
value = round(value, 2)
progress_current_value.set(value)
prs_label.set(str(value) + "%")
progress_bar.update()
def youtubu_download() :
global file
url = url_entry.get()
yt = YouTube(url, on_progress_callback=progress_callback, on_complete_callback=progress_complete)
btn_download['state'] = "disable"
yt.streams.get_highest_resolution().download(save_folder)
def url_entry_clear() :
url_entry.delete(0, END)
def brower_open_button() :
path = os.path.realpath("youtube")
os.startfile(path)
# start
#################################################################################################################
root = Tk() # 최상위 레벨의 윈도우(window) 생성
root.iconphoto(False, PhotoImage(file=resource_path('icon\download.png'))) # Fase - 특정 창에만 적용
root.title("YouTube Downloader by kig2929kig") # 윈도우 제목 표시줄
root.geometry(str(window_size_width) + "x" + str(window_size_height)) # 너비 x 높이 + x좌표 + y좌표
root.resizable(False, False) # 윈도우 크기 조절 - True(가능), False(불가능)
#root.config(background='white')
url_Frame = LabelFrame(root, text="주소(URL)")
url_Frame.pack(padx=5, pady=5, fill="x", expand="yes")
progress_select_frame = Frame(root)
progress_select_frame.pack(padx=5, pady=5, fill="x", expand="yes")
progress_frame = LabelFrame(progress_select_frame, text="진행률")
progress_frame.pack(padx=5, pady=5, fill="x", expand="yes", side="left")
select_file_frame = LabelFrame(progress_select_frame, text="파일 선택")
select_file_frame.pack(padx=5, pady=5, fill="y", side="left")
folder_list_frame = LabelFrame(root, text="mp3 목록")
folder_list_frame.pack(padx=5, pady=5, fill="both", expand="yes")
# url_Frame
#################################################################################################################
url_entry = Entry(url_Frame)
url_entry.pack(padx=2, pady=10, fill="both", expand="yes", side="left")
btn_clear_icon = PhotoImage(file =resource_path(r"icon\close.png"))
btn_clear_icon = btn_clear_icon.subsample(40,40)
btn_url_clear = Button(url_Frame , text="x", image=btn_clear_icon, command=url_entry_clear)
#btn_url_clear = Button(url_Frame , text="x", command=url_entry_clear)
btn_url_clear.pack(padx=2, side="left")
btn_folder_icon = PhotoImage(file = resource_path(r"icon\folder.png"))
btn_folder_icon = btn_folder_icon.subsample(2, 2)
btn_url = Button(url_Frame , text="...", image=btn_folder_icon, command=brower_open_button)
#btn_url = Button(url_Frame , text="...", command=brower_open_button)
btn_url.pack(padx=5, side="left")
#################################################################################################################
# progress_frame
#################################################################################################################
progress_current_value = DoubleVar()
prs_label = StringVar()
progress_bar = ttk.Progressbar(progress_frame, maximum=100, variable=progress_current_value)
progress_bar.pack(padx=1, pady=10, fill="both", expand="yes", side="left")
progress_label = Label(progress_frame, textvariable=prs_label)
progress_label.pack(padx=2, side="left")
btn_download = Button(progress_frame, text="다운로드", command=threading)
btn_download.pack(padx=2, side="left")
#################################################################################################################
# select_file_frame - radio button
#################################################################################################################
radio_value = StringVar()
radio_value.set("mp3")
mp3_radio_btn = ttk.Radiobutton(select_file_frame, text="mp3", variable=radio_value)
mp4_radio_btn = ttk.Radiobutton(select_file_frame, text="mp4", variable=radio_value)
mp3_radio_btn.config(value="mp3")
mp4_radio_btn.config(value="mp4")
mp3_radio_btn.pack(side="left")
mp4_radio_btn.pack(side="left")
#################################################################################################################
#folder_list_frame
f_list = Listbox(folder_list_frame, activestyle="none")
f_list.pack(fill="both", side="left", expand="yes")
f_list_scrollbar = Scrollbar(folder_list_frame, orient=VERTICAL)
f_list_scrollbar.pack(side="right", fill="y")
f_list.config(yscrollcommand=f_list_scrollbar.set)
f_list_scrollbar.config(command=f_list.yview)
file_list()
f_list.bind("<<ListboxSelect>>", music_select)
btn_play = Button(folder_list_frame, text="PLAY", command=play)
btn_play.pack(fill="x")
btn_stop = Button(folder_list_frame, text="STOP", command=stop, foreground="gray")
btn_stop.pack(fill="x")
btn_pause = Button(folder_list_frame, text="PAUSE", command=pause, foreground="gray")
btn_pause.pack(fill="x")
btn_prev = Button(folder_list_frame, text="Prev", command=prev, foreground="gray")
btn_prev.pack(fill="x")
btn_next = Button(folder_list_frame, text="Next", command=next, foreground="gray")
btn_next.pack(fill="x")
btn_play['state'] = 'disable'
btn_pause['state'] = 'disable'
btn_stop['state'] = 'disable'
check_event()
console_hwnd = ctypes.windll.kernel32.GetConsoleWindow ()
ctypes.windll.user32.ShowWindow (console_hwnd, subprocess.SW_HIDE)
# end
root.mainloop() # 윈도우(window) 종료될 때까지 실행
실행파일(.exe)로 변환
pyinstaller -F 소스코드.py
moviepy 이슈
https://github.com/Zulko/moviepy/issues/591
댓글남기기