VdrTranscode
Faup (Diskussion | Beiträge) (→ABER , folgende Einschränkungen gibts) |
Hulk (Diskussion | Beiträge) (→News) |
||
(9 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 2: | Zeile 2: | ||
'''Autor:''' Alexander Richter | '''Autor:''' Alexander Richter | ||
− | + | ;letzte stabile Version: | |
[http://faup.fa.funpic.de/Vdrtransxvid/vdrtranscode_snapshot_2011-05-04.tar.gz vdrtranscode_snapshot_2011-05-04.tar.gz] | [http://faup.fa.funpic.de/Vdrtransxvid/vdrtranscode_snapshot_2011-05-04.tar.gz vdrtranscode_snapshot_2011-05-04.tar.gz] | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Kurzinfo== | ==Kurzinfo== | ||
Zeile 30: | Zeile 20: | ||
==Arbeitsweise== | ==Arbeitsweise== | ||
− | Im VDR Aufnahme Befehlemenü | + | Im VDR Aufnahme Befehlemenü kann ein Profil zum Umwandeln ausgewählt werden.<br> |
Der Aufnahmepfad bekommt einen Hinweis zu den Einstellungen eingebaut ala : | Der Aufnahmepfad bekommt einen Hinweis zu den Einstellungen eingebaut ala : | ||
Zeile 36: | Zeile 26: | ||
Im Hintergrund überprüft vdrtranscode_server.pl das Videoverzeichnis nach diesen Inserts und wird aktiv, wenn es eine [cut... Markierung findet.<br> | Im Hintergrund überprüft vdrtranscode_server.pl das Videoverzeichnis nach diesen Inserts und wird aktiv, wenn es eine [cut... Markierung findet.<br> | ||
− | Hat die Aufnahme | + | Hat die Aufnahme eine gerade Anzahl an gesetzten Markierungen ( aka Anfang, Ende und eventuelle Werbungsblöcke ), werden die Positivbereiche zu einem großem File zusammengefasst ( meint -> Schneiden kann entfallen ) und danach kodiert, sonst wird der ganze File genommen.<br> |
+ | Bei genau 2 Markern ( aka Start und Stop ) wird der Bereich von Start bis Stop kodiert.<br> | ||
+ | Ob die Aufnahme aus einer oder mehrereer TS Files besteht, spielt keine Rolle.<br> | ||
Der Server konvertiert diese Aufnahme ( im 2 Pass Modus und aktiviertem Turbo für Pass 1 ) , markiert sie während als [work.. und danach als [del...<br> | Der Server konvertiert diese Aufnahme ( im 2 Pass Modus und aktiviertem Turbo für Pass 1 ) , markiert sie während als [work.. und danach als [del...<br> | ||
Danach schaut er wieder periodisch nach, ob neue zu konvertierende Aufnahmen anstehen.<br> | Danach schaut er wieder periodisch nach, ob neue zu konvertierende Aufnahmen anstehen.<br> | ||
Zeile 53: | Zeile 45: | ||
** Logfile::Rotate | ** Logfile::Rotate | ||
− | Die meisten Perl Module | + | Die meisten Perl Module gehören zur Standardinstallation, sonst ist ( unter Debian ) "apt-file search Perlmodul" dein Freund. |
$ sudo apt-file search Rotate.pm | $ sudo apt-file search Rotate.pm | ||
Zeile 127: | Zeile 119: | ||
* /etc/init/vdrtranscode.conf<br> | * /etc/init/vdrtranscode.conf<br> | ||
− | ein Konfigurationsscript für Ubuntus neues upstart System, local läufts. | + | ein Konfigurationsscript für Ubuntus neues upstart System, local läufts. |
− | + | ||
− | + | ||
* /etc/vdr/command-hooks/reccmds.vdrtranscode.conf | * /etc/vdr/command-hooks/reccmds.vdrtranscode.conf | ||
Zeile 229: | Zeile 219: | ||
Die resultierenden Videos werden vor der Komprimierung in der Video Datenrate etwas feinjustiert, um runde Filegrößen zu bekommen.<br> | Die resultierenden Videos werden vor der Komprimierung in der Video Datenrate etwas feinjustiert, um runde Filegrößen zu bekommen.<br> | ||
− | + | Standardmäßig aktiv , ist decomp, ein Deinterlacer, der nur dann tätig wird, wenn Halbilder erkannt werden.<br> | |
− | Auch | + | Auch Standard ist anamorphe Kodierung ( außer bei HD und Webvideo ), kann in der conf deaktiviert werden. Sollte aber nicht, die Qualität ist besser und sexy ist es auch.<br> |
Die x264 Encoder Optionen sind etwas heftiger angelegt,für beste Bildqualität, die Prozessoren freut es :<br> | Die x264 Encoder Optionen sind etwas heftiger angelegt,für beste Bildqualität, die Prozessoren freut es :<br> | ||
Zeile 239: | Zeile 229: | ||
==ABER , folgende Einschränkungen gibts== | ==ABER , folgende Einschränkungen gibts== | ||
- Handbrake ist CPU süchtig eingestellt, ein FullHD in FullHD rekomprimieren, kann wohl seeeeehhhhr lange dauern.<br> | - Handbrake ist CPU süchtig eingestellt, ein FullHD in FullHD rekomprimieren, kann wohl seeeeehhhhr lange dauern.<br> | ||
− | - Wenn die erste Markierung in HD Material weit hinten ist, dauert es eine kleine Ewigkeit, bis der | + | - Wenn die erste Markierung in HD Material weit hinten ist, dauert es eine kleine Ewigkeit, bis der Bereich bis zur ersten Marke durchfahren ist<br> |
- Es gibt kein Echtzeitfeedback, wo Handbrake gerade ist, im Logfile, kann man zumindest die letzten Kodierungen überprüfen.<br> | - Es gibt kein Echtzeitfeedback, wo Handbrake gerade ist, im Logfile, kann man zumindest die letzten Kodierungen überprüfen.<br> | ||
- Einmal ein Aufnahmeverzeichnis fürs transcodieren markiert und ( fast ) unaufhaltbar gehts los ( nicht ganz , Server schnell killen und Markierung wieder entfernen, geht )<br> | - Einmal ein Aufnahmeverzeichnis fürs transcodieren markiert und ( fast ) unaufhaltbar gehts los ( nicht ganz , Server schnell killen und Markierung wieder entfernen, geht )<br> | ||
Zeile 252: | Zeile 242: | ||
− | < | + | <pre> |
root@siduxvdr:/home/linvdr# /etc/init.d/vdrtranscode_server start | root@siduxvdr:/home/linvdr# /etc/init.d/vdrtranscode_server start | ||
Starting vdrtranscode_server.pl : Can't locate Proc/Daemon.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at /usr/local/bin/vdrtranscode_server.pl line 11. | Starting vdrtranscode_server.pl : Can't locate Proc/Daemon.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at /usr/local/bin/vdrtranscode_server.pl line 11. | ||
Zeile 258: | Zeile 248: | ||
cat: /tmp/vdrtranscode_server.pid: No such file or directory | cat: /tmp/vdrtranscode_server.pid: No such file or directory | ||
rm: cannot remove `/tmp/vdrtranscode_server.pid': No such file or directory | rm: cannot remove `/tmp/vdrtranscode_server.pid': No such file or directory | ||
− | + | </pre> | |
− | </ | + | |
Daemon.pm findet man nach "apt-file update" in libproc-daemon-perl (lenny) | Daemon.pm findet man nach "apt-file update" in libproc-daemon-perl (lenny) | ||
Zeile 275: | Zeile 264: | ||
==letzte Worte== | ==letzte Worte== | ||
− | Da Proggi ist | + | Da Proggi ist nicht Bullet proof, da gibts bestimmt schöne Bugs, schaut bitte in die Scripte rein und ändert. |
Ich habe versucht fast alles, so simpel, wie möglich und nachvollziehbar zu schreiben, obwohl Perl ja für Write-Only bekannt ist. | Ich habe versucht fast alles, so simpel, wie möglich und nachvollziehbar zu schreiben, obwohl Perl ja für Write-Only bekannt ist. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
[[Kategorie:Video- und Audiobearbeitung]] | [[Kategorie:Video- und Audiobearbeitung]] | ||
+ | [[Kategorie:Skripte]] |
Aktuelle Version vom 8. September 2013, 10:03 Uhr
Inhaltsverzeichnis |
[Bearbeiten] News
Autor: Alexander Richter
- letzte stabile Version
vdrtranscode_snapshot_2011-05-04.tar.gz
[Bearbeiten] Kurzinfo
- ist eine Perl Script Sammlung um das Programm HandbrakeCLI herum
- konvertiert vdr TS files in h264 Videos
- Container mp4 ( m4v , wenn ac3 drin ) und mkv
- konvertiert im Hintergrund, keine Benutzerinteraktion nötig
Ein kurzes Video, das die Menüführung zeigt : Youtube->vdtranscode_menues_in_vdr
PS : Den Screencast hab ich erstellt mit vlc und nachbearbeitet mit avidemux2 :
$ cvlc screen:// --screen-fps 25 --nooverlay --sout "#transcode{vcodec=xvid,vb=6000,scale=0.8,acodec=mp3,ab=128,channels=2}:duplicate{dst=std{access=file,mux=avi,dst=screencast.avi}}"
[Bearbeiten] Arbeitsweise
Im VDR Aufnahme Befehlemenü kann ein Profil zum Umwandeln ausgewählt werden.
Der Aufnahmepfad bekommt einen Hinweis zu den Einstellungen eingebaut ala :
/video/Papageien,_Palmen_&_Co./[cut-m4v|HD-smallHD|VHQ|all](40)_Zoogeschichten_aus_dem_Loro_Park_auf_Teneriffa
Im Hintergrund überprüft vdrtranscode_server.pl das Videoverzeichnis nach diesen Inserts und wird aktiv, wenn es eine [cut... Markierung findet.
Hat die Aufnahme eine gerade Anzahl an gesetzten Markierungen ( aka Anfang, Ende und eventuelle Werbungsblöcke ), werden die Positivbereiche zu einem großem File zusammengefasst ( meint -> Schneiden kann entfallen ) und danach kodiert, sonst wird der ganze File genommen.
Bei genau 2 Markern ( aka Start und Stop ) wird der Bereich von Start bis Stop kodiert.
Ob die Aufnahme aus einer oder mehrereer TS Files besteht, spielt keine Rolle.
Der Server konvertiert diese Aufnahme ( im 2 Pass Modus und aktiviertem Turbo für Pass 1 ) , markiert sie während als [work.. und danach als [del...
Danach schaut er wieder periodisch nach, ob neue zu konvertierende Aufnahmen anstehen.
Alle konvertierten Aufnahmen landen im in der vdrtranscode.conf angegebenen Zielverzeichnis.
[Bearbeiten] Abhängigkeiten
- Vdr >= 1.7.4 ( ts Format )
- HandBrakeCLI
- Perl
- Proc::Daemon
- File::Find
- File::Copy
- File::Basename
- Getopt::Long
- Cwd
- Logfile::Rotate
Die meisten Perl Module gehören zur Standardinstallation, sonst ist ( unter Debian ) "apt-file search Perlmodul" dein Freund.
$ sudo apt-file search Rotate.pm
ergibt ( hier in kubuntu 10.04) :
... liblogfile-rotate-perl: /usr/share/perl5/Logfile/Rotate.pm ...
Installation mit :
$sudo apt-get install liblogfile-rotate-perl
[Bearbeiten] Paket Bestandteile / Installation
Alle Programmteile liegen im tgz im jeweiligen Verzeichnis, in das sie später sollen.
- /usr/local/bin/vdrtranscode_server.pl
Das Hauptprogramm kann als Daemon im Hintergrund laufen, ohne Parameter läufts im Vordergrund.
Ein guter Anfang zum Probieren :
$ /usr/local/bin/vdrtranscode_server.pl -v
Wichtig : /usr/local/bin/vdrtranscode_server.pl muss unter demselben User laufen, unter dem vdr läuft, sonst gibts Probleme beim Aufnahmeverzeichnis umbenennen.
In der Config muß dieser User angegeben werden.
vdrtranscode_server.pl als root gestartet, wechselt dann zu diesem User.
Optionen :
-h die Hilfe -d als Daemon im Hintergrund -l schreibe Logdatei ( insbesondere die handbrake Ausgaben ) ins Zielverzeichnis der umgewandelten Aufnahmen -v schreibe umfangreiche Infos auf die Ausgabe, wenn im Vordergrund laufend
- /usr/local/bin/vdrtranscode_touch_cuted_flag.pl
Übernimmt die Umbenennung der Aufnahmeverzeichnisse, wird vom Vdr Menüeintrag aufgerufen
- /etc/vdrtranscode.conf
Die KonfigurationsDatei , reinschauen und anpassen ...
# vdtranscode conf ## General settings Indir = /video/ Outdir = /home/alex/Videos/ # User of running vdr vdr_user = alex # nice Level for processing, valid is 0...19 , large means lower priority nice_level = 5 # Set kbps Video Data Rate for Encoding # UVHQ , VHQ and HQ Settings for HD Targets ( 1080 -> 1080 , 1080 -> 720 , 720 -> 720 ) # HQ and MQ Seting for SD Targets ( keep Dimensions ) # VLQ LQ for Webencoding ( sets maximum Width of Picture to 480px , resp. 640px width , always disables anamorph encoding ) UVHQ = 7000 VHQ = 3700 HQ = 1200 MQ = 800 LQ = 600 VLQ = 400 # Set Audio Bitrate for aac content AAC_Bitrate = 128 # use dynmic range control on audio AAC ( means compression , valid are 1.0 ( none ) ... 4.0 ( closing a Door sounds like roar of guns ) DRC = 2.5 ## Video Settings # anamorph encoding , recommended for better quality anamorph_encoding = 1 # set classic modus to speedup the encoding by factor 4 to 5 on smaller Encoding Quality use_classic_profile = no
- /etc/init.d/vdrtranscode_server
ein ( halbwegs ) Debian konformes Start und Stop Script. So benutzt, auch hier den User eintragen, unter dem VDR läuft, sonst klappt die
Umbenenung der Aufnahmeverzeichnisse ev. nicht.
- /etc/init/vdrtranscode.conf
ein Konfigurationsscript für Ubuntus neues upstart System, local läufts.
- /etc/vdr/command-hooks/reccmds.vdrtranscode.conf
erzeugt die Menüs, zur Auswahl der Komprimierung, bitte per Hand in die Vdr Struktur einpflegen, danach Vdr neu starten
Unter Ubuntu 10.04 mit den yavdr Quellen brauchts nach dem Kopieren ins Zielverzeichnis noch ein :
$ sudo ln -s /etc/vdr/command-hooks/reccmds.vdrtranscode.conf /usr/share/vdr/command-hooks/
Sieht so aus ( keine Angst , erklärt sich schnell ) :
Ein Auschnitt mit Erklärung :
... VdrTranscode High Quality SD{ # Auswahl Qualität und maximale Bildbreite , hier SD , also max. 720 breit Container mp4{ # klar first stereo Track only : vdrtranscode_touch_cuted_flag.pl mp4 noDD HQ first .... * first stereo Track only : -> Menüeintrag für nehme nur ersten Audiotrack ( mp2 ) * vdrtranscode_touch_cuted_flag.pl -> rufe dieses Script auf * Parameter 1 -> mp4 -> Container * Parameter 2 -> noDD -> nimm keine DolbyDigital Spur mit * Parameter 3 -> HQ -> nimm die unter HQ in der conf angegebene Video Bitrate * Parameter 4 -> first -> nimm nur die erste Audiotonspur ( mp2 ) mit
Das ganze Werk :
VdrTranscode High Quality SD{ Container mp4{ first stereo Track only : vdrtranscode_touch_cuted_flag.pl mp4 noDD HQ first first stereo Track only + DD : vdrtranscode_touch_cuted_flag.pl m4v DD HQ first all stereo Tracks : vdrtranscode_touch_cuted_flag.pl mp4 noDD HQ all all stereo Tracks + DD : vdrtranscode_touch_cuted_flag.pl m4v DD HQ all } Container mkv{ first stereo Track only : vdrtranscode_touch_cuted_flag.pl mkv noDD HQ first first stereo Track only + DD : vdrtranscode_touch_cuted_flag.pl mkv DD HQ first all stereo Tracks : vdrtranscode_touch_cuted_flag.pl mkv noDD HQ all all stereo Tracks + DD : vdrtranscode_touch_cuted_flag.pl mkv DD HQ all } } VdrTranscode Mid Qualiy SD{ Container mp4{ first stereo Track only : vdrtranscode_touch_cuted_flag.pl mp4 noDD MQ first first stereo Track only + DD : vdrtranscode_touch_cuted_flag.pl m4v DD MQ first all stereo Tracks : vdrtranscode_touch_cuted_flag.pl mp4 noDD MQ all all stereo Tracks + DD : vdrtranscode_touch_cuted_flag.pl m4v DD MQ all } Container mkv{ first stereo Track only : vdrtranscode_touch_cuted_flag.pl mkv noDD MQ first first stereo Track only + DD : vdrtranscode_touch_cuted_flag.pl mkv DD MQ first all stereo Tracks : vdrtranscode_touch_cuted_flag.pl mkv noDD MQ all all stereo Tracks + DD : vdrtranscode_touch_cuted_flag.pl mkv DD MQ all } } VdrTranscode Low Quality Webvideo : vdrtranscode_touch_cuted_flag.pl mp4 noDD LQ first VdrTranscode HD convert - keep Picturesize { Container m4v{ Ultra Very High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-HD UVHQ all Very High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-HD VHQ all High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-HD HQ all } Container mkv{ Ultra Very High Quality : vdrtranscode_touch_cuted_flag.pl mkv HD-HD UVHQ all Very High Quality : vdrtranscode_touch_cuted_flag.pl mkv HD-HD VHQ all High Mid Quality : vdrtranscode_touch_cuted_flag.pl mkv HD-HD HQ all } } VdrTranscode HD-smallHD convert - downsize Pictureformat { Container m4v{ Ultra Very High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-smallHD UVHQ all Very High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-smallHD VHQ all High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-smallHD HQ all } Container mkv{ Ultra Very High Quality : vdrtranscode_touch_cuted_flag.pl m4v HD-smallHD UVHQ all Very High Quality : vdrtranscode_touch_cuted_flag.pl mkv HD-smallHD VHQ all High Quality : vdrtranscode_touch_cuted_flag.pl mkv HD-smallHD HQ all } } VdrTranscode Remove cut/del Flag : vdrtranscode_touch_cuted_flag.pl REMOVE undef undef undef
[Bearbeiten] Im Detail
Das Script geht stets vom Ziel der Komprimierung aus, es geht also jegliche Quelle einem Zielprofil zuzuordnen.
Das meint, aus z.B. einer 1080 HD Quelle kann man anwählen :
- SD Format mit Mid Quali , High Quali
- Low Quality Webformat 480px Breite max.
- HD Recomprimierung , Bild bei 1080 beibehalten
- smallHD , komprimieren nach 720p
Kleinere Bildformate ( SD ) könnte man z.B. einem smallHD Ziel zuorden, es wird aber nirgends hochskaliert, macht also keinen Sinn.
In den Untermenüs, nach der Wahl der Qualität und der Bildgröße, legt man die gewünschten Audiospuren und den Container fest, ein beherzter Druck, der File bekommt eine
führende Markierung und vdrtranscode_server findet und bearbeitet es.
Mögliche Audioauswahl kann sein :
- nur erste Stereorspur nutzen ( mp2 )
- alle Stereospuren ( mp2 )
- zusätzlich Dolby Digital mit durchreichen ( keine Neukomprimierung )
- alle mp2 Audiospuren ( die zu aac werden ) , werden etwas normalisiert ( 2.5 ) , um die Lautheit zu erhöhen.
Einstellbar in der conf als Parameter DRC, valide ist 1.0 ( orig belassen ) bis 4.0 ( Türzuschlag = Kanonenschlag )
Die resultierenden Videos werden vor der Komprimierung in der Video Datenrate etwas feinjustiert, um runde Filegrößen zu bekommen.
Standardmäßig aktiv , ist decomp, ein Deinterlacer, der nur dann tätig wird, wenn Halbilder erkannt werden.
Auch Standard ist anamorphe Kodierung ( außer bei HD und Webvideo ), kann in der conf deaktiviert werden. Sollte aber nicht, die Qualität ist besser und sexy ist es auch.
Die x264 Encoder Optionen sind etwas heftiger angelegt,für beste Bildqualität, die Prozessoren freut es :
Zeile 247 in vdtranscode_server.pl :
# ref=2:mixed-refs:bframes=2:b-pyramid=1:weightb=1:analyse=all:8x8dct=1:subme=7:me=umh:merange=24:trellis=1:no-fast-pskip=1:no-dct-decimate=1:direct=auto
[Bearbeiten] ABER , folgende Einschränkungen gibts
- Handbrake ist CPU süchtig eingestellt, ein FullHD in FullHD rekomprimieren, kann wohl seeeeehhhhr lange dauern.
- Wenn die erste Markierung in HD Material weit hinten ist, dauert es eine kleine Ewigkeit, bis der Bereich bis zur ersten Marke durchfahren ist
- Es gibt kein Echtzeitfeedback, wo Handbrake gerade ist, im Logfile, kann man zumindest die letzten Kodierungen überprüfen.
- Einmal ein Aufnahmeverzeichnis fürs transcodieren markiert und ( fast ) unaufhaltbar gehts los ( nicht ganz , Server schnell killen und Markierung wieder entfernen, geht )
[Bearbeiten] Tricks und Tips
Tragt ein, was ihr rausgefunden habt ( Bugs, Hints, Stolperfallen etc. )
Ich hatte als User vdr eingetragen, aber die Art und weise, wie das Startskript die PID ausliest, funktioniert nicht (das pid-File wird nicht erzeugt).
vdr läuft allerdings als root (nur vdr-kbd als vdr), wenn ich user=root setze bekomme ich diese Fehlermeldung beim Starten des Daemons:
root@siduxvdr:/home/linvdr# /etc/init.d/vdrtranscode_server start Starting vdrtranscode_server.pl : Can't locate Proc/Daemon.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.1 /usr/local/share/perl/5.10.1 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at /usr/local/bin/vdrtranscode_server.pl line 11. BEGIN failed--compilation aborted at /usr/local/bin/vdrtranscode_server.pl line 11. cat: /tmp/vdrtranscode_server.pid: No such file or directory rm: cannot remove `/tmp/vdrtranscode_server.pid': No such file or directory
Daemon.pm findet man nach "apt-file update" in libproc-daemon-perl (lenny)
Nachinstalliert: libproc-daemon-perl, liblogrotate-rotate-perl.
Anschließend "stirbt" der Dämon in Zeile 504: Die Funktion quit() wird allerdings nur aufgerufen, wenn IN/OUTDIR nicht existiert, dann aber mit einer entsprechenden Fehlermeldung, die hier nicht erscheint!
Mit strace wird die Fehlermeldung angezeigt - jedenfalls existierte in der Tat das angegebene Ausgabeverzeichnis NICHT! Nach Anlegen des Verzeichnisses war nur das PID-Problem zu lösen:
Hiermit klappt es:
pgrep -f vdrtranscode_server.pl > /var/run/vdrtranscode_server.pid
[Bearbeiten] letzte Worte
Da Proggi ist nicht Bullet proof, da gibts bestimmt schöne Bugs, schaut bitte in die Scripte rein und ändert. Ich habe versucht fast alles, so simpel, wie möglich und nachvollziehbar zu schreiben, obwohl Perl ja für Write-Only bekannt ist.