Windows平台just_audio自定义StreamAudioSource遇数据长度异常
解决just_audio自定义StreamAudioSource数据长度不匹配问题
可能的原因
- 重复输出WAV头:每次生成音频批次时都包含44字节的WAV头,导致总输出数据量为预期的2倍(头+数据重复发送)。
- contentLength计算错误:将contentLength设为单批次长度,但实际流输出了多批次数据;或总长度计算时未正确累加WAV头和PCM数据的总大小。
- 无限流错误设置固定contentLength:如果是实时合成的无固定长度音频流,设置固定contentLength会触发just_audio的字节数匹配检查,导致异常。
具体修复步骤
1. 拆分WAV头与PCM数据输出
WAV头仅需在流起始位置输出一次,后续批次只输出纯PCM音频数据,避免重复发送头信息:
class FaustAudioSource extends StreamAudioSource { // 省略成员变量定义... @override Future<StreamAudioResponse> request([int? start, int? end]) async { final controller = StreamController<List<int>>(); bool hasSentHeader = false; // 预生成标准WAV头 final wavHeader = generateWavHeader( sampleRate: 44100, channels: 2, bitsPerSample: 16, totalSamples: 125, // 单批次样本数,固定时长时填总样本数 ); void emitAudioBatch() { if (!hasSentHeader) { hasSentHeader = true; controller.add(wavHeader); } // 生成纯PCM数据(125样本×2声道×2字节 = 500字节) final pcmData = _generatePcmBatch(); controller.add(pcmData); // 单批次场景发送后关闭控制器;持续流可循环调用 controller.close(); } emitAudioBatch(); return StreamAudioResponse( sourceLength: wavHeader.length + 500, // 44 + 500 = 544 contentLength: wavHeader.length + 500, // 固定长度时设置总字节数 offset: start ?? 0, stream: controller.stream, contentType: 'audio/wav', ); } }
2. 修正contentLength设置
- 固定时长音频:确保
contentLength等于WAV头长度 + 总PCM数据长度(样本数×声道数×位深/8)。 - 实时无限流:将
contentLength设为null,跳过just_audio的字节数匹配检查:
return StreamAudioResponse( sourceLength: null, contentLength: null, offset: start ?? 0, stream: controller.stream, contentType: 'audio/wav', );
3. 检查流输出逻辑
确认流仅输出一次完整的音频数据(头+对应PCM数据),避免循环逻辑错误导致多批次重复输出。比如用take(1)限制单批次输出,或发送完数据后及时关闭StreamController。
额外验证
- 打印流输出的总字节数,确认与
contentLength一致。 - 将流数据写入本地WAV文件,验证文件可正常播放且大小符合预期。
内容的提问来源于stack exchange,提问作者t2techno
相关产品推荐
相关产品推荐

