Kolejny projekt z mojego portfolio pod
michal.ronim.com.pl, tym razem nie strona internetowa,
tylko desktopowa aplikacja: SubForge, narzędzie do wyszukiwania
i synchronizacji napisów do filmów. Kod jest publiczny na GitHubie.
Ten wpis jest uczciwy co do stanu projektu: SubForge jest w budowie,
ukończony w około 95%, nie jest to gotowy, zamknięty produkt.
Problem
Szukanie napisów do filmu rozproszone jest po kilku różnych serwisach, z których każdy ma inny interfejs i inną jakość wyników. Nawet gdy znajdzie się właściwy plik z napisami, rzadko pasuje on idealnie do konkretnej wersji wideo - offset czasowy jest przesunięty, albo liczba klatek na sekundę (FPS) pliku wideo różni się od tej, dla której napisy zostały przygotowane. Ręczne dopasowywanie tego w klasycznym odtwarzaczu zajmuje więcej czasu niż samo obejrzenie filmu.
Decyzje architektoniczne
Interfejs zbudowany jest w Tauri v2 z Reactem, ale cała logika - wyszukiwanie, dopasowanie, synchronizacja, sprawdzanie czytelności - siedzi w Pythonie, oddzielona od warstwy UI. Taki podział ma konkretną zaletę: interfejs da się w całości przebudować albo zastąpić czymś innym bez dotykania rdzenia, który robi rzeczywistą pracę.
Wyszukiwanie napisów obejmuje sześć różnych serwisów naraz. Kluczowa decyzja dotyczy jednak samego dopasowania: napisy są kojarzone z plikiem wideo po hashu pliku, nie po zgadywaniu tytułu z nazwy pliku. Nazwa pliku wideo bywa zmieniona, obcięta albo w innym języku niż tytuł oryginalny - hash pliku nie kłamie, więc dopasowanie po nim jest dokładniejsze niż dopasowanie po tekście.
Program sam próbuje wykryć rozjazd liczby klatek na sekundę między plikiem napisów a wideo i przeliczyć odpowiednią korektę automatycznie. Gdy automatyczne wykrycie się nie uda, wystarczy ręcznie wskazać dwa punkty odniesienia w podglądzie, zamiast żmudnie przesuwać cały plik klatka po klatce. Przed zapisaniem gotowego pliku aplikacja dodatkowo sprawdza czytelność napisów (np. czy linia nie znika z ekranu za szybko, żeby zdążyć ją przeczytać) i w razie potrzeby sama wydłuża czas wyświetlania.
Zgadywanie tytułu z nazwy pliku to najsłabsze możliwe dopasowanie - hash pliku jest jedynym identyfikatorem, który nie zależy od tego, jak ktoś akurat nazwał plik na dysku.
Efekt
Napisy znalezione i zsynchronizowane w jednym kliknięciu, zamiast ręcznego przeszukiwania kilku serwisów i liczenia offsetu na piechotę. Rdzeń logiki (część w Pythonie, nie interfejs) pokryty jest 530 testami - przy projekcie, którego głównym ryzykiem jest cichy błąd w liczeniu korekty czasowej (widoczny dopiero jako napisy przesunięte o ułamek sekundy, łatwy do przeoczenia), taki poziom pokrycia testami jest świadomą decyzją, nie przypadkiem. Sam projekt pozostaje w budowie, z ukończeniem szacowanym na około 95% - nie jest to jeszcze zamknięty rozdział.