diff --git a/run.py b/run.py index fc07bbc..951e8f7 100644 --- a/run.py +++ b/run.py @@ -3,52 +3,36 @@ from tkinter import filedialog from tkinter import font from tkinter import ttk -import re -import os import sys from tkinter import messagebox from tubecut.commands import _download_video, _trim_video -# Get the directory of the current executable or script -if getattr(sys, 'frozen', False): # If running as PyInstaller bundled exe - current_dir = Path(sys.executable).parent # Path of the binaries +if getattr(sys, 'frozen', False): + current_dir = Path(sys.executable).parent else: - current_dir = Path(__file__).parent # For normal development + current_dir = Path(__file__).parent -# Path to the local ffmpeg and yt-dlp binaries in the 'bin' folder ffmpeg_path = current_dir / 'bin' / 'ffmpeg.exe' -ytdlp_path = current_dir / 'bin' / 'yt-dlp.exe' -print(ffmpeg_path) -# Ensure the binaries are executable (for UNIX-based systems) -os.chmod(ffmpeg_path, 0o755) -os.chmod(ytdlp_path, 0o755) - -# Create the main window root = tk.Tk() root.title("TubeCut") -# Get screen width and height screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() -# Set the window size proportional to the screen size (e.g., 30% width and 15% height) window_width = int(screen_width * 0.4) window_height = int(screen_height * 0.3) -# Set the geometry of the window using the calculated width and height root.geometry(f"{window_width}x{window_height}") -# Create a font for scaling and bold button text -label_font = font.Font(size=12) # Larger font for labels and entries -entry_font = font.Font(size=14) # Larger font for entry fields -button_font = font.Font(size=12) # Larger font and bold for buttons -bold_button_font = font.Font(size=12, weight="bold") # Larger font and bold for buttons +label_font = font.Font(size=12) +entry_font = font.Font(size=14) +button_font = font.Font(size=12) +bold_button_font = font.Font(size=12, weight="bold") -# Customize the style of the notebook tabs and buttons style = ttk.Style() -style.configure("TNotebook.Tab", font=("Arial", 12), background="#D3D3D3") # Darker tab background -style.map("TNotebook.Tab", background=[("selected", "#A9A9A9")]) # Even darker when selected +style.configure("TNotebook.Tab", font=("Arial", 12), background="#D3D3D3") +style.map("TNotebook.Tab", background=[("selected", "#A9A9A9")]) download_url = tk.StringVar() download_output_dir_path = tk.StringVar() @@ -104,31 +88,29 @@ def on_trim(): except Exception as e: messagebox.showerror("Error", f"Failed to trim video: {str(e)}") -# Function to handle directory selection (empty handler) def on_directory_select(): dir_path = filedialog.askdirectory() if dir_path: - dir_path_entry.delete(0, tk.END) # Clear current entry + dir_path_entry.delete(0, tk.END) dir_path_entry.insert(0, dir_path) print(f"Directory selected: {dir_path}") def on_cut_output_dir_select(): dir_path = filedialog.askdirectory() if dir_path: - cut_output_dir_entry.delete(0, tk.END) # Clear current entry + cut_output_dir_entry.delete(0, tk.END) cut_output_dir_entry.insert(0, dir_path) print(f"Directory selected: {dir_path}") -# Function to handle directory selection for cutting def on_cut_file_select(): file_path = filedialog.askopenfilename( title="Select a File", - filetypes=[("Video Files", "*.mp4 *.avi *.mkv *.mov *.flv *.wmv *.webm")] + filetypes=[("Video and Audio Files", "*.mp4 *.avi *.mkv *.mov *.flv *.wmv *.webm *.mp3 *.wav *.aac *.flac *.ogg *.m4a")] ) if file_path: - cut_file_path_entry.delete(0, tk.END) # Clear the entry field - cut_file_path_entry.insert(0, file_path) # Insert the selected file path - print(f"File selected: {file_path}") # Output the selected file path to console + cut_file_path_entry.delete(0, tk.END) + cut_file_path_entry.insert(0, file_path) + print(f"File selected: {file_path}") def on_cut_output_file_select(): file_path = filedialog.askopenfilename( @@ -136,48 +118,41 @@ def on_cut_output_file_select(): filetypes=[("Video Files", "*.mp4 *.avi *.mkv *.mov *.flv *.wmv *.webm")] ) if file_path: - cut_output_dir_entry.delete(0, tk.END) # Clear the entry field - cut_output_dir_entry.insert(0, file_path) # Insert the selected file path - print(f"File selected: {file_path}") # Output the selected file path to console + cut_output_dir_entry.delete(0, tk.END) + cut_output_dir_entry.insert(0, file_path) + print(f"File selected: {file_path}") -# Create a Notebook (for tabs) notebook = ttk.Notebook(root) notebook.pack(pady=10, padx=10, expand=True, fill="both") -# Create frames for the two tabs download_frame = tk.Frame(notebook, width=700, height=250) cut_frame = tk.Frame(notebook, width=700, height=250) -# Add the tabs to the notebook notebook.add(download_frame, text="YT Download") notebook.add(cut_frame, text="Cut") # --- Download Tab UI --- -# URL Entry Field for Download tab url_label = tk.Label(download_frame, text="Enter URL:", font=label_font) url_label.grid(row=0, column=0, padx=10, pady=10, sticky="e") url_entry = tk.Entry(download_frame, font=entry_font, textvariable=download_url) url_entry.grid(row=0, column=1, padx=10, pady=10, sticky="ew", columnspan=6) -# Create a dropdown (Combobox) for format selection in download_frame format_combobox = ttk.Combobox(download_frame, textvariable=download_format_var, values=formats, state="readonly", font=entry_font) -format_combobox.set("Select a format") # Set the default text -format_combobox.grid(row=3, column=4, padx=10, pady=10, sticky="ew") # Place in the grid of download_frame +format_combobox.set("Select a format") +format_combobox.grid(row=3, column=4, padx=10, pady=10, sticky="ew") url_button = tk.Button(download_frame, text="Download", command=on_download, font=bold_button_font) url_button.grid(row=3, column=2, padx=10, pady=10, sticky="ew") -# Directory Path Entry Field for Download tab dir_path_label = tk.Label(download_frame, text="Select output directory:", font=label_font) dir_path_label.grid(row=1, column=0, padx=10, pady=10, sticky="e") dir_path_entry = tk.Entry(download_frame, font=entry_font, textvariable=download_output_dir_path) dir_path_entry.grid(row=1, column=1, padx=10, pady=10, sticky="ew", columnspan=6) -# Directory Path Entry Field for Download tab filename_label = tk.Label(download_frame, text="Insert output file name:", font=label_font) filename_label.grid(row=2, column=0, padx=10, pady=10, sticky="e") @@ -189,7 +164,6 @@ def on_cut_output_file_select(): # --- Cut Tab UI --- -# File Selection for Cut tab cut_file_path_label = tk.Label(cut_frame, text="Select file to cut:", font=label_font) cut_file_path_label.grid(row=0, column=0, padx=10, pady=10, sticky="e") @@ -199,7 +173,6 @@ def on_cut_output_file_select(): cut_file_path_button = tk.Button(cut_frame, text="Browse", command=on_cut_file_select, font=button_font) cut_file_path_button.grid(row=0, column=6, padx=10, pady=10, sticky="ew") -# Labels and entries for start and end time in HH:MM:SS format start_time_label = tk.Label(cut_frame, text="Start Time (HH:MM:SS):", font=label_font) start_time_label.grid(row=3, column=0, padx=10, pady=10, sticky="e") @@ -218,14 +191,12 @@ def on_cut_output_file_select(): start_time_label = tk.Label(cut_frame, text="Empty for last frame", font=label_font) start_time_label.grid(row=4, column=3, padx=1, pady=1, sticky="e") -# Directory Path Entry Field for Download tab filename_cut_label = tk.Label(cut_frame, text="Insert output file name:", font=label_font) filename_cut_label.grid(row=1, column=0, padx=10, pady=10, sticky="e") filename_cut_entry = tk.Entry(cut_frame, font=entry_font, textvariable=cut_output_filename) filename_cut_entry.grid(row=1, column=1, padx=10, pady=10, sticky="ew", columnspan=5) -# Directory Path Entry Field for Download tab cut_output_dir_label = tk.Label(cut_frame, text="Select output directory:", font=label_font) cut_output_dir_label.grid(row=2, column=0, padx=10, pady=10, sticky="e") @@ -235,14 +206,11 @@ def on_cut_output_file_select(): cut_output_dir_button = tk.Button(cut_frame, text="Browse", command=on_cut_output_dir_select, font=button_font) cut_output_dir_button.grid(row=2, column=6, padx=10, pady=10, sticky="ew") -# Submit button for trimming video submit_button = tk.Button(cut_frame, text="Trim Video", font=bold_button_font, command=on_trim) submit_button.grid(row=5, column=1, padx=10, pady=20, sticky="ew") -# Create a dropdown (Combobox) for format selection in download_frame format_combobox_cut = ttk.Combobox(cut_frame, textvariable=cut_format_var, values=formats, state="readonly", font=entry_font) -format_combobox_cut.set("Select output file format") # Set the default text -format_combobox_cut.grid(row=5, column=4, padx=10, pady=10, sticky="ew") # Place in the grid of download_frame +format_combobox_cut.set("Select output file format") +format_combobox_cut.grid(row=5, column=4, padx=10, pady=10, sticky="ew") -# Start the Tkinter event loop root.mainloop() diff --git a/tubecut/commands.py b/tubecut/commands.py index 1bef33f..5928f8c 100644 --- a/tubecut/commands.py +++ b/tubecut/commands.py @@ -13,7 +13,7 @@ def _download_video(url, output_dir, filename, ffmpeg_path, format="mp4", audio_ 'preferredcodec': format, 'preferredquality': '192', }], - 'ffmpeg_location': str(ffmpeg_path), # Use local ffmpeg binary + 'ffmpeg_location': str(ffmpeg_path), } else: ydl_opts = { @@ -23,7 +23,7 @@ def _download_video(url, output_dir, filename, ffmpeg_path, format="mp4", audio_ 'key': 'FFmpegVideoConvertor', 'preferedformat': format, }], - 'ffmpeg_location': str(ffmpeg_path), # Use local ffmpeg binary + 'ffmpeg_location': str(ffmpeg_path), } with yt_dlp.YoutubeDL(ydl_opts) as ydl: @@ -34,16 +34,13 @@ def _trim_video(file_path, output_dir, start_time, end_time, output_filename, ou if (start_time == "") and (end_time == ""): raise ValueError('Start Time and End Time cannot be both empty.') - # Ensure the output directory exists output_dir = Path(output_dir) output_dir.mkdir(parents=True, exist_ok=True) - # Construct the full output file path output_file = output_dir / f'{output_filename}.{output_format}' command = [str(ffmpeg_path), '-i', str(file_path)] - # ffmpeg trimming with input arguments if start_time == '': command.extend(['-ss', '0']) else: @@ -54,70 +51,7 @@ def _trim_video(file_path, output_dir, start_time, end_time, output_filename, ou command.append(str(output_file)) try: - # Use the local ffmpeg binary subprocess.run(command, check=True) print(f"Trimmed video/audio saved to: {output_file}") except subprocess.CalledProcessError as e: print(f"Error trimming video: {e}") - - - - -# import subprocess -# import os -# from pathlib import Path -# import yt_dlp -# import ffmpeg - -# def _download_video(url, output_dir, filename, format="mp4", audio_only=False): -# # Adjust the format options based on whether it's video or audio -# if audio_only: -# # If audio_only is True, extract audio and save as MP3 (or another format) -# ydl_opts = { -# 'format': 'bestaudio/best', # Download best audio -# 'outtmpl': f'{output_dir}/{filename}.%(ext)s', # Use extension of the extracted audio -# 'postprocessors': [{ -# 'key': 'FFmpegExtractAudio', -# 'preferredcodec': format, # Convert to the desired audio format (e.g., 'mp3', 'm4a', 'opus') -# 'preferredquality': '192', # Audio quality (e.g., 192 kbps) -# }], -# } -# else: -# # If downloading video, select the best video and audio and merge into a single file -# ydl_opts = { -# 'format': f'bestvideo[ext={format}]+bestaudio[ext=m4a]/best[ext={format}]', # Download best video with chosen format -# 'outtmpl': f'{output_dir}/{filename}.%(ext)s', # Output filename -# 'postprocessors': [{ -# 'key': 'FFmpegVideoConvertor', -# 'preferedformat': format, # Convert to the desired video format if needed -# }], -# } - -# # Perform the download -# with yt_dlp.YoutubeDL(ydl_opts) as ydl: -# ydl.download([url]) -# print(f"Download complete: {filename}.{format}") - -# def _trim_video(file_path, output_dir, start_time, end_time, output_filename, output_format): -# if (start_time == "") and (end_time == ""): -# raise Exception('Start Time and End Time cannot be both empty.') - -# # Ensure the output directory exists -# if not os.path.exists(output_dir): -# os.makedirs(output_dir) - -# # Construct the full output file path and infer the output format -# output_file = os.path.join(output_dir, f'{output_filename}.{output_format}') - -# # Trim the input file based on start_time and end_time -# input_args = {} -# if start_time != "": -# input_args['ss'] = start_time -# if end_time != "": -# input_args['to'] = end_time - -# # ffmpeg trimming with input arguments and specifying output format -# ffmpeg.input(file_path, **input_args).output(output_file, format=output_format).run() - -# print(f"Trimmed video/audio saved to: {output_file}") -