转码微信 speex

H5 可以使用微信 jssdk 提供的录音接口,将录音上传到微信的服务器。而后端可以通过获取微信录音的接口下载录音。
录音有两种格式,一种是 8K 采样率的 amr 格式。还有一种是 16K 采样率的 speex 格式。speex 格式的录音更清晰,当然文件也更大。同样的录音,speex 格式大约是 amr 格式的 4 倍。但同时,amr 格式的录音失真十分严重。如果有播放、语音识别的需求,建议还是采用 speex 格式的录音。
不知出于什么考虑,微信对 speex 格式的录音做了加工,得使用 speex 官方解码库结合微信的解码库才能进行转码。
下文介绍如何使用 docker 编译可转码微信 speex 的程序。

编译

首先 git clone https://github.com/ppninja/wechat-speex-declib。该仓库在微信解码库示例 的基础上添加了 Makefile。
由于编译需要使用 linux,下文使用 ubuntu 16.04 作为示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 启动 ubuntu 16.04 的 docker 并运行 bash,绑定本机 wechat-speex-declib 的地址到 docker 的 /opt/speex 上
docker pull ubuntu:16.04
docker run -i -t --mount type=bind,source=(wechat-speex-declib 的绝对地址替换),target=/opt/speex ubuntu:16.04 /bin/bash

# 修改为阿里云的镜像源,提升 apt-get 的速度
cat > /etc/apt/sources.list << END
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
END

# 安装 gcc 等编译工具
apt-get build-essential
# 安装 speex 开发库
apt-get libspeex-dev

cd /opt/speex
make

注意这里安装的 speex 开发库是 libspeex-dev,而不是 speex。speex 库提供了 speex 编码、解码的命令行,而 libspeex-dev 库提供了开发所需的文件。

执行完后在 bin 目录下会新增 speex_decode,也就是编译出的可执行文件。
通过执行 ./speex_decode test.speex test.wav 就可以将微信定制的 speex 转码成标准的 wav 格式了。
提醒下,转码产生的 wav 格式未压缩,体积很大。可以通过 ffmpeg 等工具进行处理。

参考