问题
客户端使用小程序,需要录音功能然后到后台页面播放,由于微信提供的录音API压缩后的格式为 .silk格式的,但是这个格式其他播放器都是播放不了的,更何况html页面的audio标签更是不可能播放了,所以我们需要将.silk格式转码到mp3格式,因为mp3格式是最流行的音频格式,不管手机音乐还是其他方面,MP3格式都是很经常看到的.
前言
遍寻网络,只此一家将.silk转码到mp3的开源项目,可以说这兄弟非常牛了, github地址: https://github.com/kn007/silk-v3-decoder 此牛的blog: https://kn007.net/
为什么写这篇文章呢,大概有两点.
- 就是要记录一下编程路上遇到的坑,保证以后不会再犯或者说以后犯了也可以很快找到问题所在并解决问题.
- 就是此牛的readme写的不太好,第一次看都看不太懂,我在这里下了好大功夫,因为我菜嘛,这东西的确没技术含量...对,就因为我菜嘛...
解决方案
软件解码转码
- 去github下载此牛提供的插件
- 下载后这个样子
- 打开windows文件夹,看到在windows平台下的插件合集
- silk2mp3.exe是主程序,我们可以用此用户交互界面进行解码转码
- 打开主程序导入需要转码文件开始转换
- 转换成功后便在输出目录显示了.mp3格式的文件,然后你就可以播放了!
- 此处注意几个坑! 因为.silk是腾讯压缩后的格式,自然是不会特别大,一搬几百k就ok了,如果你转码过程中非常缓慢(超过10秒),或者转换后的文件体积过于庞大(我源文件500kb,开始是转成pcm后250多兆,又转成mp3后成了95兆)这种情况一律都是.silk源文件损坏或者不是标准的.silk文件导致的,你应该看一下这个文件从哪里来的,复制导入的时候有没有损坏迹象,如果你的音频文件是通过网络上传并且用编程语言写入到磁盘的,那么你就应该着重看并且仔细的看一下你的IO代码.八成就是这里出错了.(比如我,就是IO写错了,导致浪费了太多时间)
- 用户交互界面的转码到此结束,你可以听到你美妙的声音了.
代码解码转码
由于是需要客户端上传到服务器并且在后台播放,所以肯定需要用代码的方式实现解码转码咯. 代码方式也很简单,其实本质就是调用这个程序,传几个参数而已.
基本的思路就是:
- 先将.silk源文件解码为.pcm文件,具体原因百度即可
- 再讲.pcm文件转码到.MP3格式
那基本步骤就是:
- 我直接贴代码吧,也没啥好写的...
import org.nutz.lang.Encoding; import org.nutz.lang.Lang; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * Describe:针对silk文件进行转码工具类 * Author:陆小不离 * Age:Eighteen * Time:2017年5月27日 10:12:06 */ public class DeCoder { public static void main(String[] args){ String skil = "F:\zhuanma\vg2ub41omgipvrmur1fnssd3tq.silk"; String pcm = "F:\zhuanma\vg2ub41omgipvrmur1fnssd3tq.pcm"; String mp3 = "F:\zhuanma\vg2ub41omgipvrmur1fnssd3tq.mp3"; boolean b = getPcm(skil,pcm); System.out.println(b); if (b) getMp3(pcm,mp3); } /** * 解码为pcm格式 * @param silk 源silk文件,需要绝对路径!! 例:F:zhuanmavg2ub41omgipvrmur1fnssd3tq.silk * @param pcm 目标pcm文件,需要绝对路径!! 例:F:zhuanmavg2ub41omgipvrmur1fnssd3tq.pcm * @return */ public static boolean getPcm(String silk,String pcm){ boolean flag = true; String cmd="cmd.exe /c F:\zhuanma\silk_v3_decoder.exe "+silk+" "+pcm+" -quiet"; System.out.println("转码到pcm..."); try { StringBuilder msg = Lang.execOutput(cmd, Encoding.CHARSET_GBK); System.out.println(msg); } catch (IOException e) { e.printStackTrace(); flag = false; } return flag; } /** * 转码为MP3格式 * @param pcm 源pcm文件,需要绝对路径!! 例:F:zhuanmavg2ub41omgipvrmur1fnssd3tq.pcm * @param mp3 目标mp3文件,需要绝对路径!! 例:F:zhuanmavg2ub41omgipvrmur1fnssd3tq.mp3 * @return */ public static boolean getMp3(String pcm,String mp3){ boolean flag = true; System.out.println("转码到mp3..."); try { StringBuilder sb = Lang.execOutput("cmd /c F:\开发工具包\转码一套\ffmpeg-20170130-cba4f0e-win64-static\bin\ffmpeg.exe -y -f s16le -ar 24000 -ac 1 -i "+pcm+" "+mp3+"", Encoding.CHARSET_GBK); System.out.println(sb); } catch (IOException e) { e.printStackTrace(); flag = false; } return flag; } }
注意: 我的代码依赖于优秀的国产框架Nutz(http://www.nutzam.com/),非常牛叉的Java框架,涵盖MVC,IOC,AOP,DAO,JSON,Castors,Lang,Resource等等一些非常实用的功能,而且全文档中文!全代码注释中文!在拥有这么多功能的情况下它却只是一个小小的jar,没有任何依赖! 极具Ji情的社区,万能的wendal大叔时刻秒回您的问题,为您的项目保驾护航! 还在犹豫什么,这么好的国产,赶紧脱坑吧~
版权所有.转载请注明出处.