mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-19 13:08:05 +02:00
Multi-IPTV : chaque fonction utilise la playlist sélectionnée
Le serveur ignorait l'IPTV choisie : direct, VOD, guide, enregistrements, season passes et Auto NBA passaient tous par la playlist la plus récente (ou celle du premier utilisateur pour la capture FFmpeg), et les enregistrements s'affichaient sous toutes les playlists. - get_playlist respecte ?playlist=<id> (prioritaire) puis l'en-tête X-Playlist-Id, avec contrôle du propriétaire (admin : toutes). - Sessions FFmpeg HLS/VOD séparées par IPTV (même stream_id possible) ; le m3u8 propage ?playlist= aux segments, redirections et bascule .ts → HLS du lecteur web aussi. - tv_recordings, season_passes, auto_rules : colonne playlist_id (migrations v4-v6) ; lignes existantes rattachées à la playlist la plus récente de leur propriétaire ; URL de capture avec ?playlist= ; listes filtrées par IPTV ; une règle NBA par IPTV. - Proxy /api/xtream : cache d'allowlist par playlist, paramètre retiré avant l'appel au panneau ; CORS autorise X-Playlist-Id. - Client : AuthedHttp envoie X-Playlist-Id ; XtreamService ajoute ?playlist= aux flux, à l'EPG et aux appels xtream-api (cache distinct). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
29b4e11d13
commit
4f978755fd
15 files changed
+501
-70
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:html' as html;
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@@ -23,9 +24,27 @@ class AuthedHttp {
|
||||
return (t != null && t.isNotEmpty) ? t : null;
|
||||
}
|
||||
|
||||
/// IPTV sélectionnée (persistée par `playlistPersistenceProvider`).
|
||||
///
|
||||
/// Envoyée à chaque appel : sans elle le serveur prenait la playlist la
|
||||
/// plus récente, et guide, enregistrements et Auto NBA visaient la
|
||||
/// mauvaise IPTV quand plusieurs étaient configurées.
|
||||
static String? get selectedPlaylistId {
|
||||
try {
|
||||
final stored = html.window.localStorage['selected_playlist'];
|
||||
if (stored == null) return null;
|
||||
final id = (jsonDecode(stored) as Map<String, dynamic>)['id'];
|
||||
return (id is String && id.isNotEmpty) ? id : null;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Map<String, String> _headers([Map<String, String>? extra]) {
|
||||
final token = _token;
|
||||
final playlistId = selectedPlaylistId;
|
||||
return {
|
||||
if (playlistId != null) 'X-Playlist-Id': playlistId,
|
||||
if (extra != null) ...extra,
|
||||
if (token != null) 'Authorization': 'Bearer $token',
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user