// lib/services/audio_player_handler.dart import 'package:flutter/foundation.dart'; import 'package:audio_service/audio_service.dart' as audio_service; import '../audio/player_controller.dart'; import '../audio/playback_state_manager.dart'; import '../services/audio_service.dart'; class AudioPlayerHandler extends audio_service.BaseAudioHandler { final PlayerController _player = PlayerController(); final PlaybackStateManager _state = PlaybackStateManager(); String? _currentId; String? _currentTitle; String? _currentArtist; AudioPlayerHandler() { // ---- 播放状态 ---- _player.playingStream.listen((playing) { _state.updatePlaying(playing); _publishState(); }); // ---- 进度变化 ---- _player.positionStream.listen((position) { _state.updatePosition(position); // ⭐ 0.18.19 版本:通过更新 PlaybackState 的 updateTime 来驱动进度刷新 _publishStateOnly(); }); // ---- 时长变化 ---- _player.durationStream.listen((duration) { _state.updateDuration(duration); if (_currentId != null && _currentTitle != null) { _updateMediaItem( id: _currentId!, title: _currentTitle!, artist: _currentArtist!, duration: duration, ); } _publishState(); }); } // ---- 发布完整状态 ---- void _publishState() { playbackState.add(_state.playbackState); } // ---- 0.18.19 版本:只更新时间戳,驱动系统刷新进度 ---- void _publishStateOnly() { final current = playbackState.value; playbackState.add(audio_service.PlaybackState( controls: current.controls, processingState: current.processingState, playing: current.playing, androidCompactActionIndices: current.androidCompactActionIndices, updateTime: DateTime.now(), // ⭐ 关键:更新时间戳,系统会重新读取位置 )); } // ---- 更新媒体信息 ---- void _updateMediaItem({ required String id, required String title, required String artist, Duration? duration, }) { _currentId = id; _currentTitle = title; _currentArtist = artist; debugPrint('📢 [handler] updateMediaItem: $title - $artist'); mediaItem.add(audio_service.MediaItem( id: id, title: title, artist: artist, duration: duration ?? _player.duration, )); } // ---- 外部接口 ---- void updateNotification({ required String id, required String title, required String artist, }) { _updateMediaItem(id: id, title: title, artist: artist); _publishState(); } // ---- 控制命令 ---- @override Future play() async { debugPrint('▶️ [handler] play() called'); _player.play(); _publishState(); } @override Future pause() async { debugPrint('⏸️ [handler] pause() called'); _player.pause(); _publishState(); } @override Future stop() async { debugPrint('⏹️ [handler] stop() called'); _player.stop(); _publishState(); } @override Future seek(Duration position) async { debugPrint('⏩ [handler] seek() called: $position'); _player.seek(position); _publishStateOnly(); } @override Future skipToNext() async { debugPrint('⏭️ [handler] skipToNext() called'); AudioService().next(); } @override Future skipToPrevious() async { debugPrint('⏮️ [handler] skipToPrevious() called'); AudioService().previous(); } @override Future click( [audio_service.MediaButton button = audio_service.MediaButton.media]) async { debugPrint('🎯 [handler] click() called with button: ${button.name}'); switch (button) { case audio_service.MediaButton.next: await skipToNext(); break; case audio_service.MediaButton.previous: await skipToPrevious(); break; case audio_service.MediaButton.media: if (_player.isPlaying) { await pause(); } else { await play(); } break; default: // 其他按钮 fallback if (_player.isPlaying) { await pause(); } else { await play(); } } } }