- Registriert
- 30. Dezember 2011
- Beiträge
- 16.631
- Lösungen
- 12
- Reaktionspunkte
- 18.532
- Punkte
- 3.740
- Ort
- Im wilden Süden
@matty
Dann müsste man leider mit Dreamboxedit oder ähnlichem Tool die richtige sid zuweisen. Ehrlich gesagt hab ich mich damit noch nicht beschäftigt.
Hier noch ein geändertes vavoo_E2.py mit allen Ländern in Kategorien.
Ihr findet dann im Ordner home eine vavoo_master.m3 und ein Ordner namens playlists.
Um daraus ein Bouquet zu erzeugen führt ihr ca. 3 Minuten nach neustart das aus:
Hab es auf einem Pi am laufen und es sieht sehr gut aus. Hier ein Screenshot von meinem cloudstream am Handy
Edit: die Unterteilung bekommt man nicht mit m3u2e2.sh so hin, dazu solltet ihr das plugin bouquetmakerxtream besser nutzen
Edit: Läuft auch unter TVHEADEND! Nehmt den bouquetmakerextreme zum Auswählen der Länder.
Dann müsste man leider mit Dreamboxedit oder ähnlichem Tool die richtige sid zuweisen. Ehrlich gesagt hab ich mich damit noch nicht beschäftigt.
Hier noch ein geändertes vavoo_E2.py mit allen Ländern in Kategorien.
Code:
###############################################################
PORT = 4323
ADDON_SIG_TTL = 600 # 10 Minuten
###############################################################
import json
import gzip
import requests
import os
from io import BytesIO
import uuid
from flask import Flask, request, Response, abort
import time
import socket
import threading
# ---------------- LÄNDER ----------------
REGIONS = [
{"language": "nl", "region": "BE"},
]
GEOIP_URL = "https://www.vavoo.tv/geoip"
PING_URL = "https://www.vavoo.tv/api/app/ping"
CATALOG_URL = "https://vavoo.to/mediahubmx-catalog.json"
RESOLVE_URL = "https://vavoo.to/mediahubmx-resolve.json"
LANGUAGE = "de"
REGION = "DE"
HEADERS = {
"accept": "*/*",
"user-agent": "electron-fetch/1.0 electron (+https://github.com/arantes555/electron-fetch)",
"Accept-Language": LANGUAGE,
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
}
def decode_response(resp):
if resp.content[:2] == b'\x1f\x8b':
return json.loads(gzip.decompress(resp.content))
return resp.json()
session = requests.Session()
session.headers.update(HEADERS)
# ---------------- GEO + INITIAL PING ----------------
r_geo = session.get(GEOIP_URL)
r_geo.raise_for_status()
geo_data = decode_response(r_geo)
unique_id = str(uuid.uuid4())
current_timestamp = int(time.time() * 1000)
initial_payload = {
"reason": "app-focus",
"locale": "de",
"theme": "dark",
"metadata": {
"device": {"type": "desktop", "uniqueId": unique_id},
"os": {"name": "win32", "version": "Windows 10 Pro", "abis": ["x64"], "host": "Lenovo"},
"app": {"platform": "electron"},
"version": {"package": "tv.vavoo.app", "binary": "3.1.8", "js": "3.1.8"},
},
"appFocusTime": 0,
"playerActive": False,
"playDuration": 0,
"devMode": False,
"hasAddon": True,
"castConnected": False,
"package": "tv.vavoo.app",
"version": "3.1.8",
"process": "app",
"firstAppStart": current_timestamp,
"lastAppStart": current_timestamp,
"ipLocation": None,
"adblockEnabled": True,
"proxy": {"supported": ["ss"], "engine": "Mu", "enabled": False, "autoServer": True},
"iap": {"supported": False},
}
r1 = session.post(PING_URL, json=initial_payload)
r1.raise_for_status()
data1 = decode_response(r1)
# ---------------- ADDON SIG MANAGEMENT ----------------
addon_sig_lock = threading.Lock()
addon_sig_data = {
"sig": data1.get("addonSig"),
"ts": time.time()
}
def refresh_addon_sig_if_needed(force=False):
with addon_sig_lock:
now = time.time()
if not force and now - addon_sig_data["ts"] < ADDON_SIG_TTL:
return addon_sig_data["sig"]
payload = initial_payload.copy()
payload["lastAppStart"] = int(time.time() * 1000)
r = session.post(PING_URL, json=payload)
r.raise_for_status()
data = decode_response(r)
sig = data.get("addonSig")
if not sig:
raise RuntimeError("No addonSig received")
addon_sig_data["sig"] = sig
addon_sig_data["ts"] = now
print("[✓] addonSig refreshed")
return sig
# ---------------- CATALOG LOAD (MULTI-REGION) ----------------
items_by_region = {}
for entry in REGIONS:
LANGUAGE = entry["language"]
REGION = entry["region"]
region_key = f"{LANGUAGE}-{REGION}"
print(f"[+] Lade Katalog für {region_key}")
catalog_headers = {
"content-type": "application/json; charset=utf-8",
"mediahubmx-signature": addon_sig_data["sig"],
"user-agent": "MediaHubMX/2",
"accept": "*/*",
"Accept-Language": LANGUAGE,
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
}
cursor = None
while True:
catalog_payload = {
"language": LANGUAGE,
"region": REGION,
"catalogId": "iptv",
"id": "iptv",
"adult": False,
"search": "",
"sort": "",
"filter": {},
"cursor": cursor,
"clientVersion": "3.0.2"
}
r_catalog = session.post(CATALOG_URL, json=catalog_payload, headers=catalog_headers)
r_catalog.raise_for_status()
catalog_data = decode_response(r_catalog)
for item in catalog_data.get("items", []):
if item.get("type") == "iptv":
items_by_region.setdefault(region_key, []).append({
"id": item["ids"]["id"],
"url": item["url"],
"name": item["name"],
"group": item["group"],
"logo": item["logo"],
"language": LANGUAGE,
"region": REGION
})
cursor = catalog_data.get("nextCursor")
if not cursor:
break
print(f"[✓] Gesamtanzahl IPTV-Sender: {sum(len(v) for v in items_by_region.values())}")
# ---------------- M3U SAVE (MULTI-FILE) ----------------
LOCAL_IP = "127.0.0.1"
def get_local_ip():
return LOCAL_IP
# Unterordner erstellen
PLAYLIST_DIR = "playlists"
os.makedirs(PLAYLIST_DIR, exist_ok=True)
def save_m3u_files():
local_ip = get_local_ip()
for region_key, items in items_by_region.items():
filename = os.path.join(PLAYLIST_DIR, f"vavoo_{region_key}.m3u")
m3u = "#EXTM3U\n"
for item in items:
m3u += (
f'#EXTINF:-1 tvg-id="{item["id"]}" '
f'tvg-name="{item["name"]}" '
f'tvg-logo="{item["logo"]}" '
f'group-title="{item["group"]} ({item["region"]})",{item["name"]}\n'
)
m3u += f"http://{local_ip}:{PORT}/vavoo?channel={item['id']}\n"
with open(filename, "w", encoding="utf-8") as f:
f.write(m3u)
print(f"[✓] {filename} geschrieben")
def save_master_m3u():
master = "#EXTM3U\n"
for region_key in items_by_region.keys():
filename = f"playlists/vavoo_{region_key}.m3u"
master += f'#EXTINF:-1 group-title="Master",{region_key}\n'
master += f"{filename}\n"
with open("vavoo_master.m3u", "w", encoding="utf-8") as f:
f.write(master)
print("[✓] vavoo_master.m3u geschrieben")
save_m3u_files()
save_master_m3u()
# ---------------- FLASK APP ----------------
app = Flask(__name__)
@app.route("/vavoo")
def stream_proxy():
channel_id = request.args.get("channel")
if not channel_id:
abort(400)
channel = None
for region_items in items_by_region.values():
for i in region_items:
if i["id"] == channel_id:
channel = i
break
if not channel:
abort(404)
try:
sig = refresh_addon_sig_if_needed()
except Exception as e:
abort(502, str(e))
resolve_headers = {
"content-type": "application/json; charset=utf-8",
"mediahubmx-signature": sig,
"user-agent": "MediaHubMX/2",
"accept": "*/*",
"Accept-Language": channel["language"],
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
}
resolve_payload = {
"language": channel["language"],
"region": channel["region"],
"url": channel["url"],
"clientVersion": "3.0.2"
}
r_resolve = session.post(RESOLVE_URL, json=resolve_payload, headers=resolve_headers)
if r_resolve.status_code == 403:
sig = refresh_addon_sig_if_needed(force=True)
resolve_headers["mediahubmx-signature"] = sig
r_resolve = session.post(RESOLVE_URL, json=resolve_payload, headers=resolve_headers)
r_resolve.raise_for_status()
result = decode_response(r_resolve)
if result:
return Response(status=302, headers={"Location": result[0]["url"]})
abort(404)
# ---------------- ALL-IN-ONE PLAYLIST ----------------
@app.route("/playlist.m3u")
def playlist():
local_ip = get_local_ip()
m3u = "#EXTM3U\n"
for region_items in items_by_region.values():
for item in region_items:
m3u += (
f'#EXTINF:-1 tvg-id="{item["id"]}" '
f'tvg-name="{item["name"]}" '
f'tvg-logo="{item["logo"]}" '
f'group-title="{item["group"]} ({item["region"]})",{item["name"]}\n'
)
m3u += f"http://{local_ip}:{PORT}/vavoo?channel={item['id']}\n"
return Response(m3u, mimetype="application/x-mpegURL")
# ---------------- MASTER PLAYLIST ----------------
@app.route("/master.m3u")
def master_playlist():
try:
with open("vavoo_master.m3u", "r", encoding="utf-8") as f:
content = f.read()
return Response(content, mimetype="application/x-mpegURL")
except FileNotFoundError:
return Response("#EXTM3U\n# Master playlist not found\n", mimetype="application/x-mpegURL")
# ---------------- START SERVER ----------------
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
Um daraus ein Bouquet zu erzeugen führt ihr ca. 3 Minuten nach neustart das aus:
Code:
cd /home
wget http://127.0.0.1:4323/playlist.m3u
./m3u2e2.sh playlist.m3u vavoo-int
Hab es auf einem Pi am laufen und es sieht sehr gut aus. Hier ein Screenshot von meinem cloudstream am Handy
Edit: die Unterteilung bekommt man nicht mit m3u2e2.sh so hin, dazu solltet ihr das plugin bouquetmakerxtream besser nutzen
Edit: Läuft auch unter TVHEADEND! Nehmt den bouquetmakerextreme zum Auswählen der Länder.
Anhänge
Du musst angemeldet sein, um die Anhangsliste zu sehen.
Zuletzt bearbeitet: