import 'dart:async'; import 'package:audio_service/audio_service.dart'; import 'package:just_audio/just_audio.dart'; import '../models/song.dart'; import 'player_service.dart'; /// Hintergrund-Audio-Handler für Sperrbildschirm & Benachrichtigung class MeloAudioHandler extends BaseAudioHandler { final PlayerService _player = PlayerService(); MeloAudioHandler() { // Zustand vom Player an audio_service weiterleiten _player.stateStream.listen(_updateState); _player.positionStream.listen((pos) { if (_playing) { playbackState.add(playbackState.value.copyWith( updatePosition: pos, )); } }); _player.onSongWechsel.listen((song) { if (song != null) { mediaItem.add(_toMediaItem(song)); } }); } bool _playing = false; void _updateState(PlayerState state) { _playing = state.playing; playbackState.add(PlaybackState( controls: _playing ? [MediaControl.pause, MediaControl.skipToPrevious, MediaControl.skipToNext, MediaControl.stop] : [MediaControl.play, MediaControl.skipToPrevious, MediaControl.skipToNext, MediaControl.stop], systemActions: const {MediaAction.seek}, androidCompactActionIndices: const [0, 1, 2], processingState: _playing ? AudioProcessingState.ready : AudioProcessingState.idle, playing: _playing, speed: 1.0, )); } MediaItem _toMediaItem(Song song) => MediaItem( id: song.id?.toString() ?? '0', album: song.album.isEmpty ? 'Melo' : song.album, title: song.titel, artist: song.kuenstler, duration: Duration(seconds: song.dauerSekunden), artUri: song.coverPfad != null ? Uri.file(song.coverPfad!) : null, ); @override Future play() async { if (_player.aktuellerSong != null) { _playing = true; await _player.playPause(); } } @override Future pause() async { _playing = false; await _player.playPause(); } @override Future stop() async { _playing = false; await _player.playPause(); playbackState.add(playbackState.value.copyWith( controls: [MediaControl.play], playing: false, processingState: AudioProcessingState.idle, )); } @override Future seek(Duration position) async { _player.spiele(_player.aktuellerSong!, position: position.inSeconds); } @override Future skipToNext() => _player.naechstes(); @override Future skipToPrevious() => _player.vorheriges(); // Exposed for the ViewModel PlayerService get player => _player; }