fix: code-review #2 — dedup MagicBytes, auth für check_corrupted, UI-Flag, merged player streams, jq-JSON

This commit is contained in:
Dustin
2026-08-01 16:48:45 +02:00
parent 2d4c7c8b98
commit f00fd445f5
5 changed files with 57 additions and 90 deletions
+2 -44
View File
@@ -6,6 +6,7 @@ import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import '../models/song.dart';
import '../database/db_helper.dart';
import '../utils/audio_validator.dart';
import 'melo_logger.dart';
import '../config/app_config.dart';
@@ -268,7 +269,7 @@ class DownloadService extends ChangeNotifier {
await file.writeAsBytes(mp3Antwort.bodyBytes);
// ── Magic-Byte-Prüfung: Echte MP3-Datei? ──
istKorrupt = !_hatValideMagicBytes(file);
istKorrupt = !hatValideMagicBytes(file);
if (istKorrupt) {
debugPrint('⚠️ Korrupte Datei erkannt (Magic Bytes): $dateiPfad');
MeloLogger().fehler('magic_bytes_check', 'Ungültiger MP3-Header in $dateiPfad');
@@ -336,49 +337,6 @@ class DownloadService extends ChangeNotifier {
}
}
/// Prüft die Magic Bytes einer Audiodatei.
/// MP3: ID3-Tag (49 44 33) oder MPEG-Frame (FF FB, FF FA, FF F3, FF F2)
/// M4A/AAC: ftyp-Box (66 74 79 70)
/// FLAC: fLaC (66 4C 61 43)
/// WAV: RIFF (52 49 46 46)
/// OGG: OggS (4F 67 67 53)
static bool _hatValideMagicBytes(File file) {
try {
if (!file.existsSync()) return false;
final bytes = file.readAsBytesSync().take(16).toList();
if (bytes.length < 4) return false;
// ID3v2 Tag (MP3 mit Metadaten) — Bytes: 49 44 33
if (bytes[0] == 0x49 && bytes[1] == 0x44 && bytes[2] == 0x33) return true;
// MP3 ohne ID3: MPEG Audio Frame Sync (FF FB, FF FA, FF F3, FF F2)
if (bytes[0] == 0xFF && (bytes[1] & 0xFE) == 0xFA) return true; // MPEG v1
if (bytes[0] == 0xFF && bytes[1] == 0xF3) return true; // MPEG v2 / v2.5
if (bytes[0] == 0xFF && bytes[1] == 0xF2) return true; // MPEG v2 / v2.5
// M4A/AAC: ftyp-Box
if (bytes.length >= 8 &&
bytes[4] == 0x66 && bytes[5] == 0x74 &&
bytes[6] == 0x79 && bytes[7] == 0x70) return true;
// FLAC: fLaC
if (bytes[0] == 0x66 && bytes[1] == 0x4C &&
bytes[2] == 0x61 && bytes[3] == 0x43) return true;
// WAV: RIFF
if (bytes[0] == 0x52 && bytes[1] == 0x49 &&
bytes[2] == 0x46 && bytes[3] == 0x46) return true;
// OGG: OggS
if (bytes[0] == 0x4F && bytes[1] == 0x67 &&
bytes[2] == 0x67 && bytes[3] == 0x53) return true;
return false;
} catch (_) {
return false;
}
}
/// HTTP POST mit Retry (exponentieller Backoff)
Future<http.Response> _retryHttpPost(
Uri url, {