From 60bb10fe4d70a1046042c515d9ddf062905beab2 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 8 Mar 2026 22:43:42 +0100 Subject: [PATCH] fix(recordings): correct stream_url to use real live stream, resolve to absolute URL for FFmpeg, use copy mode, speed up scheduler to 10s --- bin/services/recording_scheduler.dart | 23 +++++++++++-------- .../iptv/widgets/recording_modal.dart | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/bin/services/recording_scheduler.dart b/bin/services/recording_scheduler.dart index bdeb2a7..4539759 100644 --- a/bin/services/recording_scheduler.dart +++ b/bin/services/recording_scheduler.dart @@ -17,8 +17,8 @@ class RecordingScheduler { void start() { print('[RecordingScheduler] Démarrage du planificateur d\'enregistrements TV'); - // Vérifier toutes les minutes - _timer = Timer.periodic(const Duration(minutes: 1), (_) => _checkAndRunRecordings()); + // Vérifier toutes les 10 secondes (pour un démarrage quasi-immédiat) + _timer = Timer.periodic(const Duration(seconds: 10), (_) => _checkAndRunRecordings()); // Lancer une première vérification immédiatement _checkAndRunRecordings(); } @@ -100,16 +100,19 @@ class RecordingScheduler { final fileName = '${safeTitle}_$dateStr.mp4'; final filePath = p.join(recordingsDir.path, fileName); - // FFmpeg arguments pour transcodage H265 - // Utilisation d'un Timeout ou d'une capture directe + // FFmpeg arguments pour enregistrement direct (copie sans transcodage = bien plus rapide) + // On résout l'URL relative en URL absolue pour que FFmpeg puisse y accéder depuis Docker + String streamUrl = recording.streamUrl; + if (streamUrl.startsWith('/')) { + // URL relative → URL absolue (le serveur Xtremflow tourne sur le port 8080 en interne) + streamUrl = 'http://localhost:8080$streamUrl'; + } + final args = [ '-y', // Force overwrite - '-i', recording.streamUrl, // Input stream - '-c:v', 'libx265', // Transcodage Video H.265 (HEVC) - '-preset', 'fast', // Preset d'encodage - '-c:a', 'aac', // Transcodage Audio AAC - '-b:a', '128k', // Bitrate audio - // Arrêter automatiquement après la durée (sécurité supplémentaire en plus du Timer) + '-i', streamUrl, // Input stream (URL absolue) + '-c', 'copy', // Copie directe sans transcodage (beaucoup plus rapide et fiable) + // Arrêter automatiquement après la durée '-t', '${recording.endTime.difference(DateTime.now()).inSeconds}', filePath ]; diff --git a/lib/features/iptv/widgets/recording_modal.dart b/lib/features/iptv/widgets/recording_modal.dart index 3efa61b..516a37e 100644 --- a/lib/features/iptv/widgets/recording_modal.dart +++ b/lib/features/iptv/widgets/recording_modal.dart @@ -50,7 +50,7 @@ class _RecordingModalState extends State { headers: {'Content-Type': 'application/json'}, body: json.encode({ 'channel_id': widget.channel.streamId, - 'stream_url': widget.channel.streamIcon, // Hack temp: Utiliser streamId pour générer l'url via player logic plus tard + 'stream_url': '/api/live/${widget.channel.streamId}.ts', // URL du flux live via le proxy backend 'title': widget.channel.name, 'start_time': _startTime.toIso8601String(), 'end_time': endTime.toIso8601String(),