Initial commit of video downloader app
This commit is contained in:
commit
51a0fdef26
62
download.py
Normal file
62
download.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def download(video_url, output_file_name, dest_dir='./', audio_only=False, progress_callback=None):
|
||||||
|
# Ensure the destination directory exists
|
||||||
|
if not os.path.exists(dest_dir):
|
||||||
|
os.makedirs(dest_dir)
|
||||||
|
|
||||||
|
# Prepare the command to predict filename extension
|
||||||
|
if audio_only:
|
||||||
|
predict_command = ['yt-dlp', '--newline', '-x', '--audio-format', 'mp3', '--get-filename', '-o', f'{output_file_name}.%(ext)s', video_url]
|
||||||
|
else:
|
||||||
|
predict_command = ['yt-dlp', '--newline', '--get-filename', '-o', f'{output_file_name}.%(ext)s', video_url]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Using yt-dlp with --get-filename to predict the output filename
|
||||||
|
result = subprocess.check_output(predict_command)
|
||||||
|
file_extension = os.path.splitext(result.decode('utf-8').strip())[1]
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Unexpected error when getting filename: {e}')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Prepare the command to download the media
|
||||||
|
if audio_only:
|
||||||
|
download_command = [
|
||||||
|
'yt-dlp',
|
||||||
|
'-x', '--audio-format', 'mp3',
|
||||||
|
'-o', f'{dest_dir}/{output_file_name}{file_extension}',
|
||||||
|
video_url
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
download_command = [
|
||||||
|
'yt-dlp',
|
||||||
|
'-o', f'{dest_dir}/{output_file_name}{file_extension}',
|
||||||
|
video_url
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Execute the download command and capture stdout in real-time
|
||||||
|
process = subprocess.Popen(download_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
|
||||||
|
while True:
|
||||||
|
line = process.stdout.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
if '[download]' in line:
|
||||||
|
# Parse the progress from the output
|
||||||
|
match = re.search(r'\[download\]\s+(\d+\.\d+|\d+)%', line)
|
||||||
|
if match:
|
||||||
|
percentage = int(float(match.group(1)))
|
||||||
|
if progress_callback:
|
||||||
|
progress_callback(percentage) # Call the callback with the parsed progress value
|
||||||
|
process.communicate() # Wait for the process to finish if it hasn't yet
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print('Error occurred while downloading the video/audio.')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Unexpected error: {e}')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
def update_progress_bar(percentage):
|
||||||
|
print(percentage)
|
||||||
|
download('https://www.youtube.com/watch?v=ON7QQtF-RNA', 'Khonsu - A Jhator Ascension', progress_callback=update_progress_bar)
|
66
downloader.py
Normal file
66
downloader.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, filedialog, messagebox
|
||||||
|
from download import download
|
||||||
|
|
||||||
|
def update_progress_bar(percentage):
|
||||||
|
progress_var.set(percentage)
|
||||||
|
|
||||||
|
def start_download():
|
||||||
|
url = url_entry.get()
|
||||||
|
filename = filename_entry.get()
|
||||||
|
dest_dir = directory_var.get()
|
||||||
|
audio_only = audio_only_var.get()
|
||||||
|
|
||||||
|
if not url or not filename or not dest_dir:
|
||||||
|
messagebox.showerror("Error", "Please fill in all required fields!")
|
||||||
|
return
|
||||||
|
|
||||||
|
download(url, filename, dest_dir=dest_dir, audio_only=audio_only, progress_callback=update_progress_bar)
|
||||||
|
|
||||||
|
def select_directory():
|
||||||
|
directory = filedialog.askdirectory()
|
||||||
|
directory_var.set(directory)
|
||||||
|
|
||||||
|
# GUI Setup
|
||||||
|
app = tk.Tk()
|
||||||
|
app.title("yt-dlp Downloader")
|
||||||
|
|
||||||
|
frame = ttk.Frame(app, padding="10")
|
||||||
|
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||||
|
|
||||||
|
# URL input
|
||||||
|
url_label = ttk.Label(frame, text="Video URL:")
|
||||||
|
url_label.grid(row=0, column=0, sticky=tk.W, pady=5)
|
||||||
|
url_entry = ttk.Entry(frame, width=40)
|
||||||
|
url_entry.grid(row=0, column=1, pady=5)
|
||||||
|
|
||||||
|
# Filename input
|
||||||
|
filename_label = ttk.Label(frame, text="Filename (without extension):")
|
||||||
|
filename_label.grid(row=1, column=0, sticky=tk.W, pady=5)
|
||||||
|
filename_entry = ttk.Entry(frame, width=40)
|
||||||
|
filename_entry.grid(row=1, column=1, pady=5)
|
||||||
|
|
||||||
|
# Directory chooser
|
||||||
|
directory_var = tk.StringVar()
|
||||||
|
directory_label = ttk.Label(frame, text="Destination Directory:")
|
||||||
|
directory_label.grid(row=2, column=0, sticky=tk.W, pady=5)
|
||||||
|
directory_entry = ttk.Entry(frame, width=30, textvariable=directory_var)
|
||||||
|
directory_entry.grid(row=2, column=1, pady=5, sticky=tk.W)
|
||||||
|
directory_btn = ttk.Button(frame, text="Browse", command=select_directory)
|
||||||
|
directory_btn.grid(row=2, column=2, pady=5, sticky=tk.W)
|
||||||
|
|
||||||
|
# Audio only checkbox
|
||||||
|
audio_only_var = tk.BooleanVar()
|
||||||
|
audio_only_checkbox = ttk.Checkbutton(frame, text="Audio Only", variable=audio_only_var)
|
||||||
|
audio_only_checkbox.grid(row=3, column=1, sticky=tk.W, pady=5)
|
||||||
|
|
||||||
|
# Download button
|
||||||
|
download_btn = ttk.Button(frame, text="Download", command=start_download)
|
||||||
|
download_btn.grid(row=4, column=1, pady=10)
|
||||||
|
|
||||||
|
# Progress bar
|
||||||
|
progress_var = tk.DoubleVar()
|
||||||
|
progress_bar = ttk.Progressbar(frame, orient="horizontal", length=300, variable=progress_var, maximum=100)
|
||||||
|
progress_bar.grid(row=5, column=0, columnspan=3, pady=5)
|
||||||
|
|
||||||
|
app.mainloop()
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
tkinter
|
Loading…
Reference in New Issue
Block a user