diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 860118d1a..c58678fdd 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -264,5 +264,6 @@ "use_system_title_bar": "Use system title bar", "crunching_results": "Crunching results...", "search_to_get_results": "Search to get results", - "use_amoled_dark_theme": "Use AMOLED (Pitch Black) dark theme" + "use_amoled_dark_theme": "Use AMOLED (Pitch Black) dark theme", + "normalize_audio": "Normalize audio" } \ No newline at end of file diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index e209e47b0..dd1969ddf 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -448,6 +448,13 @@ class SettingsPage extends HookConsumerWidget { }, trailing: const Icon(SpotubeIcons.angleRight), ), + SwitchListTile( + secondary: const Icon(SpotubeIcons.playlistRemove), + title: Text(context.l10n.normalize_audio), + subtitle: Text(context.l10n.blacklist_description), + value: preferences.normalizeAudio, + onChanged: preferences.setNormalizeAudio, + ), ], ), SectionCardWithHeading( diff --git a/lib/provider/user_preferences_provider.dart b/lib/provider/user_preferences_provider.dart index 01494f5af..20765fd25 100644 --- a/lib/provider/user_preferences_provider.dart +++ b/lib/provider/user_preferences_provider.dart @@ -10,6 +10,7 @@ import 'package:spotube/components/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/models/matched_track.dart'; import 'package:spotube/provider/palette_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; +import 'package:spotube/services/audio_player/audio_player.dart'; import 'package:spotube/utils/persisted_change_notifier.dart'; import 'package:spotube/utils/platform.dart'; @@ -70,6 +71,8 @@ class UserPreferences extends PersistedChangeNotifier { bool amoledDarkTheme; + bool normalizeAudio; + final Ref ref; UserPreferences( @@ -92,6 +95,7 @@ class UserPreferences extends PersistedChangeNotifier { this.youtubeApiType = YoutubeApiType.youtube, this.systemTitleBar = false, this.amoledDarkTheme = false, + this.normalizeAudio = true, }) : super() { if (downloadLocation.isEmpty && !kIsWeb) { _getDefaultDownloadDirectory().then( @@ -219,6 +223,13 @@ class UserPreferences extends PersistedChangeNotifier { updatePersistence(); } + void setNormalizeAudio(bool normalize) { + normalizeAudio = normalize; + audioPlayer.setAudioNormalization(normalize); + notifyListeners(); + updatePersistence(); + } + Future _getDefaultDownloadDirectory() async { if (kIsAndroid) return "/storage/emulated/0/Download/Spotube"; @@ -285,6 +296,9 @@ class UserPreferences extends PersistedChangeNotifier { setSystemTitleBar(systemTitleBar); amoledDarkTheme = map["amoledDarkTheme"] ?? amoledDarkTheme; + + normalizeAudio = map["normalizeAudio"] ?? normalizeAudio; + audioPlayer.setAudioNormalization(normalizeAudio); } @override @@ -309,6 +323,7 @@ class UserPreferences extends PersistedChangeNotifier { "youtubeApiType": youtubeApiType.name, 'systemTitleBar': systemTitleBar, "amoledDarkTheme": amoledDarkTheme, + "normalizeAudio": normalizeAudio, }; } diff --git a/lib/services/audio_player/audio_player.dart b/lib/services/audio_player/audio_player.dart index 8566977d1..78dc149b4 100644 --- a/lib/services/audio_player/audio_player.dart +++ b/lib/services/audio_player/audio_player.dart @@ -24,10 +24,6 @@ abstract class AudioPlayerInterface { ) // _justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null { - //? Normalizing the audio - (_mkPlayer.platform as mk.NativePlayer) - .setProperty('af', 'dynaudnorm=g=5:f=250:r=0.9:p=0.5'); - _mkPlayer.stream.error.listen((event) { Catcher.reportCheckedError(event, StackTrace.current); }); diff --git a/lib/services/audio_player/audio_player_impl.dart b/lib/services/audio_player/audio_player_impl.dart index 417cf4b30..0f8e715cb 100644 --- a/lib/services/audio_player/audio_player_impl.dart +++ b/lib/services/audio_player/audio_player_impl.dart @@ -312,4 +312,8 @@ class SpotubeAudioPlayer extends AudioPlayerInterface // await _justAudio!.setLoopMode(loop.toLoopMode()); // } } + + Future setAudioNormalization(bool normalize) async { + await _mkPlayer.setAudioNormalization(normalize); + } } diff --git a/lib/services/audio_player/mk_state_player.dart b/lib/services/audio_player/mk_state_player.dart index aeb59e597..148b95acb 100644 --- a/lib/services/audio_player/mk_state_player.dart +++ b/lib/services/audio_player/mk_state_player.dart @@ -318,4 +318,14 @@ class MkPlayerWithState extends Player { index: newMedias.indexOf(_playlist!.medias[_playlist!.index]), ); } + + NativePlayer get nativePlayer => platform as NativePlayer; + + Future setAudioNormalization(bool normalize) async { + if (normalize) { + await nativePlayer.setProperty('af', 'dynaudnorm=g=5:f=250:r=0.9:p=0.5'); + } else { + await nativePlayer.setProperty('af', ''); + } + } } diff --git a/untranslated_messages.json b/untranslated_messages.json index f1a9cb16c..9ebae92a1 100644 --- a/untranslated_messages.json +++ b/untranslated_messages.json @@ -1,45 +1,56 @@ { "bn": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "ca": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "de": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "es": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "fr": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "hi": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "ja": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "pl": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "pt": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "ru": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ], "zh": [ - "use_amoled_dark_theme" + "use_amoled_dark_theme", + "normalize_audio" ] }