Zum Inhalt springen

Archivierung von YouTube-Livestreams

YouTube begann vor einiger Zeit damit, technisch auch Live-Streams zu ermöglichen. Die Technik dahinter ist relativer Standard, es kommt HLS (HTTP Live Streaming) und mpeg4 zum Einsatz. Das ganze wird über eine `.m3u`-Ressource abgewickelt, die der Browser abruft.

Nun möchte YouTube aber nicht, dass man auf bestimmten Geräten den Stream im Hintergrund laufen lässt, oder sogar Videos generell: Vermutlich um den „Missbrauch“ als Gratis-Spotify zu verhindern und den Video-Werbenden auch „Video“-Werbung verkaufen zu können.

Mir sind die wirtschaftlichen Hintergründe und die YouTube AGB egal, weil YouTube als Teil von Alphabet auch ein Monopolist ist und Live-Streaming eines der wenigen Bereiche ist, bei dem sie nicht den Markt dominieren (Amazons Twitch ist hier dominierend).

Nun schaue ich gerne diverse regelmäßige Livestreams an, u.a. die Mainboad-Repair-Videos von Louis Rossmann aus New York oder die langen Streams von Bjørn Nyland aus Oslo, wenn er mit einem Elektroauto tausende Kilometer durch Norwegen zurücklegt. Diese Art von Streams sind unerhaltsam, aber einfach nicht ausfüllend genug, um sie 100% der Zeit „modal“ zu konsumieren und so laufen die Streams bei mir im Hintergrund – leider bisher nicht auf iOS oder Android-Geräten, weil YouTube dies unterbindet.

Und dann gibt es noch Streams, die von den Produzenten wieder gelöscht werden, weil etwas zu skurriles oder unprofessionelles passiert ist: Das frisierte E-Bike fackelt mitten in Manhattan ab,oder ein Idiot darf sich wegen unprofessioneller Fahrweise einen lauten Anschiss anhören. All das will man als Fan natürlich mitbekommen, auch wenn man gerade nicht in der passenden Zeitzone lebt oder anderweitig beschäftigt war.

Eine Archivierungs-Lösung muss her!

diagram
So ähnlich schaut es aus…

Problemstellung:

  1. Automatisches Aufzeichnen von Streams
  2. Abspielen von Streams ohne YouTube-App oder Modal-Zwang (wie z.B. in Safari, Chrome auf mobilen Plattformen).

Ich legte los und bastelte einen Prototypen auf Basis von etwas Ruby, MQTT, Streamlink, dazu VLC auf iOS, Pushover.com als Push-Service und in der späteren Version dann Syncthing zur Dateisynchronisation.

Positiv anzumerken ist, dass Google einen wenig beachteten Pubsubhubbub-Server betreibt (Vorgänger von WebSub) und YouTube darüber Push-Notifications per HTTP für YouTube-Kanäle anbietet. Allerdings nur sehr rudimentär, man kann nicht einmal zuverlässig darauf schliessen, ob ein neues Video hochgeladen, ein Stream begonnen oder einfach nur die Beschreibung eines Videos oder Streams verändert wurden. Man bekommt also sehr viele „doppelte“ Notifications.

Somit wäre der erste Teil eigentlich schnell beschrieben: Die Ruby-Applikation auf einem virtuellen Server bei einem Cloud-Provider abonniert beim Start die passenden Topics (Kanäle), erhält dann via HTTP requests Infos zu neuen Streams. Diese werden per MQTT an einen anderen Docker-Container weitergeleitet, bei dem dann die downloads gestartet werden.

Für den zweiten Teil wird es komplizierter: Erstens sind die von YouTube bereitgestellten `.m3u`-Files mittels kryptographischer Signatur auf die abrufende IP-Adresse beschränkt, zweitens sind diese zu lang, um sie in diversen generischen iOS-Push-Service-Diensten zu versenden. Um das Problem der IP-Beschränkung zu überwinden, muss also die Datei mit der selben IP-Adresse abgerufen werden. Bei mir zuhause sind diverse iOS/Android-Geräte im WiFi, teilen sich zusammen u.a. mit dem NAS per NAT die IPv4-Adresse des Providers. Bei der Anschaffung des QNAP NAS habe ich bereits darauf geachtet, dass es sich um x86-Hardware handelt, also in dem Falle konkret ein Intel Atom-System mit Docker-Unterstützung und der Möglichkeit den Arbeitsspeicher auf 16GB aufzurüsten.

