如何转码微信多媒体下载接口的音频文件?

Humphry
  • 16.3k

由于微信服务器只会暂存多媒体文件三天,需要在自己的服务器上存储并转码。
我使用了微信的多媒体下载接口下载了之前使用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 cloneconfiguremake install后,编译了里面的speexdec.c文件,尝试执行的结果是:
This doesn't look like a Speex file——失败

4. 辅助信息

  1. 文件没有在传输过程中损坏:从浏览器和从后端获取该微信地址是一样的文件;
  2. 不存在单次录音文件损坏的原因:尝试了很多个不一样的通过jssdk上传的录音文件;
回复
阅读 15.7k
8 个回答

微信团队昨晚已经解决speex文件的问题,早上测试了页面录语音OK,返回amr格式的文件

Humphry
  • 16.3k

微信jssdk语音接口上传的文件类型为speex,第三方在自己的网页无法直接播放(微信团队已经确认该问题,正在努力解决中,预计本周上线优化此问题)(http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.955-.E5.B8.B8.E8.A7.81.E9.94.99.E8.AF.AF.E5.8F.8A.E8.A7.A3.E5.86.B3.E6.96.B9.E6.B3.95)


更新:

之前微信jssdk语音接口上传的文件类型为speex,第三方在自己的网页无法直接播放(微信团队确认了该问题,并已在本周上线解决了此问题,第三方可以通过多媒体接口下载得到标准的amr音频文件) ref

经确认,现在接口返回的是amr,已可以用ffmpeg转码。


ffmpeg -i test.mp3 -ar 8k -ac 1 test.amr
(libopencore_amrnb支持程度有限)
ffmpeg -i test.amr -ar 44100 -ab 128k test.mp3
(微信的离奇的没有错误的转出参数)
杨絮sunny
  • 3
新手上路,请多包涵

这个问题我回答下吧,因为之前有做过这个功能。

其实通过api返回的文件流并不是你说的格式, 而应该是 amr 格式的 。所以这就好办了。

我用的是ubuntu服务器, 所以在获取到返回的数据后保存为 amr ,然后通过ffmpeg转码为mp3就可以正常永久保存了

毛里求斯
  • 2
新手上路,请多包涵

我也遇到这个问题了,时而收到speex格式的语音,时而收到amr格式的语音

天平座11
  • 1
新手上路,请多包涵

您好,现在为什么还是 speex 接口呢? 直接发送的语音 ,file.api.weixin.qq.com 下载 的仍然是 speex

zsn19940125
  • 1
新手上路,请多包涵

微信的多媒体下载接口 这个你用起了吗?我这个不行,请问是怎样用的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