Skip to content

Commit 91329c9

Browse files
committed
add youtube audio downloader tutorial
1 parent a48eed1 commit 91329c9

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
142142
- [How to Make a Currency Converter in Python](https://www.thepythoncode.com/article/make-a-currency-converter-in-python). ([code](web-scraping/currency-converter))
143143
- [How to Extract Google Trends Data in Python](https://www.thepythoncode.com/article/extract-google-trends-data-in-python). ([code](web-scraping/extract-google-trends-data))
144144
- [How to Make a YouTube Video Downloader in Python](https://www.thepythoncode.com/article/make-a-youtube-video-downloader-in-python). ([code](web-scraping/youtube-video-downloader))
145+
- [How to Build a YouTube Audio Downloader in Python](https://www.thepythoncode.com/article/build-a-youtube-mp3-downloader-tkinter-python). ([code](web-scraping/youtube-mp3-downloader))
145146

146147
- ### [Python Standard Library](https://www.thepythoncode.com/topic/python-standard-library)
147148
- [How to Transfer Files in the Network using Sockets in Python](https://www.thepythoncode.com/article/send-receive-files-using-sockets-python). ([code](general/transfer-files/))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Build a YouTube Audio Downloader in Python](https://www.thepythoncode.com/article/build-a-youtube-mp3-downloader-tkinter-python)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
from tkinter import *
2+
from tkinter import ttk
3+
from pytube import YouTube
4+
from tkinter.messagebox import showinfo, showerror, askokcancel
5+
import threading
6+
import os
7+
8+
9+
# the function for closing the application
10+
def close_window():
11+
# if askokcancel is True, close the window
12+
if askokcancel(title='Close Application', message='Do you want to close MP3 downloader?'):
13+
# this distroys the window
14+
window.destroy()
15+
16+
17+
# the function to download the mp3 audio
18+
def download_audio():
19+
# the try statement to excute the download the video code
20+
# getting video url from entry
21+
mp3_link = url_entry.get()
22+
# checking if the entry and combobox is empty
23+
if mp3_link == '':
24+
# display error message when url entry is empty
25+
showerror(title='Error', message='Please enter the MP3 URL')
26+
# else let's download the audio file
27+
else:
28+
# this try statement will run if the mp3 url is filled
29+
try:
30+
# this function will track the audio file download progress
31+
def on_progress(stream, chunk, bytes_remaining):
32+
# the total size of the audio
33+
total_size = stream.filesize
34+
# this function will get the size of the audio file
35+
def get_formatted_size(total_size, factor=1024, suffix='B'):
36+
# looping through the units
37+
for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]:
38+
if total_size < factor:
39+
return f"{total_size:.2f}{unit}{suffix}"
40+
total_size /= factor
41+
# returning the formatted audio file size
42+
return f"{total_size:.2f}Y{suffix}"
43+
44+
# getting the formatted audio file size calling the function
45+
formatted_size = get_formatted_size(total_size)
46+
# the size downloaded after the start
47+
bytes_downloaded = total_size - bytes_remaining
48+
# the percentage downloaded after the start
49+
percentage_completed = round(bytes_downloaded / total_size * 100)
50+
# updating the progress bar value
51+
progress_bar['value'] = percentage_completed
52+
# updating the empty label with the percentage value
53+
progress_label.config(text=str(percentage_completed) + '%, File size:' + formatted_size)
54+
# updating the main window of the app
55+
window.update()
56+
57+
# creating the YouTube object and passing the the on_progress function
58+
audio = YouTube(mp3_link, on_progress_callback=on_progress)
59+
# extracting and downloading the audio file
60+
output = audio.streams.get_audio_only().download()
61+
# this splits the audio file, the base and the extension
62+
base, ext = os.path.splitext(output)
63+
# this converts the audio file to mp3 file
64+
new_file = base + '.mp3'
65+
# this renames the mp3 file
66+
os.rename(output, new_file)
67+
# popup for dispalying the mp3 downlaoded success message
68+
showinfo(title='Download Complete', message='MP3 has been downloaded successfully.')
69+
# ressetting the progress bar and the progress label
70+
progress_label.config(text='')
71+
progress_bar['value'] = 0
72+
# the except will run when an expected error occurs during downloading
73+
except:
74+
showerror(title='Download Error', message='An error occurred while trying to ' \
75+
'download the MP3\nThe following could ' \
76+
'be the causes:\n->Invalid link\n->No internet connection\n'\
77+
'Make sure you have stable internet connection and the MP3 link is valid')
78+
# ressetting the progress bar and the progress label
79+
progress_label.config(text='')
80+
progress_bar['value'] = 0
81+
82+
83+
84+
# the function to run the download_audio function as a thread
85+
def downloadThread():
86+
t1 = threading.Thread(target=download_audio)
87+
t1.start()
88+
89+
90+
# creates the window using Tk() fucntion
91+
window = Tk()
92+
93+
# this will listen to the close window event
94+
window.protocol('WM_DELETE_WINDOW', close_window)
95+
96+
# creates title for the window
97+
window.title('MP3 Downloader')
98+
99+
# the icon for the application, this will replace the default tkinter icon
100+
window.iconbitmap(window, 'icon.ico')
101+
102+
# dimensions and position of the window
103+
window.geometry('500x400+430+180')
104+
# makes the window non-resizable
105+
window.resizable(height=FALSE, width=FALSE)
106+
107+
# creates the canvas for containing all the widgets
108+
canvas = Canvas(window, width=500, height=400)
109+
canvas.pack()
110+
111+
"""Styles for the widgets"""
112+
# style for the label
113+
label_style = ttk.Style()
114+
label_style.configure('TLabel', foreground='#000000', font=('OCR A Extended', 15))
115+
116+
# style for the entry
117+
entry_style = ttk.Style()
118+
entry_style.configure('TEntry', font=('Dotum', 15))
119+
120+
# style for the button
121+
button_style = ttk.Style()
122+
button_style.configure('TButton', foreground='#000000', font='DotumChe')
123+
124+
# loading the MP3 logo
125+
logo = PhotoImage(file='mp3_icon.png')
126+
# creates dimensions for the logo
127+
logo = logo.subsample(2, 2)
128+
# adding the logo to the canvas
129+
canvas.create_image(180, 80, image=logo)
130+
131+
# the Downloader label just next to the logo
132+
mp3_label = ttk.Label(window, text='Downloader', style='TLabel')
133+
canvas.create_window(340, 125, window=mp3_label)
134+
135+
# creating a ttk label
136+
url_label = ttk.Label(window, text='Enter MP3 URL:', style='TLabel')
137+
# creating a ttk entry
138+
url_entry = ttk.Entry(window, width=72, style='TEntry')
139+
140+
# adding the label to the canvas
141+
canvas.create_window(114, 200, window=url_label)
142+
# adding the entry to the canvas
143+
canvas.create_window(250, 230, window=url_entry)
144+
145+
# creating the empty label for displaying download progress
146+
progress_label = Label(window, text='')
147+
# adding the label to the canvas
148+
canvas.create_window(240, 280, window=progress_label)
149+
150+
# creating a progress bar to display progress
151+
progress_bar = ttk.Progressbar(window, orient=HORIZONTAL, length=450, mode='determinate')
152+
# adding the progress bar to the canvas
153+
canvas.create_window(250, 300, window=progress_bar)
154+
155+
# creating the button
156+
download_button = ttk.Button(window, text='Download MP3', style='TButton', command=downloadThread)
157+
# adding the button to the canvas
158+
canvas.create_window(240, 330, window=download_button)
159+
160+
# this runs the app infinitely
161+
window.mainloop()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytube

0 commit comments

Comments
 (0)