Flutter中如何从搜索页将歌曲数据传递给audio_service处理器
解决方案
1. 修改AudioPlayerHandler构造函数,支持动态传入歌曲详情
把原来固定的静态_item改成通过构造函数传入,让外部可以在创建handler时传递当前歌曲的信息:
class AudioPlayerHandler extends BaseAudioHandler with SeekHandler { final AudioPlayer _player = AudioPlayer(); MediaItem? _currentItem; // 构造函数接收外部传入的MediaItem AudioPlayerHandler(MediaItem initialItem) { _currentItem = initialItem; // 初始化媒体项到audio_service mediaItem.add(initialItem); // 设置音频源 _player.setAudioSource(AudioSource.uri(Uri.parse(initialItem.id))); _player.playbackEventStream.map(_transformEvent).pipe(playbackState); } // 新增方法:切换歌曲时更新媒体项和音频源 Future<void> updateMediaItem(MediaItem newItem) async { _currentItem = newItem; mediaItem.add(newItem); await _player.setAudioSource(AudioSource.uri(Uri.parse(newItem.id))); } @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(); PlaybackState _transformEvent(PlaybackEvent event) { return PlaybackState( controls: [ MediaControl.rewind, if (_player.playing) MediaControl.pause else MediaControl.play, MediaControl.stop, MediaControl.fastForward, ], systemActions: const { MediaAction.seek, MediaAction.seekForward, MediaAction.seekBackward, }, androidCompactActionIndices: const [0, 1, 3], 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, ); } }
2. 在外部创建handler时传入当前歌曲详情
在你的页面或播放逻辑里,构造当前歌曲的MediaItem,再初始化AudioPlayerHandler:
// 示例:构造当前歌曲的MediaItem final currentSong = MediaItem( id: "你的歌曲链接", album: "专辑名", title: "歌曲名", artist: "歌手名", duration: Duration(milliseconds: 歌曲时长), artUri: Uri.parse("封面图片链接"), ); // 初始化AudioPlayerHandler,传入歌曲详情 final audioHandler = await AudioService.init( builder: () => AudioPlayerHandler(currentSong), config: const AudioServiceConfig( androidNotificationChannelId: 'com.yourapp.channel', androidNotificationChannelName: '音乐播放', androidNotificationOngoing: true, ), );
3. 切换歌曲时调用updateMediaItem方法
当需要播放另一首歌时,直接调用handler的updateMediaItem方法,就能同步更新通知栏显示和音频源:
// 构造新的歌曲MediaItem final newSong = MediaItem( id: "新歌曲链接", album: "新专辑名", title: "新歌曲名", artist: "新歌手名", duration: Duration(milliseconds: 新歌曲时长), artUri: Uri.parse("新封面链接"), ); // 更新歌曲 await audioHandler.updateMediaItem(newSong); // 可选:自动播放新歌曲 await audioHandler.play();
关键说明
- 移除了原来的静态
_item,改用实例变量_currentItem存储当前歌曲,确保每次传入的歌曲都是动态的。 - 通过
mediaItem.add(newItem)将新的歌曲信息同步到audio_service的通知栏和系统媒体会话。 updateMediaItem方法封装了更新媒体项和切换音频源的逻辑,简化外部切换歌曲的操作。
内容的提问来源于stack exchange,提问作者Neal
相关产品推荐
相关产品推荐

