Devlog #3
Last time SubBake could mux subtitles with colors intact, but only through python -c one-liners. This time it got a face. It also got that face redesigned, because the first one looked like it was generated by an AI. More on that later.
The shell
The GUI is PySide6: a drag-and-drop area, a queue table, options row, a progress bar, and a collapsible log panel. Dropping a folder scans it recursively and pairs videos with same-named subtitles. The pairing is just (parent folder, lowercase stem) as a dictionary key, which quietly handles nested folders with identical filenames.
Everything is a thread problem
FFmpeg muxing is blocking, and a Qt window must never block. So every job is a QRunnable on a QThreadPool capped at 4. The catch: worker threads cannot touch widgets, at all, or the app crashes. So workers never see the UI — they emit signals (progress, file_progress, finished, log) and the GUI thread applies them.
One trap cost me a real headache: the pool auto-deletes finished runnables by default. My cancel button keeps references to running tasks so it can flag them — which becomes a dangling pointer the moment auto-delete kicks in. The fix is one line you only learn by crashing:
self.setAutoDelete(False)
Cancel itself is two different operations pretending to be one button. thread_pool.clear() drops queued tasks, but anything already running needs a cancel() flag that FFmpeg checks between progress updates. The progress bar’s total also has to be recalculated mid-flight, or cancelling leaves the bar lying about how much is left.
The tray icon that isn’t a file
I didn’t want to ship an icon asset for a tray icon nobody looks at, so the app paints one at runtime — a 32×32 QPixmap filled with one flat color. Zero files, zero resource management, and honestly nobody can tell.
Where SubBake stands
- A real window: drag-and-drop, queue table, live per-file progress, cancel, tray notification when done
- Four files mux in parallel without freezing the UI, and cancelling mid-run doesn’t corrupt anything
- Flat neutral theme, zero emoji, no gradients
- Still English-only, still launched from a terminal
Next up
Two things remain before this is a product: a language toggle (every string already funnels through one translation table, so it’s a refactor, not a rewrite), and PyInstaller packaging so normal humans can double-click it. Then the web demo, which is a story of its own.
Comments 1
Wow you are dedicated. I am unable to to put in so many hours. what should I do
Sign in to join the conversation.