【微信開發】上傳使用者語音 並轉碼 分享
好久沒有寫部落格了,這段時間遇到了很多問題都沒有記錄下來
今天剛好上線了一個小活動,期間遇到一些比較折騰的問題,撐著有時間記錄一下
需求
臨近聖誕節,運營組想了一個活動來拉新,活動的大概內容是這樣的;
使用者訪問活動首頁, 點選 【我想說】 然後呼叫微信的 JSDK 來錄音,錄完音之後上傳到微信的伺服器,然後 前端根據聲音生成一張聖誕樹形狀的聲波圖,使用者點選分享生成一張海報,其他使用者掃描二維碼可以收聽你分享的語音;然後別人參與活動的時候需要先關注公眾號;
這個需求很簡單吧,邏輯清晰的不行…好 開搞
查詢微信開發者文件
看完這些文件, 很棒!簡單! 微信該提供的都提供了
那梳理一下流程應該是這樣的
1、呼叫wx.startRecord();開始錄音
2、呼叫wx.stopRecord();結束錄音,可以得到 localId(注意這個並不是錄音存放在手機的路徑)
3、呼叫wx.uploadVoice()上傳錄音,需要傳入2拿到的localId; 微信會返回一個 serverId; (這個serverId 就是微信的素材檔案的mediaId;通過這個mediaId 可以從微信伺服器下載檔案的)
4、ok! 上傳成功了 分享的時候把這個serverId分享出去!
5、被分享人拿到這個serverId之後呼叫wx.downloadVoice();這個介面需要4的serverId,然後這個語音素材就下載到了使用者手機,並且返回了一個 localId(注意這個並不是錄音存放在手機的路徑)
6、使用者點選[播放語音] 則呼叫wx.playVoice()來播放語音,需要5返回的localId;
完美! 一個流程下來雖然步驟多了一點,但是並不是不可行啊,既然可行那就擼起袖子幹吧!
但是仔細一看 就發現有很多問題了
方案不足地方
1、
通過這種方式上傳的語音 屬於 【臨時素材】,只有3天的有效期!
那麼就直接將上面想到的方案給否定掉了,因為你分享出去之後過了3天別人就聽不到了!
2、上面的方案有個弊端就是 ,使用者收聽別人的語音都需要下載,每次都要下載是一件讓使用者很煩的一件事情;
3、通過微信 【下載臨時素材】介面下載語音素材的格式是 amr ; 如果通過微信 的wx.playVoice()播放可能沒什麼問題,但是這個方案,但是這個方案已經不行了,因為你不能通過wx.downloadVoice()下載語音了(3天有效期一過就不行);
提出新的方案
既然上面的方案不行,不足也很清楚, 那麼我們換種實現
主要思路:將檔案下載到我們自己的伺服器上,將amr格式轉碼成mp3等等 <audio 能夠播放的格式, 然後上傳到阿里雲OSS儲存,開放外部訪問,將OSS連結分享出去,直接播放這個連結就行了
詳細步驟:
1、呼叫wx.startRecord();開始錄音
2、呼叫wx.stopRecord();結束錄音,可以得到 localId(注意這個並不是錄音存放在手機的路徑)
3、呼叫wx.uploadVoice()上傳錄音,需要傳入2拿到的localId; 微信會返回一個 serverId; (這個serverId 就是微信的素材檔案的mediaId;通過這個mediaId 可以從微信伺服器下載檔案的)
(前面3個步驟不變 )
4、前端上傳完了之後,呼叫我的 【下載臨時素材到我們自己伺服器並且轉碼成MP3並且上傳到阿里雲OSS並且返回訪問連結】的介面
需要3獲取到的serverId(就是這裡的media_id)作為引數;
5、前端拿到了4中的 語音連結 然後分享出去帶上這個連結(連結太長可以自己做個對應)
6、被分享著點選播放 直接使用 元素 <audio 來播放這個連結
7、PS:千萬不要在 微信開發者工具中 除錯[上傳語音]的介面;它不支援的!
好 ! 流程這樣就沒有錯了, 但是正在做的時候猜的坑也不少
最主要的就是 4 中 【下載臨時素材到我們自己伺服器並且轉碼成MP3並且上傳到阿里雲OSS並且返回訪問連結】
這個介面踩得坑真的不少,最主要的就是轉碼;網上文章一艘沒有幾篇有價值的東西 ;
主要就是 呼叫 jave 這個jar包去轉碼, 其實最終這個jave 呼叫了一個叫做 ffmpeg 轉碼程式來轉碼的;然後這個程式不同環境還不一樣的
我的是Mac 然後伺服器又需要Linux版本的;
囉嗦我就不囉嗦了 , 推薦一個解決方案 ,我就是用的這種
這裡我提供一下 Mac版的 ffmpeg下載 ffmpeg-mac
特別注意 下載下來的檔案是 ffmpeg-mac
字尾 -mac是必須的,因為這個作者是按照這個路徑找的
public class changToMp3 {
public static void main(String[] args) throws Exception {
String path1 = "/Users/XXX/Desktop/voice/1111.amr";
String path2 = "/Users/XXX/Desktop/voice/1111.mp3";
System.setProperty("ffmpeg.home", "/Users/XXX/Desktop/voice/");
it.sauronsoftware.jave.AudioUtils.amrToMp3(path1, path2);
}
}
再上傳一個Linux版本的提供下載:ffmpeg for linux
如果還有windows版本的 或者上面我發的不支援的;可以去官網自己下載 地址:FFMPEG下載
下載完解壓之後 找到對應程式 放到某個路徑 然後 程式碼設定的路徑跟程式路徑一直即可!
貼一下關鍵程式碼:
@Override
public RpcResult<PutResult> amr2mp3Upload2OSS(String gzhAppid, String mediaId,String ossDirKey) {
RpcResult result = new RpcResult();
PutResult p = new PutResult();
String filepath ;String name ;
try {
//下載臨時檔案到 伺服器本地
File file = WxMpConfiguration.getMpServices().get(gzhAppid).getMaterialService().mediaDownload(mediaId);
if(file == null){
result.setFail("-1", "操作失敗,mediaId 不存在或已過期");
return result;
}
filepath = file.getPath();
name = file.getName();
name = name.replace(".amr",".mp3");
} catch (WxErrorException e) {
result.setFail(e.getError().getErrorCode()+"", e.getError().getErrorMsg());
return result;
}
//設定 使用轉碼軟體的 程式地址 (要在對應的地址有這個執行指令碼)
System.setProperty("ffmpeg.home", ffmpeg);
String targetPath = mp3_path+name;
//轉碼之後存到本地伺服器
it.sauronsoftware.jave.AudioUtils.amrToMp3(filepath, targetPath);
PutResult putResult = mossClient.putObject(ossDirKey+ UUID.randomUUID(),new File(targetPath));
BeanUtils.copyProperties(putResult,p);
result.setResult(p);
result.setSuccess();
return result;
}
PS: 在呼叫 wx.uploadVoice() 的介面 千萬不要在 微信開發者工具中測試,它不支援,每次返回的都是一樣的數,這個要在手機端測試
轉碼程式一定要接到放到目標伺服器上,並且有可以執行的許可權(X的許可權)
微信開發者配置記得配置JS安全域名不然不能夠呼叫介面
給微信開發者推薦一個開源專案
推薦:班納睿 / weixin-java-tools
真的強,基於這個開發特別方便! 強推!