Flutter异步音频请求结果乱序,如何实现顺序播放且首段立即播放?
解决段落音频顺序播放且边生成边播放的问题
核心思路
别直接把所有生成中的音频源一股脑丢进ConcatenatingAudioSource,改成维护一个待播放队列,同时监听当前音频的播放结束事件,只在当前段播完后,再把队列里下一个准备好的音频源加入播放列表,确保严格按段落顺序走。
具体实现步骤
- 初始化基础组件
保留AudioPlayer和ConcatenatingAudioSource,但初始时播放列表为空,先完成基础配置:
final audioPlayer = AudioPlayer(); final concatenatingSource = ConcatenatingAudioSource(children: []); await audioPlayer.setAudioSource(concatenatingSource);
- 维护待播队列与异步生成任务
创建一个队列存储已生成好的音频源,同时启动文本流的段落处理循环:
- 逐个读取文本段落,向Eleven Labs API发送转换请求
- 每拿到一个段落的音频源(比如
UrlAudioSource或本地文件源),就将其加入队列 - 同时监听
AudioPlayer的播放状态流,当当前音频播放结束且队列不为空时,把队列头部的音频源添加到播放列表
- 监听播放状态动态添加音频源
这是解决乱序的关键,只有当前段播完才加下一段:
audioPlayer.playerStateStream.listen((state) { if (state.processingState == ProcessingState.completed && audioQueue.isNotEmpty) { final nextSource = audioQueue.removeFirst(); concatenatingSource.add(nextSource); } });
- 第一段就绪后立即启动播放
当第一个段落的音频源生成完成后,直接加入播放列表并启动播放,不用等后续段落:
// 假设firstSource是第一段生成好的音频源 concatenatingSource.add(firstSource); await audioPlayer.play();
额外优化点
- 给Eleven Labs的转换请求加并发限制,比如同时只处理1-2个段落,避免短段落大量生成后堆积队列
- 监听音频源的加载状态,确保加入播放列表的音频源已就绪,避免播放报错
- 可以在UI上显示待播段落数量,让用户知道后续内容的加载进度
内容的提问来源于stack exchange,提问作者Sahil Singh
相关产品推荐
相关产品推荐

