SWick

Sysadmin-by-Nature

Entries tagged "subtitle".

Speichern von Untertiteln - bzip2 vs zlib vs lzma
29th July 2012

Bisher speichere ich Text-Untertitel (meist im SubRip Format) als Base64-codierten String, der vorher mit zlib komprimiert ist, in einer MongoDB Datenbank. Auf der Debconf12 wurde vor kurzem diskutiert, ob man von gzip (zlib) auf xz (lzma/lzma2) umsteigen soll, um das Debian Archiv einzudampfen (derzeit 615 GB).

Dabei kam mir der Gedanke, vielleicht auch umzusteigen und zukünftig Untertitel vor dem Speichern in MongoDB mit xz zu komprimieren damit die Datenbank nicht explodiert. Aber nur weil das für Debian vielleicht von Vorteil ist, muss das in meinem Fall nicht auch so sein. Es gilt also selbst Tests durchzuführen.

Ein handvoll Untertitel zum Testen vorbereiten

$ find /media/master/Movies/ -name *.srt -exec cp "{}" /srv/subtitles/ \;

$ du -ch /srv/subtitles/*.srt

31M total

$ ls -l /srv/subtitles/ | wc -l

508

$ ls -l /srv/subtitles/ | awk '{s+=$5} END {print "Average file size: " s/NR/1024 "k"}'

Average file size: 58.1365k

Zum Testen sind also 508 Untertiteldateien vorhanden, die insgesamt eine Größe von 31 MB haben. SubRip Dateien sind in der Regel zwischen 40 und 100 KB groß, wie man auch unter "Average file size" sieht.

Mit xz komprimieren

$ time xz -k /srv/subtitles/*.srt

real    0m29.131s
user    0m26.670s
sys 0m0.216s

$ du -ch /srv/subtitles/*.xz

9.7M    total

Mit bzip2 komprimieren

$ time bzip2 -k /srv/subtitles/*.srt

real    0m7.469s
user    0m6.536s
sys 0m0.308s

$ du -ch /srv/subtitles/*.bz2

9.2M    total

Mit gzip komprimieren

$ time gzip /srv/subtitles/*.srt

real    0m4.660s
user    0m4.308s
sys 0m0.148s

$ du -ch /srv/subtitles/*.gz

12M total

xz soll angeblich sehr effektiv im Eindampfen sein, das, wie man hier sieht, nicht der Fall ist. Bei bereits nur 508 Untertiteln, spart bzip2 gegenüber gzip 2,8 MB ein und gegenüber xz 0,5 MB und braucht zeitlich nur gering länger als gzip. Bei xz dauert das schon sehr viel länger.

Da Untertitel meist nur einzeln und nicht in Bulk in MongoDB gespeichert werden, kann der Zeitverlust vernachlässigt werden:

Einzelnen Untertitel komprimieren

$ ls -lh subtitle.srt

65K Jul 29 18:28 subtitle.srt

$ time xz -k subtitle.srt

real    0m0.093s
user    0m0.064s
sys 0m0.020s

$ time bzip2 -k subtitle.srt

real    0m0.021s
user    0m0.004s
sys 0m0.012s

$ time gzip subtitle.srt

real    0m0.016s
user    0m0.008s
sys 0m0.004s

$ ls -alhS --reverse

21K Jul 29 18:28 subtitle.srt.bz2
22K Jul 29 18:28 subtitle.srt.xz
27K Jul 29 18:28 subtitle.srt.gz

Dauert alles weniger als 200 ms, ab wann es für den Menschen spürbar wird, was Latenz betrifft....

Versuch mit größeren Dateien

$ wget 'http://cachefly.cachefly.net/100mb.test' -O 100M.tar

Das Testfile von Cachefly beinhaltet sehr viele Textdateien.

$ tar tfv 100M.tar

Mit xz komprimieren

$ time xz -k 100M.tar

real    0m53.034s
user    0m51.811s
sys 0m0.296s

Mit bzip2 komprimieren

$ time bzip2 -k 100M.tar

real    0m21.024s
user    0m20.761s
sys 0m0.092s

Mit gzip komprimieren

$ time gzip 100M.tar

real    0m2.762s
user    0m2.488s
sys 0m0.136s

Resultat

$ ls -alhS --reverse

 44K Feb 28  2005 100M.tar.xz
1.5M Feb 28  2005 100M.tar.bz2
4.5M Feb 28  2005 100M.tar.gz

In diesem Fall hat xz also ganze Arbeit geleistet und 100 MB in nur 44 KB eingestampft. Bei Kompression kommt es natürlich immer darauf an, welche Art von Daten man schrumpfen will. So wie es aussieht, ist für kleine Textdateien < 900 KB bzip2 die beste Wahl. Bei sehr viel größeren Dateien wie z.B. Logfiles oder auch Binary Files zeigt xz seine Stärken.

D.h. zum Speichern der Untertitel ist in diesem Anwendungsfall bzip2 der geeignetere Kandidat. Den Code umzustricken dürfte eine Kleinigkeit sein, da die API der Python Module gleich aufgebaut ist:

Ein

$ sed -i 's/zlib\.compress/bz2\.compress/g' *.py
$ sed -i 's/zlib\.decompress/bz2\.decompress/g' *.py

wäre warscheinlich schon alles...

Links

Tags: db, mongodb, nosql, subtitle.
Encoding von Text Untertiteln fixen
3rd November 2012

Heute hab ich ein paar Untertitel in die Finger bekommen, bei denen das Character Encoding unbekannt war und das gefixed werden musste. Die Screenshots sind von Totem, da VLC nach der Korrektur weiterhin nur Müll als Text angezeigt hat.

Ausgangslage

Movie.Chs.srt
Movie.Cht.srt
Movie.Eng.srt
Movie.mkv

Versuch 1

file *.srt
Movie.Chs.srt: Non-ISO extended-ASCII text, with CRLF line terminators
Movie.Cht.srt: ISO-8859 text, with CRLF line terminators
Movie.Eng.srt: ASCII text, with CRLF line terminators
file --mime-encoding *.srt
Movie.Chs.srt: unknown-8bit
Movie.Cht.srt: iso-8859-1
Movie.Eng.srt: us-ascii

Da die englischen Untertitel korrekt angezeigt werden und UTF-8 abwärtskompatibel zu ASCII ist, betrachten wir nur die beiden anderen Untertitel. ISO-8859-1 für Movie.Cht.srt kann eigentlich nicht stimmen, da dieser soweit ich weiß, keine asiatischen Zeichen darstellen kann. Aber probieren wir es einfach mal, denn beim Thema Encoding ist oft Raten angesagt.

iconv -f ISO-8859-1 -t UTF-8 Movie.Chs.srt > Movie.Chs.utf8.srt

Hm, sieht genauso scheisse aus. Das war eher eine Verschlimmbesserung. file erzählt mir hier glaub was vom Pferd[*]...

Versuch 2

Mal sehen, was uchardet bzw. chardet so meint. ( enca war keine große Hilfe )

# uchardet unterstützt kein Globbing ( *.srt )
for subtitle in *.srt ; do echo -n "$subtitle " ; uchardet "$subtitle" ; done
Movie.Chs.srt gb18030
Movie.Cht.srt Big5
Movie.Eng.srt ascii/unknown
chardet *.srt
Movie.Chs.srt: GB2312 (confidence: 0.99)
Movie.Cht.srt: Big5 (confidence: 0.99)
Movie.Eng.srt: ascii (confidence: 1.00)

Aha, GB 18030 bzw. GB2312 und Big5 klingt schon vielversprechender.

iconv -f GB2312 -t UTF-8 Movie.Chs.srt > Movie.Chs.UTF8.srt
iconv: illegal input sequence at position 10003

Ok, der erste Schuss ging daneben.

iconv -f GB18030 -t UTF-8 Movie.Chs.srt > Movie.Chs.UTF8.srt

Sieht gut aus. Keine Fehlermeldung.

iconv -f BIG-5 -t UTF-8 Movie.Cht.srt > Movie.Cht.UTF8.srt

Ebenfalls keine Fehlermeldung. Mal sehen, was Totem jetzt dazu meint.

Das sieht doch gut aus. Man könnte meinen, dass die Untertitel identisch sind, schaut man aber mal genauer mit Meld hin, sieht man, dass sich die Texte manchmal gleichen, manchmal aber nicht. Muss daran liegen, dass sich viele asiatische Sprachen gegenseitig Zeichen aus deren Schriften entleihen.

Mission accomplished... FIXED !

Man kann natürlich, sobald man das Encoding herausgefunden hat, einfach im Videoplayer das entsprechende Encoding für den jeweiligen Untertitel auswählen, aber da UTF-8 der de-facto Standard ist, bevorzuge ich die Konvertierung...


[*] http://superuser.com/questions/301552/how-to-auto-detect-text-file-encoding

file only detects encodings with specific properties, such as UTF-8 or UTF-16.
The rest -- oldish ISO8859 or their MS-DOS and Windows correspondents -- are listed as "unknown-8bit" or something similar,
even for files which chardet detects with 99% confidence.
Tags: encoding, subtitle.

RSS Feed

"People said I should accept the world. Bullshit! I don't accept the world." -- Stallman