如何把 WAV 转换为 Base64
- 把
.wav文件拖到框里,或者用文件选择器选择它。 - 在预览中播放一下。
- 输出为 已设为 Data URI。用于 API 时选择 纯 Base64;选 JSON 则会附带文件名、MIME 类型和大小。
- 点击 复制输出。超过几秒的录音会是很长的字符串,用 另存为 .txt 更方便处理。
Base64 WAV 会有多大
未压缩的 PCM 很容易计算:采样率 × 每个采样的字节数 × 声道数,就是每秒的字节数。加上标准的 44 字节文件头,再乘以 4/3 就是 Base64 的长度:
| 格式 | 1 秒 | 10 秒 | 1 分钟 |
|---|---|---|---|
| 8 kHz,单声道,16 位(电话) | 21,392 个字符 | 213,392 个字符 | 1,280,060 个字符 |
| 16 kHz,单声道,16 位(语音) | 42,728 个字符 | 426,728 个字符 | 2,560,060 个字符 |
| 44.1 kHz,单声道,16 位 | 117,660 个字符 | 1,176,060 个字符 | 7,056,060 个字符 |
| 44.1 kHz,立体声,16 位(CD) | 235,260 个字符 | 2,352,060 个字符 | 14,112,060 个字符 |
| 48 kHz,立体声,16 位 | 256,060 个字符 | 2,560,060 个字符 | 15,360,060 个字符 |
有些应用录制的文件带有存放元数据的额外块,所以实际大小可能略大一些。
WAV 和语音 API
语音识别服务通常接受未压缩的 16 位 PCM,因为它可以无损解码,也不需要编解码器。当它们在 JSON 请求中接收内联音频时,音频以 Base64 形式传入,同时还有描述编码、采样率和声道数的字段。这些值必须与文件一致。把 44.1 kHz 立体声录音声明为 16 kHz 单声道,会得到乱七八糟的转写结果或者报错。
语音模型通常以 16 kHz 单声道或更低的规格工作。编码前把 CD 音质的立体声录音转换为 16 kHz 单声道,请求会缩小约五倍半,通常也不会影响识别效果。请在音频编辑器中或用命令行转换工具完成这一步;本页面会按文件原样编码。
如果内联大小限制对长录音来说仍然太小,这些服务通常也接受指向存储中文件的链接,这样就完全不需要 Base64。
用 Python 生成 WAV 并编码
标准库就能写出 WAV 并编码,做测试数据很方便。下面生成一段 200 毫秒、880 Hz 的提示音:
import base64, io, math, struct, wave
rate = 8000
samples = b"".join(
struct.pack("<h", int(12000 * math.sin(2 * math.pi * 880 * i / rate)))
for i in range(rate // 5)
)
buf = io.BytesIO()
with wave.open(buf, "wb") as w:
w.setnchannels(1)
w.setsampwidth(2)
w.setframerate(rate)
w.writeframes(samples)
uri = "data:audio/wav;base64," + base64.b64encode(buf.getvalue()).decode()
文件为 3,244 字节,data URI 为 4,350 个字符,以 data:audio/wav;base64,UklGRqQMAABXQVZF 开头。文件和流的更多内容见 Python 中的 Base64。
反向转换
Base64 转 WAV 可以播放 Base64 WAV 字符串,并将其保存为文件。要为网页缩小音频,请使用压缩格式;大小对比见 MP3 转 Base64。
常见问题
为什么我的 WAV Base64 这么长?
WAV 通常存储的是未经压缩的原始 PCM 采样。一秒 CD 音质的立体声就是 176,400 字节音频数据,算上文件头,Base64 有 235,260 个字符。转换为单声道并降低采样率,能大幅缩短。
用 audio/wav 还是 audio/x-wav?
两者都在使用,浏览器都能播放。audio/wav 是常见的选择;一些较旧的系统会发送 audio/x-wav 或 audio/wave。工具使用你的浏览器报告的类型。
WAV 的 Base64 开头几个字符是什么意思?
UklGR 是 RIFF 容器头,WebP 和 AVI 也用它。WAVE 标记出现在第 12 到 16 个字符处,显示为 XQVZF,紧随其后的 Zm10 是 fmt 块。