feat: serve dynamic M3U playlists for Mopidy robust streaming

This commit is contained in:
2026-09-18 22:56:14 +02:00
parent 4dada6c3b1
commit 5e8c5165a0
2 changed files with 15 additions and 4 deletions
+13 -2
View File
@@ -614,23 +614,34 @@ def podcast_rss(station: str, slug_with_ext: str, request: Request, db: Session
@app.get("/live/{station}") @app.get("/live/{station}")
def live_stream_redirect(station: str, db: Session = Depends(db_session)): def live_stream_redirect(station: str, db: Session = Depends(db_session)):
is_m3u = False
# Usuwamy sztuczne rozszerzenia dodane dla Mopidy # Usuwamy sztuczne rozszerzenia dodane dla Mopidy
if station.endswith(".aac"): if station.endswith(".aac"):
station = station[:-4] station = station[:-4]
elif station.endswith(".mp3"): elif station.endswith(".mp3"):
station = station[:-4] station = station[:-4]
elif station.endswith(".m3u"):
station = station[:-4]
is_m3u = True
if station == "radio357": if station == "radio357":
config_url = db.query(Config).filter_by(key="r357_live_url").first() config_url = db.query(Config).filter_by(key="r357_live_url").first()
target_url = config_url.value if config_url else "https://stream.rcs.revma.com/ye5kghkgcm0uv" target_url = config_url.value if config_url else "https://stream.rcs.revma.com/ye5kghkgcm0uv"
# Doklejamy #.aac dla kompatybilności z Mopidy (GStreamer potrzebuje wskazówki) if is_m3u:
m3u_content = f"#EXTM3U\n#EXTINF:-1,Radio 357\n{target_url}\n"
from fastapi.responses import PlainTextResponse
return PlainTextResponse(content=m3u_content, media_type="audio/x-mpegurl")
if "#" not in target_url: if "#" not in target_url:
target_url += "#.aac" target_url += "#.aac"
return RedirectResponse(url=target_url, status_code=302) return RedirectResponse(url=target_url, status_code=302)
elif station == "rns": elif station == "rns":
config_url = db.query(Config).filter_by(key="rns_live_url").first() config_url = db.query(Config).filter_by(key="rns_live_url").first()
target_url = config_url.value if config_url else "https://stream.rcs.revma.com/4md4m0a0fs8uv" target_url = config_url.value if config_url else "https://stream.rcs.revma.com/4md4m0a0fs8uv"
# Doklejamy #.mp3 dla pełnej zgodności if is_m3u:
m3u_content = f"#EXTM3U\n#EXTINF:-1,Radio Nowy Świat\n{target_url}\n"
from fastapi.responses import PlainTextResponse
return PlainTextResponse(content=m3u_content, media_type="audio/x-mpegurl")
if "#" not in target_url: if "#" not in target_url:
target_url += "#.mp3" target_url += "#.mp3"
return RedirectResponse(url=target_url, status_code=302) return RedirectResponse(url=target_url, status_code=302)
+2 -2
View File
@@ -93,8 +93,8 @@
<li class="nav-item"><a class="nav-link" href="/programs/jazz">Jazz FM</a></li> <li class="nav-item"><a class="nav-link" href="/programs/jazz">Jazz FM</a></li>
</ul> </ul>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<a href="/live/radio357" class="btn btn-outline-info btn-sm" target="_blank" title="Pełny redirect do transmisji. Obie stacje oferują alternatywny link premium dla patronów (bez reklam i z lepszą jakością).">Stream 357</a> <a href="/live/radio357.m3u" class="btn btn-outline-info btn-sm" target="_blank" title="Bezpośredni stream premium Radia 357 (wyższa jakość, brak reklam)">Stream 357</a>
<a href="/live/rns" class="btn btn-outline-info btn-sm" target="_blank" title="Pełny redirect do transmisji. Obie stacje oferują alternatywny link premium dla patronów (bez reklam i z lepszą jakością).">Stream RNŚ</a> <a href="/live/rns.m3u" class="btn btn-outline-info btn-sm" target="_blank" title="Bezpośredni stream premium RNŚ (wyższa jakość, brak reklam)">Stream RNŚ</a>
<a href="/feeds/Podcasts.opml" class="btn btn-outline-warning btn-sm" target="_blank">Master OPML</a> <a href="/feeds/Podcasts.opml" class="btn btn-outline-warning btn-sm" target="_blank">Master OPML</a>
</div> </div>
</div> </div>