spotube/lib/utils/AudioPlayerHandler.dart
2022-06-20 17:47:08 +06:00

91 lines
2.8 KiB
Dart

import 'dart:async';
import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
/// An [AudioHandler] for playing a single item.
class AudioPlayerHandler extends BaseAudioHandler {
final _player = AudioPlayer();
FutureOr<void> Function()? onNextRequest;
FutureOr<void> Function()? onPreviousRequest;
/// Initialise our audio handler.
AudioPlayerHandler() {
// So that our clients (the Flutter UI and the system notification) know
// what state to display, here we set up our audio handler to broadcast all
// playback state changes as they happen via playbackState...
_player.playbackEventStream.map(_transformEvent).pipe(playbackState);
}
AudioPlayer get core => _player;
void addItem(MediaItem item) {
mediaItem.add(item);
}
// In this simple example, we handle only 4 actions: play, pause, seek and
// stop. Any button press from the Flutter UI, notification, lock screen or
// headset will be routed through to these 4 methods so that you can handle
// your audio playback logic in one place.
@override
Future<void> play() => _player.play();
@override
Future<void> pause() => _player.pause();
@override
Future<void> seek(Duration position) => _player.seek(position);
@override
Future<void> stop() => _player.stop();
@override
Future<void> skipToNext() async {
await onNextRequest?.call();
await super.skipToNext();
}
@override
Future<void> skipToPrevious() async {
await onPreviousRequest?.call();
await super.skipToPrevious();
}
@override
Future<void> onTaskRemoved() {
_player.stop();
return super.onTaskRemoved();
}
/// Transform a just_audio event into an audio_service state.
///
/// This method is used from the constructor. Every event received from the
/// just_audio player will be transformed into an audio_service state so that
/// it can be broadcast to audio_service clients.
PlaybackState _transformEvent(PlaybackEvent event) {
return PlaybackState(
controls: [
MediaControl.skipToPrevious,
if (_player.playing) MediaControl.pause else MediaControl.play,
MediaControl.skipToNext,
MediaControl.stop,
],
androidCompactActionIndices: const [0, 1, 2],
processingState: const {
ProcessingState.idle: AudioProcessingState.idle,
ProcessingState.loading: AudioProcessingState.loading,
ProcessingState.buffering: AudioProcessingState.buffering,
ProcessingState.ready: AudioProcessingState.ready,
ProcessingState.completed: AudioProcessingState.completed,
}[_player.processingState]!,
playing: _player.playing,
updatePosition: _player.position,
bufferedPosition: _player.bufferedPosition,
speed: _player.speed,
queueIndex: event.currentIndex,
);
}
}