Feat: Migrate GUI to customtkinter and update README.md

This commit is contained in:
Ramforth
2025-11-02 22:01:43 +01:00
parent 3235ed5e6f
commit e3238d7091
4 changed files with 43 additions and 24 deletions

View File

@@ -23,6 +23,10 @@ Develop a user-friendly, standalone Python tool to convert video files into form
### Future Considerations ### Future Considerations
* **Twitch Integration Strategy:**
* **URL Support:** Extend the URL handling to explicitly support Twitch video, single clip, and clip collection URLs.
* **Single Video/Clip Downloads:** Leverage `yt-dlp`'s existing capabilities to download single Twitch videos and clips. This should work with the current implementation.
* **Clip Collection Downloads (Batch Processing):** For Twitch clip collection URLs, `yt-dlp` will download all clips in the collection. This will require implementing batch processing capabilities (which is already a future consideration) to handle multiple downloaded files. The application will need to iterate through each downloaded clip and convert it individually.
* **Batch Processing:** Allow conversion of multiple files or URLs in a single run. * **Batch Processing:** Allow conversion of multiple files or URLs in a single run.
* **Configuration File:** Implement a configuration file (e.g., YAML, JSON) for persistent settings. * **Configuration File:** Implement a configuration file (e.g., YAML, JSON) for persistent settings.
* **Progress Bar:** Integrate a progress bar for both download and conversion processes. * **Progress Bar:** Integrate a progress bar for both download and conversion processes.
@@ -33,4 +37,9 @@ Develop a user-friendly, standalone Python tool to convert video files into form
### Known Issues / Limitations ### Known Issues / Limitations
* DaVinci Resolve Free on Linux has limitations with certain audio codecs (e.g., AAC) and 4K output/encoding (requires Studio version). * DaVinci Resolve Free on Linux has limitations with certain audio codecs (e.g., AAC) and 4K output/encoding (requires Studio version).
* `ffmpeg-full` AUR package is required for `dnxhd` support on Arch-based systems. * `ffmpeg-full` AUR package is required for `dnxhd` support on Arch-based systems.
### Large scale implementations
Since one of the limitations of this project is the requirement of ffmpeg-full for encoding videos for Davinci Resolve use we should investigate the proposition of implementing the necessary ffmpeg-full into the project release file.
I do not know, currently if this is viable or even possible. But I think that a fully precompiled program with built in encoders and tools would be more attractive to most users.
We should also see if there are other tools that would be considered natural for this project.

View File

@@ -19,6 +19,12 @@ For a detailed breakdown of the project's goals, technical specifications, and d
For instructions on how to use the application, please refer to the [HOW-TO.md](HOW-TO.md) file. For instructions on how to use the application, please refer to the [HOW-TO.md](HOW-TO.md) file.
## GUI
The application's graphical user interface has been updated to use `customtkinter` as of November 2, 2025. This provides a modern and customizable look and feel.
<!-- Screenshot of the GUI will be placed here -->
## Setup Notes for Arch Linux / CachyOS ## Setup Notes for Arch Linux / CachyOS
When installing `ffmpeg-full` (required for DNxHR/HD codec support), users might encounter a dependency conflict with `obs-studio-browser`. `obs-studio-browser` typically requires `ffmpeg-obs`, which is incompatible with `ffmpeg-full`. When installing `ffmpeg-full` (required for DNxHR/HD codec support), users might encounter a dependency conflict with `obs-studio-browser`. `obs-studio-browser` typically requires `ffmpeg-obs`, which is incompatible with `ffmpeg-full`.

47
gui.py
View File

