Skip to content

Commit

Permalink
removed dependency on yt_dlp executable, added audio formats on cut f…
Browse files Browse the repository at this point in the history
…ile selection
  • Loading branch information
andrei-g99 committed Oct 19, 2024
1 parent a73634c commit 00fa69a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 122 deletions.
76 changes: 22 additions & 54 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -104,80 +88,71 @@ 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(
title="Select a File",
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")

Expand All @@ -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")

Expand All @@ -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")

Expand All @@ -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")

Expand All @@ -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()
70 changes: 2 additions & 68 deletions tubecut/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -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}")

0 comments on commit 00fa69a

Please sign in to comment.