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

Flutter AudioPlayers音频同时播放问题:实现单音频播放需求

解决多音频同时播放的问题

你当前的问题是每个音频播放页都创建了独立的AudioPlayer实例,导致跳转新页面后旧播放器仍在运行。要实现“播放新音频自动停止旧音频”的效果,核心是让所有页面共享同一个播放器实例,具体步骤如下:

1. 创建全局共享的AudioPlayer实例

在项目全局位置(比如单独的audio_service.dart文件,或主文件顶部)定义单例播放器:

final AudioPlayer globalAudioPlayer = AudioPlayer();

2. 修改音频播放页代码

将页面内的局部播放器替换为全局实例,并在播放新音频前先停止当前播放:

// 音频播放页
class MusicPlayerScreen extends StatefulWidget {
  final SongInfo songInfo;
  const MusicPlayerScreen({Key? key, required this.songInfo}) : super(key: key);

  @override
  State<MusicPlayerScreen> createState() => _MusicPlayerScreenState();
}

class _MusicPlayerScreenState extends State<MusicPlayerScreen> {
  // 使用全局播放器实例
  final AudioPlayer audioPlayer = globalAudioPlayer;

  @override
  void initState() {
    super.initState();
    // 进入页面时先停止旧音频,加载新音频
    _setupNewAudio();
  }

  Future<void> _setupNewAudio() async {
    // 停止当前正在播放的音频
    await audioPlayer.stop();
    // 提前加载新音频,减少播放延迟
    await audioPlayer.setSource(UrlSource(widget.songInfo.filePath));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xff313254),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(15.0),
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 30.0, right: 30.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    InkWell(
                      onTap: () async {
                        // 直接播放已加载的音频
                        await audioPlayer.play();
                      },
                      child: Container(
                        height: 50.0,
                        width: 50.0,
                        decoration: BoxDecoration(
                          shape: BoxShape.circle,
                          gradient: const LinearGradient(colors: [
                            Colors.purpleAccent,
                            Colors.purple
                          ]),
                          boxShadow: [
                            BoxShadow(
                              color: Colors.purpleAccent.withOpacity(0.5),
                              spreadRadius: 5,
                              blurRadius: 7,
                              offset: const Offset(0, 3)
                            ),
                          ],
                        ),
                        child: const Center(child: Icon(Icons.play_circle_fill, color: Colors.white, size: 35.0)),
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 不要销毁全局播放器,否则其他页面无法使用
    super.dispose();
  }
}

3. 列表页无需修改

原列表页的跳转按钮保持不变,播放逻辑已在新页面初始化阶段处理了旧音频停止操作。

原理说明

通过全局单例的AudioPlayer,所有播放页共用同一个播放器实例。每次进入新播放页时,先停止当前正在播放的音频,再加载并准备新音频,从根源避免多音频同时播放的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:15:41