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

Flutter中AudioPlayer的pause方法不生效且播放图标无切换问题求助

问题原因与修复方案

核心问题

代码的核心问题是AudioCache.play()方法执行后会返回一个全新的AudioPlayer实例,原有代码没有将这个实例赋值给声明的audioPlayer变量,导致后续调用audioPlayer.pause()操作的是从未播放过音频的空实例,自然没有暂停效果,也不会触发状态更新切换图标。
其次原有代码把onDurationChanged、onAudioPositionChanged监听器放在了每次点击都会触发的getAudio方法中,会导致重复注册监听器,引发内存泄漏和回调多次触发的问题。

修复步骤

1. 调整getAudio方法的播放逻辑

将AudioCache.play()返回的实例赋值给全局audioPlayer变量:

void getAudio() async{
  if(playing){
    var result = await audioPlayer.pause();
    if(result == 1) {
      setState(() {
        playing = false;
      });
    }
  }else{
    // 重点:接收play方法返回的AudioPlayer实例
    audioPlayer = await player.play('audio/music.mp3'); 
    if(audioPlayer.state == PlayerState.playing) {
      setState(() {
        playing = true;
      });
    }
  }
}

2. 把监听器移到initState中仅注册一次

在State类中重写initState和dispose方法,统一管理监听器和资源释放:

@override
void initState() {
  super.initState();
  // 监听器仅注册一次
  audioPlayer.onDurationChanged.listen((Duration dd){
    setState(() {
      duration = dd;
    });
  });
  audioPlayer.onAudioPositionChanged.listen((Duration dd){
    setState(() {
      position = dd;
    });
  });
}

@override
void dispose() {
  // 页面销毁时释放音频资源
  audioPlayer.dispose();
  super.dispose();
}

3. 可选优化

如果使用的是audioplayers 1.0及以上版本,AudioCache已经整合进AudioPlayer类中,可以直接调用audioPlayer.setSourceAsset('audio/music.mp3')加载资源,不需要单独声明AudioCache实例,逻辑更清晰。
同时建议给滑块添加边界判断,避免音频未加载时duration为0导致的滑块报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:54:08