Aktuelles
Digital Eliteboard - Das Digitale Technik Forum

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

Python Script / Eigene IPTV M3U aus verschiedenen Listen aktualisieren

Registriert
11. Oktober 2009
Beiträge
7.115
Lösungen
1
Reaktionspunkte
8.870
Punkte
393
Ort
Berlin
Ich pflege meine m3u Liste selbst und nutze nur einige Sender aus fremden Listen.

Was nutzt eine Liste mit 10.000 Sendern, die man eh nie anschaut, oder Streams mit unterirdischer Qualität?

Auf einem kleinen Linux-Server habe ich mir die Verwaltung der Gesamt-Playlist eingerichtet. In einem Ordner sind einzelne kleine m3u Dateien, wo ich einzelne Gruppen von Streams geordnet verwalte.
Dann lauft ein Python Script, der die Gesamtliste automatisch aktualisiert, sobald sich eine Datei ändert.

Die Clients ziehen sich bei mir also keine "fremden" Listen, sondern immer nur die eine von meinem Server.

Voraussetzungen:
  • dauerhaft laufender Server (vorzugsweise Linux)
  • Python3 (zusätzliche Module werden hierfür nicht benötigt)
  • Webserver (z.B.: Apache2 oder Nginx)

  • im Ordner /m3u/ liegt die Gesamt-M3U "ott.m3u" und die einzelnen M3U Dateien liegen im Ordner /ott/
  • der Ordner /m3u/ wird per htpasswd geschützt
  • somit sieht der Link zur Gesamt-M3U für die Clients so aus:

Du musst Regestriert sein, um das angehängte Bild zusehen.

Das Python-Script:
Python:
# Script by Smiley007
# Version 1.0 DEB

# crontab -e
# @reboot cd /root/Scripte/ && /usr/bin/python3 ott-akt.py
# Pfad zum Script: /root/Scripte/
# Pfad zur M3U:  /var/www/html/m3u/

import os
import time

# Funktion, um den letzten Änderungszeitpunkt einer Datei zu erhalten
def get_last_modified_time(file_path):
    return os.path.getmtime(file_path)

# Funktion, um den Inhalt einer Datei einzulesen
def read_file(file_path):
    for encoding in ['utf-8', 'ISO-8859-1', 'windows-1252']:
        try:
            with open(file_path, 'r', encoding=encoding) as file:
                return file.read()
        except UnicodeDecodeError:
            continue
    raise UnicodeDecodeError(f"Kann die Datei '{file_path}' nicht dekodieren.")

