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

Flutter使用just_audio实现两个音频播放器同步播放问题

解决just_audio多轨音频同步播放问题

你当前的实现之所以会出现不同步,核心问题在于:

  1. 播放前的播放器初始化(fillXXXList)在两个并行的Future中执行,两者的完成时间无法保证一致,导致其中一组音频可能先开始播放。
  2. 两组音频的播放循环各自独立执行,逐个播放+延迟的逻辑会因为异步调度、音频加载差异等因素产生时间差。

优化方案

要实现严格同步,需要把播放器初始化和播放控制分离,并统一触发所有对应轨道的播放操作:

1. 提前初始化所有播放器

把播放器的创建和资源加载逻辑提前到播放操作之前(比如页面初始化、用户选择资源完成时),避免播放时的异步操作拖慢节奏:

// 初始化和弦播放器列表
Future<void> initChordsPlayers(List<AudioPlayer> chordsPlayers, Controller c) async {
  for (final source in c.assetSources) {
    final player = AudioPlayer();
    await player.setAsset(source.toString());
    chordsPlayers.add(player);
  }
}

// 初始化鼓点播放器列表
Future<void> initDrumsPlayers(List<AudioPlayer> drumsPlayers, Controller c) async {
  final drumPath = 'assets/drum_beats/${c.rhythmsFolderSelected}/${c.bpmSliderValue.toInt()}BPM.mp3';
  for (int i = 0; i < c.assetSources.length; i++) {
    final player = AudioPlayer();
    await player.setAsset(drumPath);
    drumsPlayers.add(player);
  }
}

2. 统一控制同步播放

在播放时,同时触发对应索引的和弦与鼓点播放器,并使用统一的时间基准来控制循环延迟:

Future<void> playSynchronized(List<AudioPlayer> chordsPlayers, List<AudioPlayer> drumsPlayers, Controller c) async {
  // 校验播放器列表状态,确保数量匹配且已初始化
  if (chordsPlayers.isEmpty || drumsPlayers.isEmpty || chordsPlayers.length != drumsPlayers.length) {
    return;
  }

  for (int i = 0; i < c.assetSources.length; i++) {
    // 同时启动当前轨道的和弦与鼓点音频
    chordsPlayers[i].play();
    drumsPlayers[i].play();

    // 以和弦音频的时长作为统一延迟基准(可根据实际需求替换为鼓点时长)
    final trackDuration = chordsPlayers[i].duration ?? const Duration(seconds: 0);
    await Future.delayed(trackDuration - const Duration(milliseconds: 100));
  }
}

3. 调用方式调整

先在合适的时机完成播放器初始化,再在按钮点击时触发同步播放:

// 提前初始化(比如在initState或用户选择资源后)
await Future.wait([
  initChordsPlayers(chordsAudioPlayersList, c),
  initDrumsPlayers(drumsAudioPlayersList, c),
]);

// 按钮点击时调用
await playSynchronized(chordsAudioPlayersList, drumsAudioPlayersList, c);

额外优化建议

  • 复用播放器:不要每次播放都创建新的AudioPlayer实例,播放结束后可以重置播放器(seek(Duration.zero)),下次播放直接复用,减少资源开销和初始化时间。
  • 统一时间基准:如果鼓点音频时长固定,可以预先计算好延迟时长,避免依赖播放器的duration获取(可能存在微小误差)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:42:49