diff --git a/android/app/libs/ffmpeg-kit-with-lame.aar b/android/app/libs/ffmpeg-kit-with-lame.aar deleted file mode 100644 index 828ad8be..00000000 Binary files a/android/app/libs/ffmpeg-kit-with-lame.aar and /dev/null differ diff --git a/android/app/libs/smart-exception-common-0.2.1.jar b/android/app/libs/smart-exception-common-0.2.1.jar deleted file mode 100644 index 624d64d7..00000000 Binary files a/android/app/libs/smart-exception-common-0.2.1.jar and /dev/null differ diff --git a/android/app/libs/smart-exception-java-0.2.1.jar b/android/app/libs/smart-exception-java-0.2.1.jar deleted file mode 100644 index 2a16b315..00000000 Binary files a/android/app/libs/smart-exception-java-0.2.1.jar and /dev/null differ diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt index 27763a7e..e76f8cb9 100644 --- a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt @@ -7,8 +7,6 @@ import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterShellArgs import io.flutter.plugin.common.MethodChannel import gobackend.Gobackend -import com.arthenica.ffmpegkit.FFmpegKit -import com.arthenica.ffmpegkit.ReturnCode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob @@ -18,7 +16,6 @@ import java.util.Locale class MainActivity: FlutterActivity() { private val CHANNEL = "com.zarz.spotiflac/backend" - private val FFMPEG_CHANNEL = "com.zarz.spotiflac/ffmpeg" private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main) companion object { @@ -901,37 +898,5 @@ class MainActivity: FlutterActivity() { } } } - - // FFmpeg method channel - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, FFMPEG_CHANNEL).setMethodCallHandler { call, result -> - scope.launch { - try { - when (call.method) { - "execute" -> { - val command = call.argument("command") ?: "" - val session = withContext(Dispatchers.IO) { - FFmpegKit.execute(command) - } - val returnCode = session.returnCode - val output = session.output ?: "" - result.success(mapOf( - "success" to ReturnCode.isSuccess(returnCode), - "returnCode" to (returnCode?.value ?: -1), - "output" to output - )) - } - "getVersion" -> { - val session = withContext(Dispatchers.IO) { - FFmpegKit.execute("-version") - } - result.success(session.output ?: "unknown") - } - else -> result.notImplemented() - } - } catch (e: Exception) { - result.error("FFMPEG_ERROR", e.message, null) - } - } - } } } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index be159c0e..f5a706f4 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -3394,35 +3394,65 @@ abstract class AppLocalizations { /// **'24-bit / up to 192kHz'** String get qualityHiResFlacMaxSubtitle; - /// Quality option - MP3 lossy format + /// Quality option - lossy format (MP3/Opus) /// /// In en, this message translates to: - /// **'MP3'** - String get qualityMp3; + /// **'Lossy'** + String get qualityLossy; - /// Technical spec for MP3 + /// Technical spec for lossy MP3 /// /// In en, this message translates to: - /// **'320kbps (converted from FLAC)'** - String get qualityMp3Subtitle; + /// **'MP3 320kbps (converted from FLAC)'** + String get qualityLossyMp3Subtitle; - /// Setting - enable MP3 quality option + /// Technical spec for lossy Opus /// /// In en, this message translates to: - /// **'Enable MP3 Option'** - String get enableMp3Option; + /// **'Opus 128kbps (converted from FLAC)'** + String get qualityLossyOpusSubtitle; - /// Subtitle when MP3 is enabled + /// Setting - enable lossy quality option /// /// In en, this message translates to: - /// **'MP3 quality option is available'** - String get enableMp3OptionSubtitleOn; + /// **'Enable Lossy Option'** + String get enableLossyOption; - /// Subtitle when MP3 is disabled + /// Subtitle when lossy is enabled /// /// In en, this message translates to: - /// **'Downloads FLAC then converts to 320kbps MP3'** - String get enableMp3OptionSubtitleOff; + /// **'Lossy quality option is available'** + String get enableLossyOptionSubtitleOn; + + /// Subtitle when lossy is disabled + /// + /// In en, this message translates to: + /// **'Downloads FLAC then converts to lossy format'** + String get enableLossyOptionSubtitleOff; + + /// Setting - choose lossy format + /// + /// In en, this message translates to: + /// **'Lossy Format'** + String get lossyFormat; + + /// Description for lossy format picker + /// + /// In en, this message translates to: + /// **'Choose the lossy format for conversion'** + String get lossyFormatDescription; + + /// MP3 format description + /// + /// In en, this message translates to: + /// **'320kbps, best compatibility'** + String get lossyFormatMp3Subtitle; + + /// Opus format description + /// + /// In en, this message translates to: + /// **'128kbps, better quality at smaller size'** + String get lossyFormatOpusSubtitle; /// Note about quality availability /// diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 0cbbbefa..a6743f05 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -1869,20 +1869,36 @@ class AppLocalizationsDe extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 9eff2a37..0a0c1dc1 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsEn extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 0a47926d..e735cb79 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsEs extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 74b8e6c0..bc34507a 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsFr extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_hi.dart b/lib/l10n/app_localizations_hi.dart index 9a690ec5..73b1918e 100644 --- a/lib/l10n/app_localizations_hi.dart +++ b/lib/l10n/app_localizations_hi.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsHi extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 3fa36e0e..118d3878 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -1868,20 +1868,36 @@ class AppLocalizationsId extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / hingga 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (konversi dari FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Aktifkan Opsi MP3'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'Opsi kualitas MP3 tersedia'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Unduh FLAC lalu konversi ke MP3 320kbps'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index 76d048b8..a807e41a 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsJa extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / 最大 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index fed8e128..c7c0b798 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsKo extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index eecb34ae..cd312e55 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsNl extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index 4a1d3424..20e466b7 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsPt extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 15ad6280..95884187 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -1894,20 +1894,36 @@ class AppLocalizationsRu extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-бит / до 192кГц'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_tr.dart b/lib/l10n/app_localizations_tr.dart index a1b0f73a..c4a9ebfb 100644 --- a/lib/l10n/app_localizations_tr.dart +++ b/lib/l10n/app_localizations_tr.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsTr extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 6b15a933..390fda9e 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -1856,20 +1856,36 @@ class AppLocalizationsZh extends AppLocalizations { String get qualityHiResFlacMaxSubtitle => '24-bit / up to 192kHz'; @override - String get qualityMp3 => 'MP3'; + String get qualityLossy => 'Lossy'; @override - String get qualityMp3Subtitle => '320kbps (converted from FLAC)'; + String get qualityLossyMp3Subtitle => 'MP3 320kbps (converted from FLAC)'; @override - String get enableMp3Option => 'Enable MP3 Option'; + String get qualityLossyOpusSubtitle => 'Opus 128kbps (converted from FLAC)'; @override - String get enableMp3OptionSubtitleOn => 'MP3 quality option is available'; + String get enableLossyOption => 'Enable Lossy Option'; @override - String get enableMp3OptionSubtitleOff => - 'Downloads FLAC then converts to 320kbps MP3'; + String get enableLossyOptionSubtitleOn => 'Lossy quality option is available'; + + @override + String get enableLossyOptionSubtitleOff => + 'Downloads FLAC then converts to lossy format'; + + @override + String get lossyFormat => 'Lossy Format'; + + @override + String get lossyFormatDescription => 'Choose the lossy format for conversion'; + + @override + String get lossyFormatMp3Subtitle => '320kbps, best compatibility'; + + @override + String get lossyFormatOpusSubtitle => + '128kbps, better quality at smaller size'; @override String get qualityNote => diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 4dd87f36..4d312b09 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1373,16 +1373,26 @@ "@qualityHiResFlacMax": {"description": "Quality option - maximum resolution FLAC"}, "qualityHiResFlacMaxSubtitle": "24-bit / up to 192kHz", "@qualityHiResFlacMaxSubtitle": {"description": "Technical spec for hi-res max"}, - "qualityMp3": "MP3", - "@qualityMp3": {"description": "Quality option - MP3 lossy format"}, - "qualityMp3Subtitle": "320kbps (converted from FLAC)", - "@qualityMp3Subtitle": {"description": "Technical spec for MP3"}, - "enableMp3Option": "Enable MP3 Option", - "@enableMp3Option": {"description": "Setting - enable MP3 quality option"}, - "enableMp3OptionSubtitleOn": "MP3 quality option is available", - "@enableMp3OptionSubtitleOn": {"description": "Subtitle when MP3 is enabled"}, - "enableMp3OptionSubtitleOff": "Downloads FLAC then converts to 320kbps MP3", - "@enableMp3OptionSubtitleOff": {"description": "Subtitle when MP3 is disabled"}, + "qualityLossy": "Lossy", + "@qualityLossy": {"description": "Quality option - lossy format (MP3/Opus)"}, + "qualityLossyMp3Subtitle": "MP3 320kbps (converted from FLAC)", + "@qualityLossyMp3Subtitle": {"description": "Technical spec for lossy MP3"}, + "qualityLossyOpusSubtitle": "Opus 128kbps (converted from FLAC)", + "@qualityLossyOpusSubtitle": {"description": "Technical spec for lossy Opus"}, + "enableLossyOption": "Enable Lossy Option", + "@enableLossyOption": {"description": "Setting - enable lossy quality option"}, + "enableLossyOptionSubtitleOn": "Lossy quality option is available", + "@enableLossyOptionSubtitleOn": {"description": "Subtitle when lossy is enabled"}, + "enableLossyOptionSubtitleOff": "Downloads FLAC then converts to lossy format", + "@enableLossyOptionSubtitleOff": {"description": "Subtitle when lossy is disabled"}, + "lossyFormat": "Lossy Format", + "@lossyFormat": {"description": "Setting - choose lossy format"}, + "lossyFormatDescription": "Choose the lossy format for conversion", + "@lossyFormatDescription": {"description": "Description for lossy format picker"}, + "lossyFormatMp3Subtitle": "320kbps, best compatibility", + "@lossyFormatMp3Subtitle": {"description": "MP3 format description"}, + "lossyFormatOpusSubtitle": "128kbps, better quality at smaller size", + "@lossyFormatOpusSubtitle": {"description": "Opus format description"}, "qualityNote": "Actual quality depends on track availability from the service", "@qualityNote": {"description": "Note about quality availability"}, diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 892fd528..b3e436ca 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -31,7 +31,8 @@ class AppSettings { final String albumFolderStructure; final bool showExtensionStore; final String locale; - final bool enableMp3Option; + final bool enableLossyOption; + final String lossyFormat; final String lyricsMode; const AppSettings({ @@ -62,7 +63,8 @@ class AppSettings { this.albumFolderStructure = 'artist_album', this.showExtensionStore = true, this.locale = 'system', - this.enableMp3Option = false, + this.enableLossyOption = false, + this.lossyFormat = 'mp3', this.lyricsMode = 'embed', }); @@ -95,7 +97,8 @@ class AppSettings { String? albumFolderStructure, bool? showExtensionStore, String? locale, - bool? enableMp3Option, + bool? enableLossyOption, + String? lossyFormat, String? lyricsMode, }) { return AppSettings( @@ -126,7 +129,8 @@ class AppSettings { albumFolderStructure: albumFolderStructure ?? this.albumFolderStructure, showExtensionStore: showExtensionStore ?? this.showExtensionStore, locale: locale ?? this.locale, - enableMp3Option: enableMp3Option ?? this.enableMp3Option, + enableLossyOption: enableLossyOption ?? this.enableLossyOption, + lossyFormat: lossyFormat ?? this.lossyFormat, lyricsMode: lyricsMode ?? this.lyricsMode, ); } diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index 5225c989..34af547e 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -36,7 +36,8 @@ AppSettings _$AppSettingsFromJson(Map json) => AppSettings( json['albumFolderStructure'] as String? ?? 'artist_album', showExtensionStore: json['showExtensionStore'] as bool? ?? true, locale: json['locale'] as String? ?? 'system', - enableMp3Option: json['enableMp3Option'] as bool? ?? false, + enableLossyOption: json['enableLossyOption'] as bool? ?? false, + lossyFormat: json['lossyFormat'] as String? ?? 'mp3', lyricsMode: json['lyricsMode'] as String? ?? 'embed', ); @@ -69,6 +70,7 @@ Map _$AppSettingsToJson(AppSettings instance) => 'albumFolderStructure': instance.albumFolderStructure, 'showExtensionStore': instance.showExtensionStore, 'locale': instance.locale, - 'enableMp3Option': instance.enableMp3Option, + 'enableLossyOption': instance.enableLossyOption, + 'lossyFormat': instance.lossyFormat, 'lyricsMode': instance.lyricsMode, }; diff --git a/lib/providers/download_queue_provider.dart b/lib/providers/download_queue_provider.dart index 99927349..ad9d5c6d 100644 --- a/lib/providers/download_queue_provider.dart +++ b/lib/providers/download_queue_provider.dart @@ -1668,9 +1668,9 @@ class DownloadQueueNotifier extends Notifier { final quality = item.qualityOverride ?? state.audioQuality; - // For MP3, we need to download FLAC first then convert - // Servers don't support MP3 quality directly - final downloadQuality = quality == 'MP3' ? 'LOSSLESS' : quality; + // For LOSSY, we need to download FLAC first then convert + // Servers don't support lossy quality directly + final downloadQuality = quality == 'LOSSY' ? 'LOSSLESS' : quality; // Fetch extended metadata (genre, label) from Deezer if available String? genre; @@ -1721,7 +1721,7 @@ class DownloadQueueNotifier extends Notifier { if (useExtensions) { _log.d('Using extension providers for download'); _log.d( - 'Quality: $quality${item.qualityOverride != null ? ' (override)' : ''}${quality == 'MP3' ? ' (downloading as LOSSLESS for conversion)' : ''}', + 'Quality: $quality${item.qualityOverride != null ? ' (override)' : ''}${quality == 'LOSSY' ? ' (downloading as LOSSLESS for conversion)' : ''}', ); _log.d('Output dir: $outputDir'); result = await PlatformBridge.downloadWithExtensions( @@ -1748,7 +1748,7 @@ class DownloadQueueNotifier extends Notifier { } else if (state.autoFallback) { _log.d('Using auto-fallback mode'); _log.d( - 'Quality: $quality${item.qualityOverride != null ? ' (override)' : ''}${quality == 'MP3' ? ' (downloading as LOSSLESS for conversion)' : ''}', + 'Quality: $quality${item.qualityOverride != null ? ' (override)' : ''}${quality == 'LOSSY' ? ' (downloading as LOSSLESS for conversion)' : ''}', ); _log.d('Output dir: $outputDir'); result = await PlatformBridge.downloadWithFallback( @@ -1969,11 +1969,12 @@ class DownloadQueueNotifier extends Notifier { return; } - if (quality == 'MP3' && filePath != null && filePath.endsWith('.flac')) { + if (quality == 'LOSSY' && filePath != null && filePath.endsWith('.flac')) { if (wasExisting) { - _log.i('MP3 requested but existing FLAC found - skipping conversion to preserve original file'); + _log.i('Lossy requested but existing FLAC found - skipping conversion to preserve original file'); } else { - _log.i('MP3 quality selected, converting FLAC to MP3...'); + final lossyFormat = settings.lossyFormat; + _log.i('Lossy quality selected, converting FLAC to $lossyFormat...'); updateItemStatus( item.id, DownloadStatus.downloading, @@ -1981,40 +1982,43 @@ class DownloadQueueNotifier extends Notifier { ); try { - final mp3Path = await FFmpegService.convertFlacToMp3( + final convertedPath = await FFmpegService.convertFlacToLossy( filePath, - bitrate: '320k', + format: lossyFormat, deleteOriginal: true, ); - if (mp3Path != null) { - filePath = mp3Path; - actualQuality = 'MP3 320kbps'; - _log.i('Successfully converted to MP3: $mp3Path'); + if (convertedPath != null) { + filePath = convertedPath; + actualQuality = lossyFormat == 'opus' ? 'Opus 128kbps' : 'MP3 320kbps'; + _log.i('Successfully converted to $lossyFormat: $convertedPath'); - _log.i('Embedding metadata to MP3...'); - updateItemStatus( - item.id, - DownloadStatus.downloading, - progress: 0.99, - ); - - final mp3BackendGenre = result['genre'] as String?; - final mp3BackendLabel = result['label'] as String?; - final mp3BackendCopyright = result['copyright'] as String?; - - await _embedMetadataToMp3( - mp3Path, - trackToDownload, - genre: mp3BackendGenre ?? genre, - label: mp3BackendLabel ?? label, - copyright: mp3BackendCopyright, - ); + // Only embed metadata for MP3 (Opus uses Vorbis comments which are preserved) + if (lossyFormat == 'mp3') { + _log.i('Embedding metadata to MP3...'); + updateItemStatus( + item.id, + DownloadStatus.downloading, + progress: 0.99, + ); + + final mp3BackendGenre = result['genre'] as String?; + final mp3BackendLabel = result['label'] as String?; + final mp3BackendCopyright = result['copyright'] as String?; + + await _embedMetadataToMp3( + convertedPath, + trackToDownload, + genre: mp3BackendGenre ?? genre, + label: mp3BackendLabel ?? label, + copyright: mp3BackendCopyright, + ); + } } else { - _log.w('MP3 conversion failed, keeping FLAC file'); + _log.w('$lossyFormat conversion failed, keeping FLAC file'); } } catch (e) { - _log.e('MP3 conversion error: $e, keeping FLAC file'); + _log.e('Lossy conversion error: $e, keeping FLAC file'); } } } diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index b7c9687f..9b91272a 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -231,14 +231,19 @@ class SettingsNotifier extends Notifier { _saveSettings(); } - void setEnableMp3Option(bool enabled) { - state = state.copyWith(enableMp3Option: enabled); - // If MP3 is disabled and current quality is MP3, reset to LOSSLESS - if (!enabled && state.audioQuality == 'MP3') { + void setEnableLossyOption(bool enabled) { + state = state.copyWith(enableLossyOption: enabled); + // If Lossy is disabled and current quality is LOSSY, reset to LOSSLESS + if (!enabled && state.audioQuality == 'LOSSY') { state = state.copyWith(audioQuality: 'LOSSLESS'); } _saveSettings(); } + + void setLossyFormat(String format) { + state = state.copyWith(lossyFormat: format); + _saveSettings(); + } } final settingsProvider = NotifierProvider( diff --git a/lib/screens/settings/download_settings_page.dart b/lib/screens/settings/download_settings_page.dart index 2182bd76..63c186c2 100644 --- a/lib/screens/settings/download_settings_page.dart +++ b/lib/screens/settings/download_settings_page.dart @@ -101,15 +101,24 @@ class DownloadSettingsPage extends ConsumerWidget { ), SettingsSwitchItem( icon: Icons.audiotrack, - title: context.l10n.enableMp3Option, - subtitle: settings.enableMp3Option - ? context.l10n.enableMp3OptionSubtitleOn - : context.l10n.enableMp3OptionSubtitleOff, - value: settings.enableMp3Option, + title: context.l10n.enableLossyOption, + subtitle: settings.enableLossyOption + ? context.l10n.enableLossyOptionSubtitleOn + : context.l10n.enableLossyOptionSubtitleOff, + value: settings.enableLossyOption, onChanged: (value) => ref .read(settingsProvider.notifier) - .setEnableMp3Option(value), + .setEnableLossyOption(value), ), + if (settings.enableLossyOption) + SettingsItem( + icon: Icons.tune, + title: context.l10n.lossyFormat, + subtitle: settings.lossyFormat == 'opus' + ? 'Opus 128kbps' + : 'MP3 320kbps', + onTap: () => _showLossyFormatPicker(context, ref, settings.lossyFormat), + ), if (!settings.askQualityBeforeDownload && isBuiltInService) ...[ _QualityOption( title: context.l10n.qualityFlacLossless, @@ -134,16 +143,18 @@ class DownloadSettingsPage extends ConsumerWidget { onTap: () => ref .read(settingsProvider.notifier) .setAudioQuality('HI_RES_LOSSLESS'), - showDivider: settings.enableMp3Option, + showDivider: settings.enableLossyOption, ), - if (settings.enableMp3Option) + if (settings.enableLossyOption) _QualityOption( - title: context.l10n.qualityMp3, - subtitle: context.l10n.qualityMp3Subtitle, - isSelected: settings.audioQuality == 'MP3', + title: context.l10n.qualityLossy, + subtitle: settings.lossyFormat == 'opus' + ? context.l10n.qualityLossyOpusSubtitle + : context.l10n.qualityLossyMp3Subtitle, + isSelected: settings.audioQuality == 'LOSSY', onTap: () => ref .read(settingsProvider.notifier) - .setAudioQuality('MP3'), + .setAudioQuality('LOSSY'), showDivider: false, ), ], @@ -722,6 +733,68 @@ class DownloadSettingsPage extends ConsumerWidget { ); } + void _showLossyFormatPicker( + BuildContext context, + WidgetRef ref, + String current, + ) { + final colorScheme = Theme.of(context).colorScheme; + showModalBottomSheet( + context: context, + backgroundColor: colorScheme.surfaceContainerHigh, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(28)), + ), + builder: (context) => SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(24, 24, 24, 8), + child: Text( + context.l10n.lossyFormat, + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(24, 0, 24, 16), + child: Text( + context.l10n.lossyFormatDescription, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: colorScheme.onSurfaceVariant, + ), + ), + ), + ListTile( + leading: const Icon(Icons.audiotrack), + title: const Text('MP3'), + subtitle: Text(context.l10n.lossyFormatMp3Subtitle), + trailing: current == 'mp3' ? const Icon(Icons.check) : null, + onTap: () { + ref.read(settingsProvider.notifier).setLossyFormat('mp3'); + Navigator.pop(context); + }, + ), + ListTile( + leading: const Icon(Icons.graphic_eq), + title: const Text('Opus'), + subtitle: Text(context.l10n.lossyFormatOpusSubtitle), + trailing: current == 'opus' ? const Icon(Icons.check) : null, + onTap: () { + ref.read(settingsProvider.notifier).setLossyFormat('opus'); + Navigator.pop(context); + }, + ), + const SizedBox(height: 16), + ], + ), + ), + ); + } + void _showFolderOrganizationPicker( BuildContext context, WidgetRef ref, diff --git a/lib/services/ffmpeg_service.dart b/lib/services/ffmpeg_service.dart index 6243d41e..22d4e272 100644 --- a/lib/services/ffmpeg_service.dart +++ b/lib/services/ffmpeg_service.dart @@ -1,23 +1,25 @@ import 'dart:io'; -import 'package:flutter/services.dart'; +import 'package:ffmpeg_kit_flutter_new_audio/ffmpeg_kit.dart'; +import 'package:ffmpeg_kit_flutter_new_audio/ffmpeg_kit_config.dart'; +import 'package:ffmpeg_kit_flutter_new_audio/return_code.dart'; import 'package:path_provider/path_provider.dart'; import 'package:spotiflac_android/utils/logger.dart'; final _log = AppLogger('FFmpeg'); /// FFmpeg service for audio conversion and remuxing -/// Uses native MethodChannel to call FFmpegKit from local AAR +/// Uses ffmpeg_kit_flutter_new_audio plugin class FFmpegService { - static const _channel = MethodChannel('com.zarz.spotiflac/ffmpeg'); - static Future _execute(String command) async { try { - final result = await _channel.invokeMethod('execute', {'command': command}); - final map = Map.from(result); + final session = await FFmpegKit.execute(command); + final returnCode = await session.getReturnCode(); + final output = await session.getOutput() ?? ''; + return FFmpegResult( - success: map['success'] as bool, - returnCode: map['returnCode'] as int, - output: map['output'] as String, + success: ReturnCode.isSuccess(returnCode), + returnCode: returnCode?.getValue() ?? -1, + output: output, ); } catch (e) { _log.e('FFmpeg execute error: $e'); @@ -69,6 +71,48 @@ class FFmpegService { return null; } + static Future convertFlacToOpus( + String inputPath, { + String bitrate = '128k', + bool deleteOriginal = true, + }) async { + final outputPath = inputPath.replaceAll('.flac', '.opus'); + + // Opus in OGG container with VBR + final command = + '-i "$inputPath" -codec:a libopus -b:a $bitrate -vbr on -compression_level 10 -map 0:a -map_metadata 0 "$outputPath" -y'; + + final result = await _execute(command); + + if (result.success) { + if (deleteOriginal) { + try { + await File(inputPath).delete(); + } catch (_) {} + } + return outputPath; + } + + _log.e('FLAC to Opus conversion failed: ${result.output}'); + return null; + } + + /// Convert FLAC to lossy format based on format parameter + /// format: 'mp3' or 'opus' + static Future convertFlacToLossy( + String inputPath, { + required String format, + bool deleteOriginal = true, + }) async { + switch (format.toLowerCase()) { + case 'opus': + return convertFlacToOpus(inputPath, deleteOriginal: deleteOriginal); + case 'mp3': + default: + return convertFlacToMp3(inputPath, deleteOriginal: deleteOriginal); + } + } + static Future convertFlacToM4a( String inputPath, { String codec = 'aac', @@ -104,8 +148,8 @@ class FFmpegService { static Future isAvailable() async { try { - final version = await _channel.invokeMethod('getVersion'); - return version != null && version.toString().isNotEmpty; + final version = await FFmpegKitConfig.getFFmpegVersion(); + return version?.isNotEmpty ?? false; } catch (e) { return false; } @@ -113,8 +157,7 @@ class FFmpegService { static Future getVersion() async { try { - final version = await _channel.invokeMethod('getVersion'); - return version as String?; + return await FFmpegKitConfig.getFFmpegVersion(); } catch (e) { return null; } diff --git a/lib/widgets/download_service_picker.dart b/lib/widgets/download_service_picker.dart index 962a807d..ec65bbde 100644 --- a/lib/widgets/download_service_picker.dart +++ b/lib/widgets/download_service_picker.dart @@ -49,11 +49,11 @@ const _builtInServices = [ ), ]; -/// MP3 quality option (shown when enabled in settings) -const _mp3QualityOption = QualityOption( - id: 'MP3', - label: 'MP3', - description: '320kbps (converted from FLAC)', +/// Lossy quality option (shown when enabled in settings) +const _lossyQualityOption = QualityOption( + id: 'LOSSY', + label: 'Lossy', + description: 'MP3 320kbps or Opus 128kbps', ); /// A reusable widget for selecting download service (built-in + extensions) @@ -115,9 +115,9 @@ class _DownloadServicePickerState extends ConsumerState { final settings = ref.read(settingsProvider); final builtIn = _builtInServices.where((s) => s.id == _selectedService).firstOrNull; if (builtIn != null) { - // Add MP3 option if enabled in settings - if (settings.enableMp3Option) { - return [...builtIn.qualityOptions, _mp3QualityOption]; + // Add Lossy option if enabled in settings + if (settings.enableLossyOption) { + return [...builtIn.qualityOptions, _lossyQualityOption]; } return builtIn.qualityOptions; } @@ -125,9 +125,9 @@ class _DownloadServicePickerState extends ConsumerState { final extensionState = ref.read(extensionProvider); final ext = extensionState.extensions.where((e) => e.id == _selectedService).firstOrNull; if (ext != null && ext.qualityOptions.isNotEmpty) { - // Add MP3 option for extensions too if enabled - if (settings.enableMp3Option) { - return [...ext.qualityOptions, _mp3QualityOption]; + // Add Lossy option for extensions too if enabled + if (settings.enableLossyOption) { + return [...ext.qualityOptions, _lossyQualityOption]; } return ext.qualityOptions; } @@ -136,8 +136,8 @@ class _DownloadServicePickerState extends ConsumerState { final defaultOptions = [ const QualityOption(id: 'DEFAULT', label: 'Default Quality', description: 'Best available'), ]; - if (settings.enableMp3Option) { - return [...defaultOptions, _mp3QualityOption]; + if (settings.enableLossyOption) { + return [...defaultOptions, _lossyQualityOption]; } return defaultOptions; } @@ -259,6 +259,7 @@ class _DownloadServicePickerState extends ConsumerState { return Icons.music_note; case 'MP3_320': case 'MP3': + case 'LOSSY': return Icons.audiotrack; case 'OPUS': case 'OPUS_128': diff --git a/pubspec.lock b/pubspec.lock index 13c08c36..e08f6ee5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -297,6 +297,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + ffmpeg_kit_flutter_new_audio: + dependency: "direct main" + description: + name: ffmpeg_kit_flutter_new_audio + sha256: "0a698b46cd163c8e9917af75325c84d27871a2a8b2c37de3b40486cd0ab662ae" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + ffmpeg_kit_flutter_platform_interface: + dependency: transitive + description: + name: ffmpeg_kit_flutter_platform_interface + sha256: addf046ae44e190ad0101b2fde2ad909a3cd08a2a109f6106d2f7048b7abedee + url: "https://pub.dev" + source: hosted + version: "0.2.1" file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 15c01ff8..5f6588b3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,8 +59,8 @@ dependencies: receive_sharing_intent: ^1.8.1 logger: ^2.5.0 - # FFmpeg - using local custom AAR (arm64-v8a + armeabi-v7a only) - # ffmpeg_kit_flutter_new_audio: ^2.0.0 # Replaced with local AAR + # FFmpeg for audio conversion + ffmpeg_kit_flutter_new_audio: ^2.0.0 open_filex: ^4.7.0 # Notifications