由于微信服务器只会暂存多媒体文件三天,需要在自己的服务器上存储并转码。
我使用了微信的多媒体下载接口下载了之前使用jssdk录制的文件。微信的多媒体下载接口返回header是Content-disposition: attachment; filename="xxxxx.speex"
、Content-Type: audio/x-speex-with-header-byte; rate=16000
,看起来就像是一个speex文件。
我试了很多方式打开/解码这个“speex”文件,得到的文件似乎缺失了一部分信息,无法成功打开/解码。网上相关文档很少,多半是介绍怎样在 c / obj-c 的层面做音频流处理的。
问题来了:如何转码微信的音频文件?
以下是我的尝试过程:
1. 尝试播放:
使用Windows Media Player + 插件Xiph.Org's DirectShow Filters尝试播放此文件,提示:
“Windows Media Player 在播放文件时遇到问题。”——失败
2. 尝试使用ffmpeg解码speex文件:
我使用了ffmpeg官网上静态编译的版本ffmpeg-release-64bit-static.tar.xz(已包含关键库libspeex),使用以下命令尝试解码:~/ffmpeg-2.5.3-64bit-static/ffmpeg -acodec libspeex -i a.speex output.wav
返回值是这样的:
[aac @ 0x3dace60] Format aac detected only with low score of 1, misdetection possible!
[libspeex @ 0x3dad8c0] Invalid sample rate: 0
Decoding as 32kHz ultra-wideband
[libspeex @ 0x3dad8c0] Invalid channel count: 0.
Decoding as stereo.
[aac @ 0x3dace60] Estimating duration from bitrate, this may be inaccurate
Input #0, aac, from 'a.speex':
Duration: 00:00:14.86, bitrate: 24 kb/s
Stream #0:0: Audio: speex, 32000 Hz, stereo, s16, 24 kb/s
Output #0, wav, to 'output.wav':
Metadata:
ISFT : Lavf56.15.102
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 32000 Hz, stereo, s16, 1024 kb/s
Metadata:
encoder : Lavc56.13.100 pcm_s16le
Stream mapping:
Stream #0:0 -> #0:0 (speex (libspeex) -> pcm_s16le (native))
Press [q] to stop, [?] for help
notification: More than two wideband layers found. The stream is corrupted.
[libspeex @ 0x3db0180] Error decoding Speex frame.
Error while decoding stream #0:0: Invalid data found when processing input
notification: Invalid mode encountered. The stream is corrupted.
[libspeex @ 0x3db0180] Error decoding Speex frame.
Error while decoding stream #0:0: Invalid data found when processing input
notification: Invalid mode encountered. The stream is corrupted.
size= 80kB time=00:00:00.64 bitrate=1025.0kbits/s
video:0kB audio:80kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.095215%
最终输出的声音只有640毫秒,跟录制的声音一点关系都没有
看起来自动识别的格式有问题,如果输入~/ffmpeg-2.5.3-64bit-static/ffmpeg -f spx -acodec libspeex -i a.speex output.wav
强制文件格式为spx
,则提示Unknown input format: 'spx'
。
——失败
3. 尝试解码x-speex-with-header-byte
:
搜索引擎告诉我这是谷歌曾经的语音识别接口接收的文件类型,有一个三年前停止更新的github项目可以解码,git clone
、configure
、make install
后,编译了里面的speexdec.c文件,尝试执行的结果是:This doesn't look like a Speex file
——失败
4. 辅助信息
- 文件没有在传输过程中损坏:从浏览器和从后端获取该微信地址是一样的文件;
- 不存在单次录音文件损坏的原因:尝试了很多个不一样的通过jssdk上传的录音文件;
微信团队昨晚已经解决speex文件的问题,早上测试了页面录语音OK,返回amr格式的文件