問題
客戶端使用小程序,需要錄音功能然后到后臺頁面播放,由于微信提供的錄音API壓縮后的格式為 .silk格式的,但是這個格式其他播放器都是播放不了的,更何況html頁面的audio標簽更是不可能播放了,所以我們需要將.silk格式轉(zhuǎn)碼到mp3格式,因為mp3格式是最流行的音頻格式,不管手機音樂還是其他方面,MP3格式都是很經(jīng)??吹降?
前言遍尋網(wǎng)絡,只此一家將.silk轉(zhuǎn)碼到mp3的開源項目,可以說這兄弟非常牛了, github地址:?https://github.com/kn007/silk-v3-decoder??此牛的blog:?https://kn007.net/
為什么寫這篇文章呢,大概有兩點.
- 就是要記錄一下編程路上遇到的坑,保證以后不會再犯或者說以后犯了也可以很快找到問題所在并解決問題.
- 就是此牛的readme寫的不太好,第一次看都看不太懂,我在這里下了好大功夫,因為我菜嘛,這東西的確沒技術含量...對,就因為我菜嘛...
軟件解碼轉(zhuǎn)碼
- 去github下載此牛提供的插件
- 下載后這個樣子
- 打開windows文件夾,看到在windows平臺下的插件合集
- silk2mp3.exe是主程序,我們可以用此用戶交互界面進行解碼轉(zhuǎn)碼
- 打開主程序?qū)胄枰D(zhuǎn)碼文件開始轉(zhuǎn)換
-
?
-
- 轉(zhuǎn)換成功后便在輸出目錄顯示了.mp3格式的文件,然后你就可以播放了!
- 此處注意幾個坑! ? 因為.silk是騰訊壓縮后的格式,自然是不會特別大,一搬幾百k就ok了,如果你轉(zhuǎn)碼過程中非常緩慢(超過10秒),或者轉(zhuǎn)換后的文件體積過于龐大(我源文件500kb,開始是轉(zhuǎn)成pcm后250多兆,又轉(zhuǎn)成mp3后成了95兆)這種情況一律都是.silk源文件損壞或者不是標準的.silk文件導致的,你應該看一下這個文件從哪里來的,復制導入的時候有沒有損壞跡象,如果你的音頻文件是通過網(wǎng)絡上傳并且用編程語言寫入到磁盤的,那么你就應該著重看并且仔細的看一下你的IO代碼.八成就是這里出錯了.(比如我,就是IO寫錯了,導致浪費了太多時間)
- 用戶交互界面的轉(zhuǎn)碼到此結(jié)束,你可以聽到你美妙的聲音了.
代碼解碼轉(zhuǎn)碼
由于是需要客戶端上傳到服務器并且在后臺播放,所以肯定需要用代碼的方式實現(xiàn)解碼轉(zhuǎn)碼咯. 代碼方式也很簡單,其實本質(zhì)就是調(diào)用這個程序,傳幾個參數(shù)而已.?
基本的思路就是:
- 先將.silk源文件解碼為.pcm文件,具體原因百度即可
- 再講.pcm文件轉(zhuǎn)碼到.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文件進行轉(zhuǎn)碼工具類 * 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("轉(zhuǎn)碼到pcm..."); try { StringBuilder msg = Lang.execOutput(cmd, Encoding.CHARSET_GBK); System.out.println(msg); } catch (IOException e) { e.printStackTrace(); flag = false; } return flag; } /** * 轉(zhuǎn)碼為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("轉(zhuǎn)碼到mp3..."); try { StringBuilder sb = Lang.execOutput("cmd /c F:\開發(fā)工具包\轉(zhuǎn)碼一套\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; } }
本文摘自 :https://blog.51cto.com/u