Newsgroup: it.comp.software.divx
Titolo: conversione sottotitoli DVD->srt

questo post e' rivolto perlopiu' a utenti linux che sono
interessati a convertire in formato testuale (diciamo srt)
i sottotitoli presenti sui propri DVD.
l'unico strumento attuale (open source per linux) che conosca
si chiama "subtitleripper", ma non ne sono molto soddisfatto
(piu' sotto spieghero' i motivi), quindi mi e' venuta voglia
di tentare di scrivere un altro programma.
se qualcun altro fosse interessato, si faccia vivo,
specificando:
- se e' disposto a fare qualche test, provando le versioni
  dei programmi sui propri DVD e riportando i risultati, e
  magari dando consigli per futuri miglioramenti
- se vuole contribuire anche solo a livello di idee
- se conosce il C e vuole darmi una mano nella scrittura
  del programma
se non c'e' nessuno che dia una mano a programmare, passero'
a utilizzare un altro linguaggio...
adesso spiego i motivi per cui non sono soddisfatto dagli
attuali programmi.
"subtitleripper" ha una utility che si chiama "vobsub2pgm"
ma non funziona bene; ha anche una utility che si chiama
"subtitle2pgm" che a dire il vero non ho mai provato, ma
siccome anch'essa usa "spudec.c" e questo e' buggato, sono
certo che sia buggata anch'essa...
il bug si trova nel file "spudec.c", nel modo in cui e'
progettata la funzione "spudec_process_control"; il bug
si manifesta solo in casi particolari (su alcuni sottotitoli
funziona bene, su altri, presi da altri DVD, ogni tanto
viene fuori qualche immagine scorretta...); credo che cio'
sia accaduto perche' non esistono documenti che descrivono
tali SPU (Sub Picture Unit) e quindi questi ragazzi hanno
dovuto capire come funzionano usando la propria
immaginazione :-)
la funzione "spudec_process_control" e' il cuore della
decodifica, costituito da un doppio ciclo in cui viene
interpretata una sequenza di "codici"; ad esempio, c'e'
un codice che dice "ecco, questo e' il momento in cui
occorre iniziare a visualizzare il sottotitolo corrente"
e un altro codice che dice "basta, adesso il sottotitolo
va fatto scomparire"...
ad ogni modo, ho riscritto tutto il file "spudec.c" in
modo completamente diverso e, su tutti i DVD che ho
provato (una ventina), mi sembra che dia sempre risultati
corretti.
questo primo tassello del programma l'ho messo sulla
pagina:
http://fsinapsi.altervista.org/code
il file da prendere e' vobsub2srt.tar.gz
l'ho chiamato "vobsub2srt" ma in realta' non genera srt,
ma si limita fare quello che fa l'utility "vobsub2pgm"
(di "subtitleripper"), solo che questa e' corretta e
inoltre non genera pgm 720x576 ma pbm aventi risoluzione
minimale.
per chi volesse sperimentare gia' con questo, le
istruzioni da seguire sono le seguenti:
(1)
si compila (da linux), battendo "make"
(probabilmente si puo' compilare anche sotto windows,
sotto cygwin o mingw)
(2)
si crea un sottotitolo vobsub con mencoder, dando un
comando simile a questo:
mencoder dvd://1 -oac ... -ovc ... -vobsubout subtitles
 -vobsuboutindex 0 -sid 0
