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

Flutter音乐播放器:如何获取迷你播放器当前播放歌曲详情?

解决方案

一、监听播放状态控制迷你播放器显示

通过just_audio的playbackStateStream实时获取播放状态,以此控制底部迷你播放器的显示/隐藏:

// 在State类中定义变量
StreamSubscription<PlaybackState>? _playbackStateSubscription;
bool _showMiniPlayer = false;

@override
void initState() {
  super.initState();
  // 监听播放状态变化
  _playbackStateSubscription = player.playbackStateStream.listen((state) {
    setState(() {
      // 仅在播放或暂停状态下显示迷你播放器,停止时隐藏
      _showMiniPlayer = state.processingState == ProcessingState.playing || 
                        state.processingState == ProcessingState.paused;
    });
  });
}

@override
void dispose() {
  _playbackStateSubscription?.cancel();
  super.dispose();
}

在UI中根据_showMiniPlayer控制显示:

// 底部迷你播放器
Visibility(
  visible: _showMiniPlayer,
  child: Container(
    height: 60,
    color: Colors.grey[800],
    child: // 这里放置迷你播放器的内容(歌名、歌手、播放暂停按钮等)
  ),
)

二、获取当前播放歌曲的详情

你的ConcatenatingAudioSource是通过allSongsList映射生成的,当前播放索引与allSongsList的索引完全对应,因此可以通过currentIndexStream获取索引,再从allSongsList中取出对应SongModel拿到歌手、歌名:

// 在State类中添加变量
StreamSubscription<int?>? _currentIndexSubscription;
SongModel? _currentSong;

@override
void initState() {
  super.initState();
  // 监听当前播放索引变化
  _currentIndexSubscription = player.currentIndexStream.listen((index) {
    if (index != null && allSongsList != null && index < allSongsList!.length) {
      setState(() {
        _currentSong = allSongsList![index];
      });
    }
  });
}

@override
void dispose() {
  _currentIndexSubscription?.cancel();
  super.dispose();
}

在迷你播放器中直接使用_currentSong的属性:

// 迷你播放器内容示例
Row(
  children: [
    // 歌曲封面(可选,通过on_audio_query获取)
    FutureBuilder<Uint8List?>(
      future: AudioQuery().queryArtwork(
        _currentSong!.id,
        ArtworkType.AUDIO,
      ),
      builder: (context, snapshot) {
        return snapshot.data != null
            ? Image.memory(snapshot.data!, width: 50, height: 50)
            : Icon(Icons.music_note, size: 50);
      },
    ),
    SizedBox(width: 10),
    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(_currentSong!.title, style: TextStyle(color: Colors.white)),
        Text(_currentSong!.artist ?? "未知歌手", style: TextStyle(color: Colors.grey, fontSize: 12)),
      ],
    ),
    Spacer(),
    // 播放暂停按钮
    IconButton(
      icon: Icon(
        player.playing ? Icons.pause : Icons.play_arrow,
        color: Colors.white,
      ),
      onPressed: () async {
        player.playing ? await player.pause() : await player.play();
      },
    ),
  ],
)

注意事项

  • 确保allSongsList在State类中可访问(可作为成员变量或通过状态管理工具共享)
  • 处理allSongsList为空或索引越界的情况,避免空指针异常
  • 务必在dispose中取消所有Stream订阅,防止内存泄漏

内容的提问来源于stack exchange,提问作者Ashish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:55:18