So schrieb ich eine weitere kleine Ruby-Applikation, die als Container auf dem NAS läuft: Sie empfängt per MQTT die allgemeine YouTube-URL des Videos, ruft damit Streamlink auf um die URL der `.m3u`-Datei zu ermitteln. Diese wird dann per MQTT wieder an den „öffentlichen“ Container geschickt, der sie umschreibt und verkürzt (das Mapping wird dort im Arbeitsspeicher gehalten weil sie relativ kurzlebig sind, also meist ein paar Stunden nach dem Stream bei YouTube nicht mehr verfügbar sind). Die verkürzte URL geht dann per MQTT wieder an den Container auf dem NAS-Zurück, der dann eine externe API von Pushover.com aufruft. Der Anbieter pusht die gekürzte URL dann auf meine Geräte.

Nützlicherweise kann man in der Pushover-App das automatische öffnen von gepushten http-URLs einstellen und so öffnet sich Safari. Da ich aber in VLC den Stream anschauen möchte, weil nur VLC das Abspielen im Hintergrund zulässt, musste ich einen Trick anwenden: Mobile Safari öffnet also die gekürzte URL durch den Aufruf meines URL-Shorteners, der wiederum schickt einen HTTP redirect auf „vlc://…m3u URL…/“ was Safari nach Rückfrage dann an die VLC-App weitergibt. Zwar ziemlich Ghetto, aber es funktioniert.

example

Zuerst übernahm auch der Container auf dem NAS den Download von YouTube: Ein paar TB freier Speicherplatz sind günstiger, als in der Cloud laufend steigende Storage-Kosten in Kauf zu nehmen. Allerdings hat man zuhause ein anderes Problem: Die Stromkosten!

Die aktuelle Lösung schreibt den Stream zuerst auf ein Volume des Cloud-Servers. Daneben läuft Syncthing. Zuhause auf dem NAS läuft ein weiterer Container mit Syncthing und lädt synchronisiert nun die Videos. Abgeschlossene Dateien werden auf dem NAS aus dem Sync-Ordner entfernt und somit auch auf dem Cloudserver automatisch gelöscht.

Das ganze funktioniert auch wunderbar, wenn man den NAS-Server über Nacht in den Ruhezustand schickt: Die Videos sind in der Cloud „gepuffert“ und wandern dann eben am nächsten Morgen auf meine lokalen Festplatten. Im Gegensatz zu einer rsync-Lösung spare ich mir hier auch das Ausrollen von SSH-Zugängen für rsync etc.

Fürs Deployment setze ich einfach zwei docker-compose Konfigurationen ein. Davor source ich jeweils die passenden Variablen und leite mir per ssh den Docker-Unix-Socket der entfernten Maschinen auf das lokale System um.

Der Quellcode liegt auf https://github.com/rmoriz/youtube-watcher allerdings gibt es keine Tests und so gut wie keine Dokumentation.

PS: Bei einem Kunden setze ich seit einiger Zeit Syncthing zur Synchronisation großer Virtualbox-Vagrant-Images ein (60-100GB): Auf einem manuellen Build-Environment wird das Image erstellt, angepasst und dann in einen Syncthing-Ordner geschoben, wovon es dann auf ca 20 weitere Server übertragen bzw. per p2p geteilt und mittels Chef ausgerollt wird. Die Syncthing-Konfiguration wird hierbei auch von Chef erstellt und aktualisiert, sodass jederzeit neue Nodes hinzugefügt oder weggenommen werden können.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

* Die DSGVO-Checkbox ist ein Pflichtfeld

*

Ich stimme zu