Großreinemachen im TVheadend
"Cleaning a TV with a soft sponge" by DALL-E 2

Großreinemachen im TVheadend

Ein vollgelaufenes Aufnahmeverzeichnis sorgt bei TVheadend für sehr unangenehmes Verhalten. Vieles, was da herumliegt, sind zudem Dateien, die keinen sinnvollen Zweck mehr erfüllen.

Schon vor vielen Jahren habe ich meinen guten lten VDR-Rekorder durch eine dezentrale TVheadend-Installation ersetzt, die seitdem im wesentlich unauffällig ihre Arbeit verrichtet.

Auch wenn das System, vor allem in Verbindung mit KODI auf den Fernsehern, insgesamt durchaus ein Fortschritt war, so gibt es dennoch Bereiche, in denen ich mir die Fähigkeiten des VDR zurückwünsche: Zum einen die überlegenen Möglichkeiten, Aufnahmen sehr flexibel zu konfigurieren, sodass Dopplungen zuverlässig ausgeschlossen werden können, und z. B. immer die neuesten n Aufnahmen aufgehoben werden. Zum anderen implizierte das aber auch äußerst praktische, automatische Löschungen, die fehlen mir in TVheadend auch sehr.

Umso unangenehmer ist es, dass TVheadend sehr seltsam reagiert, wenn sein Speicher einmal vollläuft (hier z.B. 2000 % CPU-Last) und auch gerne mal mitten im manuellen Löschen von Einträgen abstürzt. Höchste Zeit also für ein Großreinemachen.

Überreste vom Löschen von Files

Zunächst fällt auf, dass offensichtlich beim manuellen Löschen über die Oberfläche gelegentlich doch Reste übrig bleiben, wenn TVheadend dabei abstürzt:

$ find /storage/media/video/tvheadend -type f -name '*.ts.removing' -print0 | xargs -0 ls -l "\{\}" | awk '{sum+=$5;}END{print sum;}'
324992735256

In meinem Falle sind das alleine schon einmal 325 GB. Das kann schon einmal alles weg:

find /storage/media/video/tvheadend -type f -name '*.ts.removing' -print0 | xargs -0 rm

Aufnahmen ohne Dateien

Seine Aufnahmen scheint der TVheadend – soweit sich das mir erschließt – über Log-Dateien im Verzeichnis dvr/log seines Config-Verzeichnisses zu verwalten. Ein Blick in diese Dateien zeigt, dass es sich dabei offensichtlich um das JSON-Format handelt. Dank jsj können wir solche JSON-Dateien auch bequem in Kommandozeilenoperationen verwursten. In den Dateien findet sich unter files ein Array mit den einzelnen Dateien der Aufnahme. Darin dann unter filename der dazugehörige Dateiname. Nachdem ich die Standardeinstellung von TVheadend übernommen habe, Aufnahmen nicht in mehrere Dateien aufzuspalten, habe ich hier also ohnehin nur einen einzigen Eintrag. Lassen wir uns zur Kontrolle also einmal zu jeder Aufnahme hier die referenzierte Datei ausgeben:

for i in *; do echo -n $i": "; sudo jq '.files[0].filename' $i; done
0513b01741af881aea1dc337ac242449: "/storage/media/video/tvheadend/Checker Tobi/Checker Tobi-35.ts"
05214b80439f581bed89585081019a68: null
055556a3ce2019f986d8d4d08fdd09d1: "/storage/media/video/tvheadend/Checker Julian/Checker Julian-7.ts"
058778411461b203879ebd67b520ab22: "/storage/media/video/tvheadend/Lwenzahn/Lwenzahn-60.ts"
05bde5eadb550a3d4c7d72c3349324cc: null
usw...

Erstaunlicherweise haben wir hier also eine ganze Menge Einträge in der Liste, zu denen es kein korrespondierendes File im Aufnahmeverzeichnis mehr gibt. Ich weiß nicht, warum diese Dateien hier sind, hoffe aber inständig, dass TVheadend diese benutzt, um das Aufnehmen von Dubletten zu verhindern (weiß da jemand was dazu? Bitte Nachricht!). Viel Speicherplatz ist mit dem Löschen der Dateien ohnehin nicht zu gewinnen, daher lasse ich diese mal liegen.

Die nächste Frage ist, ob alle Files, die in diesen Dateien referenziert werden, tatsächlich auch verwendet werden. Erstaunlicherweise findet sich eine große Anzahl von referenzierten Aufnahmedateien, die nicht mehr existieren:

for f in * ; do
  FILENAME=`jq -r '.files[0].filename' "$f"`
  if [ "$FILENAME" == null ]; then continue ; fi
  if [ ! -f "$FILENAME" ]; then echo "Missing in $f: $FILENAME"; fi
done

Auch hier traue ich mich noch nicht, diese (zum Glück recht kleinen) Dateien zu entfernen, da man sich eine legitime Verwendung von TVheadend hier durchaus noch vorstellen kann, auch wenn die dazugehörigen Videofiles bereits gelöscht sind (z. B. Vermeidung der Aufnahme von Wiederholungen).

Spannend ist jetzt allerdings die Frage, ob es Videofiles gibt, die durch keine einzige Aufnahmedatei hier referenziert werden. Diese wäre ich nämlich durchaus bereit, hemmungslos zu löschen.

Wir benötigen dazu eine alphabetische Liste aller referenzierten und aller existenten Dateien:

jq -r '.files[0].filename' * | grep -v null | sort > ~/referenced_files.txt
find /storage/media/video/tvheadend/ -type f | sort > ~/real_files.txt

Damit können wir uns eine Liste aller Videofiles ausgeben lassen, die in keiner Aufnahmedatei referenziert werden:

comm -23 ~/real_files.txt ~/referenced_files.txt

In meinem Falle ergibt das eine recht stattliche Liste von 228 Video-Dateien, die nicht mehr von TVheadend referenziert werden, somit – wenn die Hypothese stimmt – auch nicht mehr im Frontend angezeigt werden. Viele nutzlose Speicherfresser. Um sicherzugehen, dass ich mit dieser Hypothese richtig liege, habe ich ein paar Stichproben genommen und sichergestellt, dass a) der Dateiname wirklich nirgendwo mehr im log-Verzeichnis vorkommt, unabhängig von der Position innerhalb der JSON-Strukur (z.B. grep 'Terra X-88.ts' *) und b) dass auch über die TVheadend Web-GUI die gefundenen Aufnahmen nicht mehr auffindbar waren. Beides gab keinen Grund zur Sorge.

Jetzt also allen Mut zusammen nehmen und diese Dateien löschen:

comm -23 ~/real_files.txt ~/referenced_files.txt | while read line; do sudo rm -f "$line" ; done

Fazit

Alleine durch das Entsorgen von nicht mehr referenzierten Videodateien konnte ich 1,5 GB von meiner 3 GB Aufnahmepartition freibekommen. TVheadend scheint nicht besonders gut darin zu sein, die Konsistenz seiner Datenablage auch über kritische Situationen hinweg zu gewährleisten.

Offen bleibt für mich die Frage, ob die Aufnahmedateien ohne Referenz (oder vielleicht sogar jene mit Referenz, die aber nicht mehr existierte) von TVheadend beabsichtigt sind, oder ob man diese auch gleich aufräumen sollte.

© 2024 Tobias Henöckl