mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
129 lines
3.6 KiB
Dart
129 lines
3.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:audio_service/audio_service.dart';
|
|
import 'package:audio_session/audio_session.dart';
|
|
import 'package:spotube/provider/playlist_queue_provider.dart';
|
|
import 'package:spotube/services/audio_player.dart';
|
|
|
|
class MobileAudioService extends BaseAudioHandler {
|
|
AudioSession? session;
|
|
final PlaylistQueueNotifier playlistNotifier;
|
|
final VolumeProvider volumeNotifier;
|
|
|
|
PlaylistQueue? get playlist => playlistNotifier.state;
|
|
|
|
MobileAudioService(this.playlistNotifier, this.volumeNotifier) {
|
|
AudioSession.instance.then((s) {
|
|
session = s;
|
|
session?.configure(const AudioSessionConfiguration.music());
|
|
s.interruptionEventStream.listen((event) async {
|
|
switch (event.type) {
|
|
case AudioInterruptionType.duck:
|
|
await volumeNotifier.setVolume(event.begin ? 0.5 : 1.0);
|
|
break;
|
|
case AudioInterruptionType.pause:
|
|
case AudioInterruptionType.unknown:
|
|
await playlistNotifier.pause();
|
|
break;
|
|
}
|
|
});
|
|
});
|
|
audioPlayer.playerStateStream.listen((state) async {
|
|
playbackState.add(await _transformEvent());
|
|
});
|
|
|
|
audioPlayer.positionStream.listen((pos) async {
|
|
playbackState.add(await _transformEvent());
|
|
});
|
|
audioPlayer.bufferedPositionStream.listen((pos) async {
|
|
playbackState.add(await _transformEvent());
|
|
});
|
|
}
|
|
|
|
void addItem(MediaItem item) {
|
|
session?.setActive(true);
|
|
mediaItem.add(item);
|
|
}
|
|
|
|
@override
|
|
Future<void> play() => playlistNotifier.resume();
|
|
|
|
@override
|
|
Future<void> pause() => playlistNotifier.pause();
|
|
|
|
@override
|
|
Future<void> seek(Duration position) => playlistNotifier.seek(position);
|
|
|
|
@override
|
|
Future<void> setShuffleMode(AudioServiceShuffleMode shuffleMode) async {
|
|
await super.setShuffleMode(shuffleMode);
|
|
|
|
if (shuffleMode == AudioServiceShuffleMode.all) {
|
|
playlistNotifier.shuffle();
|
|
} else {
|
|
playlistNotifier.unshuffle();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> setRepeatMode(AudioServiceRepeatMode repeatMode) async {
|
|
super.setRepeatMode(repeatMode);
|
|
if (repeatMode == AudioServiceRepeatMode.all) {
|
|
playlistNotifier.loop();
|
|
} else {
|
|
playlistNotifier.unloop();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> stop() async {
|
|
await playlistNotifier.stop();
|
|
}
|
|
|
|
@override
|
|
Future<void> skipToNext() async {
|
|
await playlistNotifier.next();
|
|
await super.skipToNext();
|
|
}
|
|
|
|
@override
|
|
Future<void> skipToPrevious() async {
|
|
await playlistNotifier.previous();
|
|
await super.skipToPrevious();
|
|
}
|
|
|
|
@override
|
|
Future<void> onTaskRemoved() async {
|
|
await playlistNotifier.stop();
|
|
return super.onTaskRemoved();
|
|
}
|
|
|
|
Future<PlaybackState> _transformEvent() async {
|
|
final position = (await audioPlayer.position) ?? Duration.zero;
|
|
return PlaybackState(
|
|
controls: [
|
|
MediaControl.skipToPrevious,
|
|
audioPlayer.isPlaying ? MediaControl.pause : MediaControl.play,
|
|
MediaControl.skipToNext,
|
|
MediaControl.stop,
|
|
],
|
|
systemActions: {
|
|
MediaAction.seek,
|
|
},
|
|
androidCompactActionIndices: const [0, 1, 2],
|
|
playing: audioPlayer.isPlaying,
|
|
updatePosition: position,
|
|
bufferedPosition: await audioPlayer.bufferedPosition ?? Duration.zero,
|
|
shuffleMode: playlist?.isShuffled == true
|
|
? AudioServiceShuffleMode.all
|
|
: AudioServiceShuffleMode.none,
|
|
repeatMode: playlist?.isLooping == true
|
|
? AudioServiceRepeatMode.one
|
|
: AudioServiceRepeatMode.all,
|
|
processingState: playlist?.isLoading == true
|
|
? AudioProcessingState.loading
|
|
: AudioProcessingState.ready,
|
|
);
|
|
}
|
|
}
|