mi raccomando, il nome del file da usare per i sottotitoli
e' "subtitles", non usate altri nomi.
alla fine di questo comando, avrete due file:
subtitles.idx
subtitles.sub
(3)
a questo punto si da' questo comando:
vobsub2srt 2> pippo.srtx
se tutto e' andato bene, sulla directory corrente
verranno creati tanti piccoli file pbm che contengono
tutti i sottotitoli. inoltre il file "pippo.srtx"
conterra' righe del tipo:
----------------------------
1
00:00:23,599 --> 00:00:24,789
xxx0001.pbm
2
00:01:55,360 --> 00:01:57,850
xxx0002.pbm
eccetera
----------------------------
i tempi sono leggermente diversi da quelli ottenuti
con "vobsub2pgm" (dovrebbero essere piu' accurati)
a questo punto entra in gioco l'OCR.
ho fatto un po' di test con "ocrad" e con "gocr" e
ho finito per preferire il secondo con le opzioni
-m 130 -m 256 (usa soltanto il database!).
non so quale sia l'ultima versione di GOCR, ma io
ho trovato la 0.39 e vi ho riscontrato vari errori,
alcuni banali, altri di difficile soluzione...
innanzitutto, se GOCR non riconosce una combinazione
di due lettere "fuse", come ad esempio "tt", "AZ",
"rv"... allora chiede all'utente e memorizza tale
associazione nel database; tuttavia, se in una
sessione successiva riconosce tale combinazione
si presenta un bug: la prima lettera viene
raddoppiata! Quindi si puo' ottenere una cosa
come questa:
-----------------------------------
1
00:00:25,679 --> 00:00:34,009
PRESENTAAZlONE DEL NOSTRO FlLM
2
00:00:39,799 --> 00:00:42,819
''La vendettta è un piattto
che va serrvito freddo.''
-----------------------------------
in pratica ci sono tre "ttt" a causa di un bug, e lo
stesso accade con "AAZ", dove la "A" viene inspiegabilmente
raddoppiata...
questo e' un bug banale, che si risolve subito: basta
andare nel file "src/database.c", nella funzione "ocr_db"
va individuato questo pezzo di codice:
-----------------------------------
      if (c && c!=UNKNOWN)
        setac(box1, c, 100-dist);
      if (box3->obj) {
        /* its not a good solution, but better then nothing: */
        if (box1->obj) free( box1->obj);
        box1->obj = (char *) malloc( strlen(box3->obj)+1 );
        if (box1->obj)
            memcpy( box1->obj, box3->obj, strlen(box3->obj)+1 );
      }
    }
-----------------------------------
e va sostituito con questo:
-----------------------------------
      if (c && c!=UNKNOWN)
        setac(box1, c, 100-dist);
      if (box3->obj) {
        /* its not a good solution, but better then nothing: */
        if (box1->obj) free( box1->obj);
        box1->obj = (char *) malloc( strlen(box3->obj)+1 );
        if (box1->obj)
            memcpy( box1->obj, box3->obj, strlen(box3->obj)+1 );
        box1->c = 0;
      }
    }
-----------------------------------
comunque ci sono altri bug, purtroppo anche fondamentali...
ad esempio, il programma non tiene nemmeno conto di una
"baseline" e questo crea un sacco di problemi... ad
esempio, sempre dai sottotitoli di "kill bill" si ottiene
questo:
--------------------------------
161
01:38:09,279 --> 01:38:12,089
Non sai dove sei
né da dove sei part,ito.
--------------------------------
la virgola nell'ultima riga c'e' davvero, ma e' alla
fine della riga precedente! questo e' potuto accadere
perche' il programma non considera nessuna "baseline"!
insomma, adesso non ho piu' tempo e ho gia' scritto molto :-)
quindi concludo dicendo che ho intenzione di scrivere un
OCR ad hoc (non general purpose!!!) che serva solo per i
sottotitoli ma che funzioni in modo decente...
credo che cio' non richiedera' moltissimo tempo (ripeto
che non si tratta di fare un vero OCR, roba tipo
"feature extraction" e simili...)
chi e' interessato, si faccia vivo.

   del programma
Per questo un po' meno perchè non so se ho tempo, non riesco a portare
avanti neanche i miei progetti.
bye
-- 
HomePage e FAQ: 
http://giubbe.altervista.org
Inutile scrivere in privato, non ricevo le email 

 Queste due sicuramente.
bene, grazie. mi son dimenticato di dire che questa cosa non ha
un'alta urgenza e quindi la mandero' avanti quando avro'
tempo/voglia 
(in altre parole, non sara' pronto in brevissimo tempo)
hai mai provato GOCR?
(si trova qua: 
http://jocr.sourceforge.net
 )
in estrema sintesi, quello che vorrei fare e' la sola "modalita'
database" di GOCR, pero' superando alcuni suoi limiti.
la "modalita' database" di GOCR e' veramente facile da rifare
partendo da zero (GOCR e' un programma molto piu' complesso,
ma a me interessa solo la "modalita' database");
se non sai di cosa si tratta, dimmelo e te lo spiego in due
parole...
comunque, ho appena messo un'altra versione di questo:
http://fsinapsi.altervista.org/code/vobsub2srt.tar.gz
ho apportato qualche modifica, e ho gia' scritto un po' di
documentazione (tutto in italiano), quindi, al momento ci
sarebbe da testare la sola utility "vobsub2pbm"...
per compilare il programma, si batte "make" (con "make install",
da root, copi il programma in /usr/local/bin)
nei file LEGGIMI c'e' scritto come si usa.
adesso ho scoperto che potrebbe esserci un errore: ho trovato
un DVD da cui ho estratto i sottotitoli in formato vobsub, poi
ho estratto le immagini con "vobsub2pbm" e queste risultano
essere 980, mentre secondo il file indice dovrebbero essere 1010;
non mi e' ancora chiaro perche' siano state saltate 20 entries,
appena riesco faro' il debugging...
a parte questo (che vedro' di risolvere), chi lo volesse provare,
a me interessa sapere se scoprite altri bug con altri DVD; in
particolare, le immagini dovrebbero sempre venire con testo
nero su sfondo bianco (se trovate eccezioni, ditemelo).
intanto vorrei chiudere questa parte del programma, poi
passero' a spiegare come intendo fare il resto.
naturalmente, segnalatemi qualsiasi problema che incontrate.
ciao

 essere 980, mentre secondo il file indice dovrebbero essere 1010;
non era un errore: pare che il file indice sia sbagliato! tale
indice elenca 1009 entries (non 1010, come avevo scritto), mentre
"vobsub2pbm" estrae 980 immagini; tuttavia 29 entries nell'indice
sono sbagliate, ad esempio:
-----------------
...
timestamp: 00:06:15:079, filepos: 000037800
timestamp: 00:06:17:199, filepos: 000038800
timestamp: 00:06:20:240, filepos: 000039800
timestamp: 00:06:20:239, filepos: 00003a800
timestamp: 00:06:24:319, filepos: 00003b000
...
-----------------
la entry 00:06:20:240 ha un timestamp maggiore a quella successiva
(non mi era mai capitato), e se il programma non produce alcuna
immagine vuol dire che i codici di quella entry non sono giusti...
quindi, la versione attuale, per quanto ne so, dovrebbe essere
corretta...

 ma a me interessa solo la "modalita' database");
nell'ultima versione (che ho messo nel solito posto) ho
aggiunto un po' di documentazione; in particolare ho spiegato
(alla buona) come funziona la "modalita' database" di GOCR.
poi ho apportato qualche miglioramento.
inoltre ho messo una utility gia' pronta (pbm2srt) che usa GOCR
per effettuare la conversione finale.
quindi, gia' adesso c'e' tutto quello che serve per estrarre
un sottotitolo da un DVD e convertirlo in formato testuale SRT.
quello che mi resta da fare e' sostituire GOCR con un altro
programma (da scrivere) che implementi la sola modalita' database
di GOCR, ma che usi una rappresentazione piu' sofisticata dei
blocchi che compongono le immagini.
le prossime cose che faro' sara' scrivere le parti teoriche di
quello che dovro' implementare (quella che ho in mente e' una
specie di "teoria dei blocchi").