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

Flutter audioplayers包如何监听歌曲播放结束事件

Flutter audioplayers 播放结束状态监听实现

audioplayers 包原生提供了可直接监听播放结束状态的流,无需额外 hack 即可实现歌曲播放完成后的业务逻辑触发。

官方推荐实现方案

从 audioplayers 1.0.0 版本开始,包内提供了专属的 onPlayerComplete Stream,音频正常播放到末尾时会触发该流的回调,直接监听即可:

  • 该流在音频播放到资源末尾自然结束时触发
  • 主动调用 stop() 方法停止播放时也会触发该回调
  • 如果开启了循环播放模式(PlayerMode.loop),播放到末尾会自动重头开始,不会触发该回调

代码示例:

// 初始化播放器实例
final AudioPlayer audioPlayer = AudioPlayer();
StreamSubscription? playCompleteSub;

void initPlayer() {
  // 绑定播放完成监听
  playCompleteSub = audioPlayer.onPlayerComplete.listen((_) {
    // 此处编写播放结束后的业务逻辑,例如切下一首、展示完成提示等
    print('当前歌曲播放完成');
    playNextTrack();
  });
}

// 页面/组件销毁时务必取消订阅、释放播放器,避免内存泄漏
@override
void dispose() {
  playCompleteSub?.cancel();
  audioPlayer.dispose();
  super.dispose();
}

旧版本兼容方案

如果你使用的是4.x及更早的audioplayers版本,没有单独提供onPlayerComplete流,可以通过监听全局播放器状态流,判断状态为完成态时触发逻辑:

audioPlayer.onPlayerStateChanged.listen((PlayerState state) {
  if (state == PlayerState.completed) {
    // 播放完成逻辑
    handlePlayFinish();
  }
});

不推荐的替代方案

注意:该方案仅作为极端场景兜底,日常开发优先使用官方提供的流监听方案。
如果遇到极端场景下流回调失效的问题,理论上可以通过定时轮询当前播放进度和音频总时长的方式判断是否播放结束,但这种方案性能损耗高、容易出现进度判断误差,非特殊情况不建议使用:

Timer? _progressCheckTimer;
void startPlayCheck() {
  _progressCheckTimer = Timer.periodic(const Duration(milliseconds: 300), (timer) async {
    final currentPosition = await audioPlayer.getCurrentPosition();
    final totalDuration = await audioPlayer.getDuration();
    if (currentPosition != null && totalDuration != null) {
      // 进度达到总时长判定为播放完成
      if (currentPosition.inMilliseconds >= totalDuration.inMilliseconds) {
        handlePlayFinish();
        timer.cancel();
      }
    }
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:01:01