Vielleicht kennt ihr das Problem? Ihr kennt eine tolle (und natürlich legale) m3u-Quelle aus dem Internet, mit der ihr Fernsehsender sehen könntet, die nicht bei kodinerds-iptv berücksichtigt sind. Ein Beispiel wären z.B. Fernsehsender in einer Sprache, die nicht bei kodinerds-iptv berücksichtigt wird. Gerne würdet ihr sie in TVHeadend nutzen, nur leider fehlen in der m3u die nötigen Pipe-Angaben für ffmpeg. Nun könntet ihr die m3u herunterladen, formatieren und einbinden. Nur müsstet ihr diese lokale Datei dann auch regelmäßig selbst aktuell halten. Ärgerlich, schließlich gibt es ja schon eine Community, welche die m3u aktuell hält. Die Community wiederum will aber keine Variante mit Pipe pflegen und versteht vielleicht auch das Problem nicht.
Ich möchte hier einmal eine Lösung beschreiben, die ich zusammen mit Bing Copilot vor einigen Monaten entwickelt habe und die für mich wirklich in der Langzeitbeobachtung gut funktioniert. Bei dieser Lösung wird die m3u-Datei regelmäßig automatisch heruntergeladen, mit Pipe-Angabe neu formatiert und lokal gespeichert. Die lokale Datei wird dann in TVHeadend eingebunden.
Natürlich müssen nicht alle so eingebundenen Streams gut funktionieren. Vielleicht kommt beim "Pipen" kein brauchbarer Stream raus oder es gibt geo-blocking. Anders als bei kodinerds-iptv fehlt ein echter Mensch, der einen Stream vorab testet. Aber für diejenigen Streams, für die es klappt, ist dies eine tolle Möglichkeit.
Hier die genauen Details. Zum Konvertieren nutze ich folgendes Python-Script:
import requests
import re
# URL der m3u-Datei
url = "https://bei.spiel/beispiel.m3u"
# Datei herunterladen
response = requests.get(url)
content = response.text
# Funktion zum Extrahieren des Kanalnamens
def extract_channel_name(extinf_line):
match = re.search(r',(.+?)(?: \(|$)', extinf_line)
return match.group(1) if match else "Unknown"
# Zeilen anpassen
def adjust_lines(content):
lines = content.splitlines()
adjusted_lines = []
channel_name = ""
for line in lines:
if line.startswith("#EXTINF"):
channel_name = extract_channel_name(line)
adjusted_lines.append(line)
elif line.startswith("http"):
# Leerzeichen in der URL mit \ maskieren
url = line.strip().replace(" ", "\\ ")
# Kanalname f r ffmpeg-Befehl maskieren
metadata_name = channel_name.replace(" ", "\\ ")
adjusted_lines.append(f"pipe://ffmpeg -loglevel fatal -i {url} -metadata >
else:
adjusted_lines.append(line)
return "\n".join(adjusted_lines)
# Neue Datei erstellen
new_content = adjust_lines(content)
# Datei speichern
with open("/opt/beispiel/beispiel.m3u", "w") as file:
file.write(new_content)
print("Datei erfolgreich angepasst und gespeichert.")
Alles anzeigen
In der Datei muss man in Zeile 5 die URL anpassen und fast unten bei "# Datei speichern" den Pfad für die lokale Datei anpassen.
Je nach Linux-Distribution hat man ggf. noch das Problem, dass Abhängigkeiten zu lösen sind. Unter Ubuntu 24.04 ist dies auf jeden Fall python3.12. Dies zu installieren kann etwas komplexer sein und es gibt mehr als einen Weg. Daher ist dies nicht Teil dieser Anleitung. Im Zweifel fragt die KI eures Vertrauens.
Natürlich kann man auch mehrere derartiger Scripte anlegen und so mehrere m3u-Quellen parallel anpassen.
Damit das Script / die Scripte regelmäßig aktuell gehalten werden, legt man Cronjobs an (mit dem Befehl cronjob -e). Je nachdem, wie eure Lösung wegen der benötigten Python_Version aussieht, können die Zeilen etwas anders aussehen. So sieht es z.B. bei mir aus:
0 * * * * /bin/bash -c 'source /opt/python3.12/bin/activate && python /opt/beispiel/beispiel.py'
@reboot /bin/bash -c 'source /opt/python3.12/bin/activate && python /opt/beispiel/beispiel.py'
Die erste Zeile startet das Script (hier soll es beispiel.py heißen) zu jeder vollen Stunde. Die zweite Zeile startet das Script zusätzlich nach jedem Neustart.
In TVHeadend legt ihr die lokal erstellte Datei dann als IPTV Automatic Network mit der Pfadangabe
(entsprechend anpassen) an.
Falls der Code für das geschulte Auge schrottig sein sollte, bedenkt bitte, dass in erster Linie Bing Copilot der Autor ist. Die Lösung habe ich im Dialog mit der KI entwickelt. Immerhin funktioniert er für mich nun aber doch schon mehrere Monate verlässlich, sodass ich die Lösung nun teilen wollte.