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

Flutter:使用just_audio加载多音频资源的优化及异步安全性疑问

问题解答

直接去掉await、在前一个资源加载完成前调用新的setAsset是不安全的,原因如下:

  • just_audio的setAsset方法会中断当前实例正在进行的加载或播放操作,连续调用且不等待前一个完成时,前序的加载任务会被直接取消,最终只有最后一次调用的资源会完成加载,你前面的45个音频根本不会被成功加载。
  • 这种操作会导致播放器内部状态混乱,可能引发播放异常、资源泄漏甚至崩溃。

优化加载速度的可行方案

方案1:多播放器实例并行加载

用多个AudioPlayer实例同时加载不同的音频,这样所有资源会并行初始化,总耗时会大幅降低:

// 创建对应数量的播放器实例
final List<AudioPlayer> _numberPlayers = List.generate(47, (_) => AudioPlayer());

// 并行加载所有音频资源
await Future.wait([
  for (int i = 0; i <= 46; i++)
    _numberPlayers[i].setAsset('assets/audio/numbers/$i.mp3'),
]);

播放时直接调用对应索引的_numberPlayers[i].play()即可,播放完成后如果不再需要,可调用_numberPlayers[i].dispose()释放资源。

方案2:按需预加载(适合播放顺序固定的场景)

如果你的播放顺序是固定的(比如从0到46依次播放),可以提前预加载下一个音频,在当前音频播放时异步加载下一个,避免等待:

static final AudioPlayer _player = AudioPlayer();
int currentIndex = 0;

// 初始化第一个音频
await _player.setAsset('assets/audio/numbers/$currentIndex.mp3');

// 播放时预加载下一个
_player.play().then((_) async {
  currentIndex++;
  if (currentIndex <= 46) {
    await _player.setAsset('assets/audio/numbers/$currentIndex.mp3');
  }
});

这种方式只用单个实例,适合对资源占用要求较高的场景,同时避免了集中加载的耗时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:10:04