@@ -1,6 +1,6 @@
import tkinter as tk import customtkinter
from tkinter import filedialog, messagebox, ttk from tkinter import filedialog, messagebox # Keep these for standard dialogs
import os import os
import sys import sys
import threading import threading
@@ -15,58 +15,61 @@ class VideoConverterGUI:
self.master = master self.master = master
master.title("Video Converter") master.title("Video Converter")
self.label = tk.Label(master, text="Select video file or enter URL:") customtkinter.set_appearance_mode("System") # Modes: "System" (default), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (default), "green", "dark-blue")
self.label = customtkinter.CTkLabel(master, text="Select video file or enter URL:")
self.label.pack() self.label.pack()
self.filepath_label = tk.Label(master, text="") self.filepath_label = customtkinter.CTkLabel(master, text="")
self.filepath_label.pack() self.filepath_label.pack()
self.browse_button = tk.Button(master, text="Browse", command=self.browse_file) self.browse_button = customtkinter.CTkButton(master, text="Browse", command=self.browse_file)
self.browse_button.pack() self.browse_button.pack()
self.url_label = tk.Label(master, text="URL:") self.url_label = customtkinter.CTkLabel(master, text="URL:")
self.url_label.pack() self.url_label.pack()
self.url_entry = tk.Entry(master, width=50) self.url_entry = customtkinter.CTkEntry(master, width=50)
self.url_entry.pack() self.url_entry.pack()
self.quality_label = tk.Label(master, text="Quality:") self.quality_label = customtkinter.CTkLabel(master, text="Quality:")
self.quality_label.pack() self.quality_label.pack()
self.quality_var = tk.StringVar(master) self.quality_var = customtkinter.StringVar(master)
self.quality_var.set("medium") # default value self.quality_var.set("medium") # default value
self.quality_menu = tk.OptionMenu(master, self.quality_var, "low", "medium", "high", "archive") self.quality_menu = customtkinter.CTkOptionMenu(master, variable=self.quality_var, values=["low", "medium", "high", "archive"])
self.quality_menu.pack() self.quality_menu.pack()
self.cookies_label = tk.Label(master, text="Cookies from Browser:") self.cookies_label = customtkinter.CTkLabel(master, text="Cookies from Browser:")
self.cookies_label.pack() self.cookies_label.pack()
self.cookies_var = tk.StringVar(master) self.cookies_var = customtkinter.StringVar(master)
self.cookies_var.set("none") # default value self.cookies_var.set("none") # default value
self.cookies_menu = tk.OptionMenu(master, self.cookies_var, "none", "brave", "chrome", "chromium", "edge", "firefox", "opera", "safari", "vivaldi", "whale") self.cookies_menu = customtkinter.CTkOptionMenu(master, variable=self.cookies_var, values=["none", "brave", "chrome", "chromium", "edge", "firefox", "opera", "safari", "vivaldi", "whale"])
self.cookies_menu.pack() self.cookies_menu.pack()
self.output_dir_label = tk.Label(master, text="Output Directory:") self.output_dir_label = customtkinter.CTkLabel(master, text="Output Directory:")
self.output_dir_label.pack() self.output_dir_label.pack()
self.output_dir_button = tk.Button(master, text="Select Directory", command=self.select_output_dir) self.output_dir_button = customtkinter.CTkButton(master, text="Select Directory", command=self.select_output_dir)
self.output_dir_button.pack() self.output_dir_button.pack()
self.output_dir_path_label = tk.Label(master, text="") self.output_dir_path_label = customtkinter.CTkLabel(master, text="")
self.output_dir_path_label.pack() self.output_dir_path_label.pack()
self.convert_button = tk.Button(master, text="Convert", command=self.convert) self.convert_button = customtkinter.CTkButton(master, text="Convert", command=self.convert)
self.convert_button.pack() self.convert_button.pack()
self.cancel_button = tk.Button(master, text="Cancel", command=self.cancel_conversion, state=tk.DISABLED) self.cancel_button = customtkinter.CTkButton(master, text="Cancel", command=self.cancel_conversion, state=customtkinter.DISABLED)
self.cancel_button.pack() self.cancel_button.pack()
self.status_var = tk.StringVar() self.status_var = customtkinter.StringVar()
self.status_label = tk.Label(master, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W) self.status_label = customtkinter.CTkLabel(master, textvariable=self.status_var)
self.status_label.pack(side=tk.BOTTOM, fill=tk.X) self.status_label.pack(side=tk.BOTTOM, fill=tk.X)
self.progress = ttk.Progressbar(master, orient=tk.HORIZONTAL, length=100, mode='determinate') self.progress = customtkinter.CTkProgressBar(master, orientation="horizontal")
self.progress.pack(side=tk.BOTTOM, fill=tk.X) self.progress.pack(side=tk.BOTTOM, fill=tk.X)
def browse_file(self): def browse_file(self):
@@ -177,6 +180,6 @@ class VideoConverterGUI:
if __name__ == '__main__': if __name__ == '__main__':
root = tk.Tk() root = customtkinter.CTk()
gui = VideoConverterGUI(root) gui = VideoConverterGUI(root)
root.mainloop() root.mainloop()

View File

@@ -1 +1,2 @@
yt-dlp yt-dlp
customtkinter