Napisy na tekst: usunięcie kodów czasowych to ta łatwiejsza połowa
Każdy format napisów koduje to samo: krótkie odcinki mowy przypięte do kodów czasowych. Zamiana tego z powrotem w czytelną prozę wygląda na skrypt na pięć wierszy — skasować liczby, skasować strzałki, skleić resztę. Puść ten skrypt na prawdziwym pliku napisów, a dostaniesz coś prawie dobrego, co jest gorsze niż oczywiście złe, bo trzeba to przeczytać, żeby zauważyć.
Psują to dwie rzeczy. Napisy łamie się tak, żeby zmieściły się na ekranie, a nie tak, żeby kończyły zdanie, więc naiwne sklejanie daje prozę posiekaną co sześć słów. A napisy generowane automatycznie przewijają się, powtarzając tekst między kolejnymi liniami, więc konkatenacja zwraca każde zdanie dwa albo trzy razy. To narzędzie ogarnia jedno i drugie. Wgraj albo wklej plik powyżej, a wynik pojawi się natychmiast, w tej karcie przeglądarki.
Problem przewijających się duplikatów
To ten, na którym ludzie się przejeżdżają. Automatyczne napisy na YouTubie i w większości systemów na żywo nie emitują odrębnych bloków tekstu. Emitują ruchome okno, tak żeby widz widział, jak słowa się dokładają. W pliku wygląda to tak:
- Linia 1: kto rano wstaje
- Linia 2: kto rano wstaje temu pan
- Linia 3: temu pan bóg daje
Sklejone bezmyślnie dają „kto rano wstaje kto rano wstaje temu pan temu pan bóg daje” — dwanaście słów tam, gdzie padło siedem. Na godzinnym wykładzie to mniej więcej podwaja albo potraja długość i czyni transkrypcję bezużyteczną do czytania, przeszukiwania i streszczania.
Lekarstwem jest zachowanie wyłącznie tego, co każda linia dokłada. Dla każdej nowej linii narzędzie znajduje najdłuższy ciąg słów będący jednocześnie sufiksem dotychczasowego tekstu i prefiksem nowej linii, po czym go wyrzuca. Zastosowane do przykładu powyżej odzyskujesz „kto rano wstaje temu pan bóg daje” dokładnie raz. Porównanie idzie względem ograniczonego okna ostatnich słów, a nie całej transkrypcji, co utrzymuje szybkość na trzygodzinnym pliku i chroni przed skasowaniem zwrotu, który zasadnie powtarza się dwadzieścia minut później.
Sklejanie zdań z powrotem
Wiersz napisu jest wymierzony pod ekran: jakieś czterdzieści znaków, dwa wiersze naraz, złamane tam, gdzie tekst akurat doszedł do krawędzi. Zdania rutynowo rozciągają się na trzy albo cztery linie. Trzymanie jednego wiersza na linię daje dokument, który technicznie jest transkrypcją, a praktycznie jest nieczytelny.
Tryb akapitowy zbiera linie i łamie, gdy zejdą się dwa warunki: uzbierało się dość tekstu na akapit i bieżąca linia kończy się znakiem kończącym zdanie. Dzięki temu złamanie nigdy nie wypada w środku myśli. Twardy sufit i tak w końcu wymusza złamanie, bo niektórzy mówcy potrafią bardzo długo iść bez kropki, a nieprzerwana ściana tekstu jest nieczytelna na swój własny sposób. Zmiana mówcy zawsze zaczyna nowy akapit, co ma znaczenie przy wywiadach i panelach.
Cztery formaty, jedna idea
Format rozpoznawany jest po zawartości samego pliku, a nie po rozszerzeniu, bo pliki napisów są bez przerwy przemianowywane, a .txt z danymi SubRipa w środku to rzecz zupełnie zwyczajna.
- SubRip (.srt) — numeryczny indeks, zakres kodów czasowych z przecinkiem dziesiętnym, potem tekst. Format produkowany najczęściej i najprostszy.
- WebVTT (.vtt) — standard przeglądarki. Kropka zamiast przecinka dziesiętnego plus opcjonalne bloki
NOTE,STYLEiREGION, które nie są mową i są usuwane przed parsowaniem. VTT dopuszcza też znaczniki wewnątrz tekstu:<v Speaker>nazywa mówiącego,<c.classname>nakłada styl, a gołe znaczniki czasu wewnątrz linii sterują podświetlaniem słowo po słowie w stylu karaoke. Wszystko to jest rozpakowywane, a znacznik głosu staje się etykietą mówcy. - YouTube (.sbv) — para kodów czasowych rozdzielona przecinkiem we własnym wierszu, potem tekst. Bez indeksu, bez znaczników.
- Advanced SubStation (.ass i .ssa) — lista zdarzeń z zadeklarowaną kolejnością kolumn. Parser czyta ten wiersz
Format:, zamiast zakładać pozycje, bo pole Text stoi na końcu właśnie po to, żeby mogło zawierać przecinki. Bloki nadpisań w nawiasach klamrowych to instrukcje stylu i są usuwane; łamania wiersza\Nstają się spacjami. Kolumna Name, jeśli jest wypełniona, wskazuje mówcę.
Mówcy, efekty dźwiękowe i co zostawić
Przypisanie mówcy przychodzi na trzy sposoby, zależnie od formatu: dedykowanym polem w ASS, znacznikiem głosu w VTT albo gołą konwencją IMIĘ: na początku wiersza w SRT, który nie ma żadnego pola mówcy. Wszystkie trzy są rozpoznawane i normalizowane do tego samego wyjścia. Heurystyka dla trzeciego przypadku jest celowo wąska — ciąg wielkich liter zakończony dwukropkiem — bo prefiks pisany małymi literami łapałby zwykłe zdania z dwukropkiem i poszatkowałby transkrypcję.
Oznaczenia dźwięku w nawiasach, takie jak [MUSIC], (laughter) czy [APPLAUSE], domyślnie zostają, a przełącznik je usuwa. Co jest właściwe, zależy wyłącznie od zadania: dla przeszukiwalnego archiwum albo zapisu na potrzeby dostępności są częścią treści, a przy podawaniu wykładu modelowi do streszczenia są szumem.
Trzy kształty wyniku
Gotowe ustawienia pokrywają to, czego ludzie naprawdę chcą. Czysta transkrypcja to płynne akapity bez kodów czasowych, do czytania, cytowania albo podania modelowi. Ze znacznikami czasu zachowuje akapity, ale opatruje każdy jego czasem początkowym, i tego chcesz, gdy transkrypcja służy do wracania do konkretnego momentu nagrania. Wiersze napisów zachowuje jeden wiersz na linię wraz z kodem czasowym i bez odsiewania powtórzeń — najbliżej oryginalnego pliku, przydatne, gdy sprawdzasz same napisy, a nie czytasz je od deski do deski.
Obok wyniku narzędzie podaje rozpoznany format, liczbę linii, liczbę słów, pokryty czas i liczbę usuniętych powtórzeń. Ta ostatnia liczba jest najuczciwsza: jeśli jest duża, źródło było automatyczne i przewijane, i widzisz dokładnie, jaka część surowego pliku była powtórką.
Nic nie opuszcza przeglądarki
Pliki napisów nie zawsze są publiczne. Nagrania wywiadów, wewnętrzne zebrania firmowe, postępowania sądowe, konsultacje lekarskie i niewydany materiał filmowy — wszystko to je generuje. Parsowanie idzie w JavaScripcie w tej karcie, więc plik czytany jest lokalnie i nigdy nie jest wysyłany. To także powód, dla którego konwersja jest natychmiastowa i dlaczego zmiana opcji od razu przerysowuje wynik, zamiast robić kolejną rundę do serwera.