# Funktion, um den alten Inhalt einer Datei aus der Output-Datei zu entfernen (außer für die spezielle Datei)
def remove_old_content(output_file, input_file_name):
    with open(output_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    inside_file_block = False
    new_lines = []
    for line in lines:
        if line.strip() == f"---{input_file_name} Anfang---":
            inside_file_block = True  # Beginn des Blocks erkennen
        elif line.strip() == f"---{input_file_name} Ende---":
            inside_file_block = False  # Ende des Blocks erkennen
            continue  # Überspringe auch die End-Marker-Zeile
        if not inside_file_block:
            new_lines.append(line)  # Nur Zeilen hinzufügen, die nicht im Block sind

    with open(output_file, 'w', encoding='utf-8') as file:
        file.writelines(new_lines)

# Funktion, um neuen Inhalt zu einer Datei hinzuzufügen (für die spezielle Datei wird der Inhalt an den Anfang gesetzt)
def add_new_file_to_output(output_file, input_file, prepend=False):
    input_file_name = os.path.basename(input_file)
    new_content = read_file(input_file)

    # Entferne den alten Inhalt der Datei
    remove_old_content(output_file, input_file_name)

    # Füge den neuen Inhalt mit den Start- und End-Markern hinzu
    if prepend:
        # Schreibe den Inhalt der free_OTT.m3u ganz nach oben
        with open(output_file, 'r', encoding='utf-8') as file:
            current_content = file.read()

        with open(output_file, 'w', encoding='utf-8') as file:
            file.write(f"---{input_file_name} Anfang---\n")
            file.write(new_content.strip() + "\n")
            file.write(f"---{input_file_name} Ende---\n")
            file.write(current_content)  # Schreibe den restlichen Inhalt wieder rein
    else:
        # Füge den Inhalt der anderen Dateien wie gewohnt am Ende ein
        with open(output_file, 'a', encoding='utf-8') as file:
            file.write(f"---{input_file_name} Anfang---\n")
            file.write(new_content.strip() + "\n")
            file.write(f"---{input_file_name} Ende---\n")

# Funktion zur Überprüfung und Aktualisierung der Output-Datei
def update_output_file(output_file, input_folder, last_modified_times, free_file):
    current_files = set(os.listdir(input_folder))  # Erfasse alle aktuellen Dateien im Ordner
    tracked_files = set(last_modified_times.keys())  # Vorher verfolgte Dateien

    # Überprüfe zuerst auf Änderungen in der free_OTT.m3u, damit diese als erste hinzugefügt wird
    free_file_path = os.path.join(input_folder, free_file)
    if os.path.isfile(free_file_path):
        last_modified = get_last_modified_time(free_file_path)
        if free_file_path not in last_modified_times or last_modified_times[free_file_path] < last_modified:
            add_new_file_to_output(output_file, free_file_path, prepend=True)  # Inhalt immer an den Anfang setzen
            last_modified_times[free_file_path] = last_modified
            print(f"Inhalt von {free_file_path} wurde an den Anfang der Output-Datei gesetzt.")

    # Überprüfe auf Änderungen oder neue Dateien (außer free_OTT.m3u)
    for input_file in current_files:
        # Ignoriere versteckte Dateien und die free_OTT.m3u
        if input_file.startswith('.') or input_file == free_file:
            continue

        input_file_path = os.path.join(input_folder, input_file)

        if os.path.isfile(input_file_path):  # Stelle sicher, dass es sich um eine Datei handelt
            last_modified = get_last_modified_time(input_file_path)
           
            # Wenn sich die Datei geändert hat oder neu ist, aktualisiere den Inhalt
            if input_file_path not in last_modified_times or last_modified_times[input_file_path] < last_modified:
                add_new_file_to_output(output_file, input_file_path)
                last_modified_times[input_file_path] = last_modified
                print(f"Inhalt von {input_file_path} wurde aktualisiert.")

    # Überprüfe auf fehlende Dateien und entferne deren Inhalt
    for tracked_file in tracked_files:
        if os.path.basename(tracked_file) not in current_files:
            input_file_name = os.path.basename(tracked_file)
            remove_old_content(output_file, input_file_name)
            del last_modified_times[tracked_file]  # Entferne die Datei aus den letzten Änderungszeiten
            print(f"Inhalt von {input_file_name} wurde entfernt, da die Datei nicht mehr vorhanden ist.")

if __name__ == "__main__":
    # Verzeichnis, in dem die Input-Dateien liegen
    input_folder = "/var/www/html/m3u/ott"
   
    # Überprüfe, ob der Ordner existiert
    if not os.path.exists(input_folder):
        print(f"Der Ordner '{input_folder}' existiert nicht. Bitte überprüfen Sie den Pfad.")
        exit(1)
   
    # Output-Datei, in der der Inhalt aktualisiert wird
    output_file = "/var/www/html/m3u/ott.m3u"

    # Definiere die Datei, die immer ganz oben stehen soll
    free_file = "/var/www/html/m3u/ott/free_OTT.m3u"

    # Letzte Änderungszeiten speichern
    last_modified_times = {}

    # Überprüfe regelmäßig die Dateien (z.B. alle 10 Sekunden)
    print(f"Überwache den Ordner '{input_folder}' auf neue Dateien...")
    while True:
        update_output_file(output_file, input_folder, last_modified_times, free_file)
        time.sleep(10)  # Wartezeit zwischen den Überprüfungen

Hinweis:
- die verwendeten Pfade des Script und der Dateien/Ordner müssen an eure vorhandene Struktur angepasst werden

Funktionsweise:
  • das Python-Script wird per crontab beim Neustart des Servers gestartet
  • das Script prüft alle 10 Sekunden auf Änderungen
  • die Datei "free_OTT.m3u" enthält frei empfangene Streams
  • der Inhalt der Datei "free_OTT.m3u" ist immer zu Beginn der Gesamt-Liste
  • in der Datei "free_OTT.m3u" gibt es als ersten Eintrag die Quelle des EPG
  • wird im Ordner /ott/ eine M3U hinzugefügt oder entfernt, wird der Inhalt der Gesamt-Liste entsprechend geändert
  • ändert sich der Inhalt einer M3U, wird der Inhalt der Gesamt-Liste entsprechend geändert

Anhang:
In der "m3u-aktualisieren.zip" befinden sich:
- ein angepasstes Python-Script, welches direkt in diesem Ordner funktioniert
  • zwei Beispiel input.m3u
  • eine erzeugte gesamt.m3u

-----------------------

Viel Spass damit

Falls Fehler oder Verbesserungen auftauchen, bitte einfach hier mitteilen
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
Kann ich gut verstehen. Ich nutze auch fast nur M3U Dateien mit den deutschen Sendern ohne den ausländischen Ballast und ohne ewiges Neuladen des Zugangs. Auf Basis von Mac Adressen.

Ich sehe aber keine große Notwendigkeit eines 24-Stunden-Servers dafür. Meist ändert sich fast nie was an den Live-Sendern - natürlich viel an VOD und Serien.

Scripte tauschen mir z.B. die Mac Adressen aus.

Aber Respekt. (y)
 
Danke

naja, ich nutze ganz sicher andere Listen als die Mehrzahl hier und da ändert sich öfter mal was

Daher hatte ich mir die Arbeit gemacht, das einfacher und übersichtlicher zu gestalten.

Anfangs hatte ich immer alles in einer Liste. die war dann irgendwann so lang und übersichtlich, dass es nur noch nervte und immer etliche "Leichen" beinhaltete.

Aber ich denke, auch der ein oder andere hier kann damit was anfangen.

keine große Notwendigkeit eines 24-Stunden-Servers dafür
Der Server ist ja nicht deswegen am Laufen, sondern wurde für Oscam, Smarthome, EPG-Server und noch ein paar Sachen eingerichtet.

Der Langweilt sich eh nur, da kann er auch noch ein paar andere Kleinigkeiten erledigen. Aber Python-Scripte vereinfachen die Arbeit dabei schon sehr effizient Zudem macht es auch immer mehr Spass solche Scripte zu erstellen, auch wenn ich dazu immer auch auf ChatGPT angewiesen bin.
 
Jup, habe gewiss auch schon 10 Scripte mithilfe ChatGPT erstellt. Ohne selber große Ahnung zu haben.
Offtopic Schluss...
 
aber im Grunde muss es ja auch kein Server sein, der 24/7 läuft, ist bei mir nur praktischer das gleich so auf dem Server zu haben

Wenn man was an einer M3U ändert, kann man im Anschluss kurz das Script anstossen und gut.

Dann ist die Gesamt-M3u auch aktuell
 
Hallöchen das hört sich recht interessant an. Hast du die Umgebung auf einem Proxmox installiert?
Kannst nem separaten LXC mit nem Apache2-Server anlegen, ggf. über NGinx drauf routen.
So schwer ists nicht ;-)
Werd ich mir bei Gelegenheit auch mal anschauen. Danke.
 
Top Arbeit. dann werde ich mich mal ans Werk setzen. Proxmox läuft schon paar Jährchen mit OScam, usw. Bin damit recht zufrieden. Cool wäre es, wenn’s dazu gleich die passende HowTo gibt.
 
Zuletzt bearbeitet:
Zurück
Oben