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
相关产品推荐
相关产品推荐

