feat: move Amazon Music to extension, fix Deezer download timeout

This commit is contained in:
zarzet committed 2026-03-08 04:15:28 +07:00
1 parent 4a61ffea8d
commit 7d5cb574c6
105 files changed
+285 -1440

No files matched your search

+6 -6
View File
@@ -198,7 +198,7 @@ class FFmpegService {
final trimmedKey = decryptionKey.trim();
if (trimmedKey.isEmpty) return inputPath;
// Amazon encrypted streams are commonly MP4 container with FLAC audio.
// Encrypted streams are commonly MP4 container with FLAC audio.
// Prefer FLAC output to avoid MP4 muxing errors during decrypt copy.
final preferredExt = inputPath.toLowerCase().endsWith('.m4a')
? '.flac'
@@ -217,7 +217,10 @@ class FFmpegService {
required String key,
}) {
final audioMap = mapAudioOnly ? '-map 0:a ' : '';
return '-v error -decryption_key "$key" -i "$inputPath" $audioMap-c copy "$outputPath" -y';
// Force MOV demuxer: -decryption_key is only supported by the MOV/MP4
// demuxer. The input may carry a .flac extension (SAF mode) while actually
// containing an encrypted M4A stream, so we must override auto-detection.
return '-v error -decryption_key "$key" -f mov -i "$inputPath" $audioMap-c copy "$outputPath" -y';
}
final keyCandidates = _buildDecryptionKeyCandidates(trimmedKey);
@@ -627,7 +630,7 @@ class FFmpegService {
return null;
}
static Future<LiveDecryptedStreamResult?> startAmazonLiveDecryptedStream({
static Future<LiveDecryptedStreamResult?> startEncryptedLiveDecryptedStream({
required String encryptedStreamUrl,
required String decryptionKey,
String preferredFormat = 'flac',
@@ -1225,7 +1228,6 @@ class FFmpegService {
final extension = format == 'opus' ? '.opus' : '.mp3';
final outputPath = _buildOutputPath(inputPath, extension);
// Step 1: Convert audio
String command;
if (format == 'opus') {
command =
@@ -1245,7 +1247,6 @@ class FFmpegService {
return null;
}
// Step 2: Embed metadata + cover into the converted file.
// Treat embed failure as conversion failure when metadata/cover was requested.
final hasMetadata = metadata.values.any((v) => v.trim().isNotEmpty);
final hasCover = coverPath != null && coverPath.trim().isNotEmpty;
@@ -1281,7 +1282,6 @@ class FFmpegService {
}
}
// Step 3: Delete original if requested
if (deleteOriginal) {
try {
await File(inputPath).delete();
-4
View File
@@ -104,8 +104,6 @@ class HistoryDatabase {
}
}
// ==================== iOS Path Normalization ====================
/// Pattern to match iOS container paths
/// Example: /var/mobile/Containers/Data/Application/UUID-HERE/Documents/...
static final _iosContainerPattern = RegExp(
@@ -325,8 +323,6 @@ class HistoryDatabase {
};
}
// ==================== CRUD Operations ====================
/// Insert or update a history item
Future<void> upsert(Map<String, dynamic> json) async {
final db = await database;
-5
View File
@@ -403,8 +403,6 @@ class PlatformBridge {
return jsonDecode(result as String) as Map<String, dynamic>;
}
// ==================== LYRICS PROVIDER SETTINGS ====================
/// Sets the lyrics provider order. Providers not in the list are disabled.
static Future<void> setLyricsProviders(List<String> providers) async {
final providersJSON = jsonEncode(providers);
@@ -1060,8 +1058,6 @@ class PlatformBridge {
}
}
// ==================== LOCAL LIBRARY SCANNING ====================
/// Set the directory for caching extracted cover art
static Future<void> setLibraryCoverCacheDir(String cacheDir) async {
_log.i('setLibraryCoverCacheDir: $cacheDir');
@@ -1261,5 +1257,4 @@ class PlatformBridge {
await _channel.invokeMethod('clearStoreCache');
}
// ==================== YOUTUBE / COBALT ====================
}