diff --git a/just_audio_background/lib/just_audio_background.dart b/just_audio_background/lib/just_audio_background.dart index 028c7ac0..90ae7c51 100644 --- a/just_audio_background/lib/just_audio_background.dart +++ b/just_audio_background/lib/just_audio_background.dart @@ -54,13 +54,11 @@ class JustAudioBackground { androidResumeOnClick: androidResumeOnClick, androidNotificationChannelId: androidNotificationChannelId, androidNotificationChannelName: androidNotificationChannelName, - androidNotificationChannelDescription: - androidNotificationChannelDescription, + androidNotificationChannelDescription: androidNotificationChannelDescription, notificationColor: notificationColor, androidNotificationIcon: androidNotificationIcon, androidShowNotificationBadge: androidShowNotificationBadge, - androidNotificationClickStartsActivity: - androidNotificationClickStartsActivity, + androidNotificationClickStartsActivity: androidNotificationClickStartsActivity, androidNotificationOngoing: androidNotificationOngoing, androidStopForegroundOnPause: androidStopForegroundOnPause, artDownscaleWidth: artDownscaleWidth, @@ -73,6 +71,15 @@ class JustAudioBackground { } } +/// Make audio stop when the app is terminated by task manager on android +class _AudioHandler extends BaseAudioHandler { + @override + Future onTaskRemoved() async { + await stop(); + await super.onTaskRemoved(); + } +} + class _JustAudioBackgroundPlugin extends JustAudioPlatform { static Future setup({ bool androidResumeOnClick = true, @@ -95,18 +102,16 @@ class _JustAudioBackgroundPlugin extends JustAudioPlatform { _platform = JustAudioPlatform.instance; JustAudioPlatform.instance = _JustAudioBackgroundPlugin(); _audioHandler = await AudioService.init( - builder: () => SwitchAudioHandler(BaseAudioHandler()), + builder: () => SwitchAudioHandler(_AudioHandler()), config: AudioServiceConfig( androidResumeOnClick: androidResumeOnClick, androidNotificationChannelId: androidNotificationChannelId, androidNotificationChannelName: androidNotificationChannelName, - androidNotificationChannelDescription: - androidNotificationChannelDescription, + androidNotificationChannelDescription: androidNotificationChannelDescription, notificationColor: notificationColor, androidNotificationIcon: androidNotificationIcon, androidShowNotificationBadge: androidShowNotificationBadge, - androidNotificationClickStartsActivity: - androidNotificationClickStartsActivity, + androidNotificationClickStartsActivity: androidNotificationClickStartsActivity, androidNotificationOngoing: androidNotificationOngoing, androidStopForegroundOnPause: androidStopForegroundOnPause, artDownscaleWidth: artDownscaleWidth, @@ -127,9 +132,7 @@ class _JustAudioBackgroundPlugin extends JustAudioPlatform { Future init(InitRequest request) async { if (_player != null) { throw PlatformException( - code: "error", - message: - "just_audio_background supports only a single player instance"); + code: "error", message: "just_audio_background supports only a single player instance"); } _player = _JustAudioPlayer( initRequest: request, @@ -138,8 +141,7 @@ class _JustAudioBackgroundPlugin extends JustAudioPlatform { } @override - Future disposePlayer( - DisposePlayerRequest request) async { + Future disposePlayer(DisposePlayerRequest request) async { final player = _player; _player = null; await player?.release(); @@ -147,8 +149,7 @@ class _JustAudioBackgroundPlugin extends JustAudioPlatform { } @override - Future disposeAllPlayers( - DisposeAllPlayersRequest request) async { + Future disposeAllPlayers(DisposeAllPlayersRequest request) async { final player = _player; _player = null; await player?.release(); @@ -225,16 +226,13 @@ class _JustAudioPlayer extends AudioPlayerPlatform { } @override - Stream get playbackEventMessageStream => - eventController.stream; + Stream get playbackEventMessageStream => eventController.stream; @override - Stream get playerDataMessageStream => - playerDataController.stream; + Stream get playerDataMessageStream => playerDataController.stream; @override - Future load(LoadRequest request) => - _playerAudioHandler.customLoad(request); + Future load(LoadRequest request) => _playerAudioHandler.customLoad(request); @override Future play(PlayRequest request) async { @@ -265,42 +263,35 @@ class _JustAudioPlayer extends AudioPlayerPlatform { } @override - Future setSkipSilence( - SetSkipSilenceRequest request) async { + Future setSkipSilence(SetSkipSilenceRequest request) async { await _playerAudioHandler.customSetSkipSilence(request); return SetSkipSilenceResponse(); } @override Future setLoopMode(SetLoopModeRequest request) async { - await _audioHandler - .setRepeatMode(AudioServiceRepeatMode.values[request.loopMode.index]); + await _audioHandler.setRepeatMode(AudioServiceRepeatMode.values[request.loopMode.index]); return SetLoopModeResponse(); } @override - Future setShuffleMode( - SetShuffleModeRequest request) async { - await _audioHandler.setShuffleMode( - AudioServiceShuffleMode.values[request.shuffleMode.index]); + Future setShuffleMode(SetShuffleModeRequest request) async { + await _audioHandler.setShuffleMode(AudioServiceShuffleMode.values[request.shuffleMode.index]); return SetShuffleModeResponse(); } @override - Future setShuffleOrder( - SetShuffleOrderRequest request) => + Future setShuffleOrder(SetShuffleOrderRequest request) => _playerAudioHandler.customSetShuffleOrder(request); @override - Future setWebCrossOrigin( - SetWebCrossOriginRequest request) async { + Future setWebCrossOrigin(SetWebCrossOriginRequest request) async { _playerAudioHandler.customSetWebCrossOrigin(request); return SetWebCrossOriginResponse(); } @override - Future seek(SeekRequest request) => - _playerAudioHandler.customPlayerSeek(request); + Future seek(SeekRequest request) => _playerAudioHandler.customPlayerSeek(request); @override Future concatenatingInsertAll( @@ -313,8 +304,7 @@ class _JustAudioPlayer extends AudioPlayerPlatform { _playerAudioHandler.customConcatenatingRemoveRange(request); @override - Future concatenatingMove( - ConcatenatingMoveRequest request) => + Future concatenatingMove(ConcatenatingMoveRequest request) => _playerAudioHandler.customConcatenatingMove(request); @override @@ -323,11 +313,9 @@ class _JustAudioPlayer extends AudioPlayerPlatform { _playerAudioHandler.customSetAndroidAudioAttributes(request); @override - Future - setAutomaticallyWaitsToMinimizeStalling( - SetAutomaticallyWaitsToMinimizeStallingRequest request) => - _playerAudioHandler - .customSetAutomaticallyWaitsToMinimizeStalling(request); + Future setAutomaticallyWaitsToMinimizeStalling( + SetAutomaticallyWaitsToMinimizeStallingRequest request) => + _playerAudioHandler.customSetAutomaticallyWaitsToMinimizeStalling(request); @override Future androidEqualizerBandSetGain( @@ -340,11 +328,9 @@ class _JustAudioPlayer extends AudioPlayerPlatform { _playerAudioHandler.customAndroidEqualizerGetParameters(request); @override - Future - androidLoudnessEnhancerSetTargetGain( - AndroidLoudnessEnhancerSetTargetGainRequest request) => - _playerAudioHandler - .customAndroidLoudnessEnhancerSetTargetGain(request); + Future androidLoudnessEnhancerSetTargetGain( + AndroidLoudnessEnhancerSetTargetGainRequest request) => + _playerAudioHandler.customAndroidLoudnessEnhancerSetTargetGain(request); @override Future audioEffectSetEnabled( @@ -359,11 +345,8 @@ class _JustAudioPlayer extends AudioPlayerPlatform { @override Future setCanUseNetworkResourcesForLiveStreamingWhilePaused( - SetCanUseNetworkResourcesForLiveStreamingWhilePausedRequest - request) => - _playerAudioHandler - .customSetCanUseNetworkResourcesForLiveStreamingWhilePaused( - request); + SetCanUseNetworkResourcesForLiveStreamingWhilePausedRequest request) => + _playerAudioHandler.customSetCanUseNetworkResourcesForLiveStreamingWhilePaused(request); @override Future setPreferredPeakBitRate( @@ -371,8 +354,7 @@ class _JustAudioPlayer extends AudioPlayerPlatform { _playerAudioHandler.customSetPreferredPeakBitRate(request); } -class _PlayerAudioHandler extends BaseAudioHandler - with QueueHandler, SeekHandler { +class _PlayerAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler { final _playerCompleter = Completer(); PlaybackEventMessage _justAudioEvent = PlaybackEventMessage( processingState: ProcessingStateMessage.idle, @@ -397,12 +379,10 @@ class _PlayerAudioHandler extends BaseAudioHandler Future get _player => _playerCompleter.future; int? get index => _justAudioEvent.currentIndex; - MediaItem? get currentMediaItem => index != null && - currentQueue != null && - index! >= 0 && - index! < currentQueue!.length - ? currentQueue![index!] - : null; + MediaItem? get currentMediaItem => + index != null && currentQueue != null && index! >= 0 && index! < currentQueue!.length + ? currentQueue![index!] + : null; List? get currentQueue => queue.nvalue; @@ -418,10 +398,7 @@ class _PlayerAudioHandler extends BaseAudioHandler _justAudioEvent = event; _broadcastState(); }); - playbackEventMessageStream - .map((event) => event.icyMetadata) - .distinct() - .listen((icyMetadata) { + playbackEventMessageStream.map((event) => event.icyMetadata).distinct().listen((icyMetadata) { customEvent.add({ 'type': 'icyMetadata', 'value': icyMetadata, @@ -456,8 +433,7 @@ class _PlayerAudioHandler extends BaseAudioHandler if (currentMediaItem != null) { if (track.duration != currentMediaItem!.duration && (index! < queue.nvalue!.length && track.duration != null)) { - currentQueue![index!] = - currentQueue![index!].copyWith(duration: track.duration); + currentQueue![index!] = currentQueue![index!].copyWith(duration: track.duration); queue.add(currentQueue!); } mediaItem.add(currentMediaItem!); @@ -468,10 +444,7 @@ class _PlayerAudioHandler extends BaseAudioHandler @override Future updateQueue(List queue) async { this.queue.add(queue); - if (mediaItem.nvalue == null && - index != null && - index! >= 0 && - index! < queue.length) { + if (mediaItem.nvalue == null && index != null && index! >= 0 && index! < queue.length) { mediaItem.add(queue[index!]); } } @@ -497,15 +470,13 @@ class _PlayerAudioHandler extends BaseAudioHandler Future customSetPitch(SetPitchRequest request) async => await (await _player).setPitch(request); - Future customSetSkipSilence( - SetSkipSilenceRequest request) async => + Future customSetSkipSilence(SetSkipSilenceRequest request) async => await (await _player).setSkipSilence(request); Future customPlayerSeek(SeekRequest request) async => await (await _player).seek(request); - Future customSetShuffleOrder( - SetShuffleOrderRequest request) async { + Future customSetShuffleOrder(SetShuffleOrderRequest request) async { _source = request.audioSourceMessage; _updateShuffleIndices(); _broadcastStateIfActive(); @@ -542,8 +513,7 @@ class _PlayerAudioHandler extends BaseAudioHandler Future customConcatenatingMove( ConcatenatingMoveRequest request) async { final cat = _source!.findCat(request.id)!; - cat.children - .insert(request.newIndex, cat.children.removeAt(request.currentIndex)); + cat.children.insert(request.newIndex, cat.children.removeAt(request.currentIndex)); _updateShuffleIndices(); _broadcastStateIfActive(); _updateQueue(); @@ -557,22 +527,19 @@ class _PlayerAudioHandler extends BaseAudioHandler Future customSetAutomaticallyWaitsToMinimizeStalling( SetAutomaticallyWaitsToMinimizeStallingRequest request) async => - await (await _player) - .setAutomaticallyWaitsToMinimizeStalling(request); + await (await _player).setAutomaticallyWaitsToMinimizeStalling(request); Future customAndroidEqualizerBandSetGain( AndroidEqualizerBandSetGainRequest request) async => await (await _player).androidEqualizerBandSetGain(request); - Future - customAndroidEqualizerGetParameters( - AndroidEqualizerGetParametersRequest request) async => - await (await _player).androidEqualizerGetParameters(request); + Future customAndroidEqualizerGetParameters( + AndroidEqualizerGetParametersRequest request) async => + await (await _player).androidEqualizerGetParameters(request); - Future - customAndroidLoudnessEnhancerSetTargetGain( - AndroidLoudnessEnhancerSetTargetGainRequest request) async => - await (await _player).androidLoudnessEnhancerSetTargetGain(request); + Future customAndroidLoudnessEnhancerSetTargetGain( + AndroidLoudnessEnhancerSetTargetGainRequest request) async => + await (await _player).androidLoudnessEnhancerSetTargetGain(request); Future customAudioEffectSetEnabled( AudioEffectSetEnabledRequest request) async => @@ -584,10 +551,8 @@ class _PlayerAudioHandler extends BaseAudioHandler Future customSetCanUseNetworkResourcesForLiveStreamingWhilePaused( - SetCanUseNetworkResourcesForLiveStreamingWhilePausedRequest - request) async => - await (await _player) - .setCanUseNetworkResourcesForLiveStreamingWhilePaused(request); + SetCanUseNetworkResourcesForLiveStreamingWhilePausedRequest request) async => + await (await _player).setCanUseNetworkResourcesForLiveStreamingWhilePaused(request); Future customSetPreferredPeakBitRate( SetPreferredPeakBitRateRequest request) async => @@ -693,8 +658,7 @@ class _PlayerAudioHandler extends BaseAudioHandler } @override - Future fastForward() => - _seekRelative(AudioService.config.fastForwardInterval); + Future fastForward() => _seekRelative(AudioService.config.fastForwardInterval); @override Future rewind() => _seekRelative(-AudioService.config.rewindInterval); @@ -710,8 +674,8 @@ class _PlayerAudioHandler extends BaseAudioHandler _repeatMode = repeatMode; _broadcastStateIfActive(); (await _player).setLoopMode(SetLoopModeRequest( - loopMode: LoopModeMessage - .values[min(LoopModeMessage.values.length - 1, repeatMode.index)])); + loopMode: + LoopModeMessage.values[min(LoopModeMessage.values.length - 1, repeatMode.index)])); } @override @@ -720,8 +684,8 @@ class _PlayerAudioHandler extends BaseAudioHandler _updateShuffleIndices(); _broadcastStateIfActive(); (await _player).setShuffleMode(SetShuffleModeRequest( - shuffleMode: ShuffleModeMessage.values[ - min(ShuffleModeMessage.values.length - 1, shuffleMode.index)])); + shuffleMode: ShuffleModeMessage + .values[min(ShuffleModeMessage.values.length - 1, shuffleMode.index)])); } @override @@ -743,8 +707,7 @@ class _PlayerAudioHandler extends BaseAudioHandler } Duration get currentPosition { - if (_playing && - _justAudioEvent.processingState == ProcessingStateMessage.ready) { + if (_playing && _justAudioEvent.processingState == ProcessingStateMessage.ready) { return Duration( milliseconds: (_justAudioEvent.updatePosition.inMilliseconds + ((DateTime.now().millisecondsSinceEpoch - @@ -774,8 +737,8 @@ class _PlayerAudioHandler extends BaseAudioHandler void _seekContinuously(bool begin, int direction) { _seeker?.stop(); if (begin) { - _seeker = _Seeker(this, Duration(seconds: 10 * direction), - const Duration(seconds: 1), currentMediaItem!.duration!) + _seeker = _Seeker(this, Duration(seconds: 10 * direction), const Duration(seconds: 1), + currentMediaItem!.duration!) ..start(); } } @@ -869,8 +832,7 @@ extension _PlaybackEventMessageExtension on PlaybackEventMessage { duration: duration ?? this.duration, icyMetadata: icyMetadata ?? this.icyMetadata, currentIndex: currentIndex ?? this.currentIndex, - androidAudioSessionId: - androidAudioSessionId ?? this.androidAudioSessionId, + androidAudioSessionId: androidAudioSessionId ?? this.androidAudioSessionId, ); } @@ -908,8 +870,7 @@ extension AudioSourceExtension on AudioSourceMessage { var offset = 0; final childIndicesList = >[]; for (final child in self.children) { - final childIndices = - child.shuffleIndices.map((i) => i + offset).toList(); + final childIndices = child.shuffleIndices.map((i) => i + offset).toList(); childIndicesList.add(childIndices); offset += childIndices.length; } diff --git a/just_audio_background/pubspec.yaml b/just_audio_background/pubspec.yaml index e8d5b0d4..384f8fa3 100644 --- a/just_audio_background/pubspec.yaml +++ b/just_audio_background/pubspec.yaml @@ -12,13 +12,13 @@ dependencies: just_audio_platform_interface: ^4.3.0 # just_audio_platform_interface: # path: ../just_audio_platform_interface - audio_service: ^0.18.9 - audio_session: ^0.1.14 + audio_service: ^0.18.13 + audio_session: ^0.1.19 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.3.0 + meta: ^1.12.0 rxdart: '>=0.26.0 <0.28.0' dev_dependencies: