You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:50:20