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

如何将UInt16格式音频数据转换为可正常播放的WAV文件

问题根因

你遇到的无法生成可播放WAV文件的核心原因有两点:

  1. Dart的File.writeAsBytes方法仅接收Uint8List类型的字节序列作为输入,你直接传入Uint16List不会自动完成类型转换和字节对齐,写入的文件内容不符合WAV格式规范,因此无法被播放器识别。
  2. 如果你的UInt16格式TXT文件中仅存储纯16位PCM采样数据、没有附带WAV文件头,也会导致播放器无法识别音频格式。

正确实现方案

场景1:UInt16 TXT中已包含完整WAV文件的全量字节(和你可用的UInt8 TXT结构一致)

仅需补充Uint16List到Uint8List的转换步骤即可:

var bytes = await rootBundle.loadString('assets/wav/audio_01_Uint16.txt');
// 原代码中此处不需要加await,split为同步方法,且返回值为List<String>不是List<int>
List<String> strList = bytes.split(', ');
List<int> intList = strList.map((s) => int.parse(s)).toList();
Uint16List uint16List = Uint16List.fromList(intList);
// *核心转换*:通过buffer将Uint16List转为符合要求的Uint8List
Uint8List wavBytes = uint16List.buffer.asUint8List();
await File('$tempPath/audio_01_Uint16.wav').writeAsBytes(wavBytes);

场景2:UInt16 TXT中仅存储纯PCM采样数据,无WAV头

需要先构造标准WAV文件头,再拼接采样数据后写入:

var bytes = await rootBundle.loadString('assets/wav/audio_01_Uint16.txt');
List<String> strList = bytes.split(', ');
List<int> intList = strList.map((s) => int.parse(s)).toList();
Uint16List uint16List = Uint16List.fromList(intList);

// 请根据你的音频实际参数修改以下配置:示例为44100采样率、双声道、16位深PCM
int sampleRate = 44100;
int channels = 2;
int bitDepth = 16;
int byteRate = sampleRate * channels * bitDepth ~/ 8;
int blockAlign = channels * bitDepth ~/ 8;
int dataSize = uint16List.length * 2;
int fileSize = 36 + dataSize;

// 构造44字节标准WAV头
Uint8List header = Uint8List(44);
header.setRange(0, 4, [0x52, 0x49, 0x46, 0x46]); // RIFF标识
header.buffer.asByteData().setUint32(4, fileSize, Endian.little); // 文件总大小
header.setRange(8, 12, [0x57, 0x41, 0x56, 0x45]); // WAVE标识
header.setRange(12, 16, [0x66, 0x6D, 0x74, 0x20]); // fmt块标识
header.buffer.asByteData().setUint32(16, 16, Endian.little); // fmt块长度
header.buffer.asByteData().setUint16(20, 1, Endian.little); // 音频格式(PCM=1)
header.buffer.asByteData().setUint16(22, channels, Endian.little); // 声道数
header.buffer.asByteData().setUint32(24, sampleRate, Endian.little); // 采样率
header.buffer.asByteData().setUint32(28, byteRate, Endian.little); // 字节传输率
header.buffer.asByteData().setUint16(32, blockAlign, Endian.little); // 块对齐单位
header.buffer.asByteData().setUint16(34, bitDepth, Endian.little); // 采样位深
header.setRange(36, 40, [0x64, 0x61, 0x74, 0x61]); // data块标识
header.buffer.asByteData().setUint32(40, dataSize, Endian.little); // 音频数据长度

// 拼接头和音频数据
Uint8List wavBytes = Uint8List(header.length + dataSize);
wavBytes.setRange(0, header.length, header);
wavBytes.setRange(header.length, wavBytes.length, uint16List.buffer.asUint8List());

// 写入文件
await File('$tempPath/audio_01_Uint16.wav').writeAsBytes(wavBytes);

内容的提问来源于stack exchange,提问作者Shree K Adhikari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 16:21:03