1. 程式人生 > >【微信開發】上傳使用者語音 並轉碼 分享

【微信開發】上傳使用者語音 並轉碼 分享

好久沒有寫部落格了,這段時間遇到了很多問題都沒有記錄下來
今天剛好上線了一個小活動,期間遇到一些比較折騰的問題,撐著有時間記錄一下


需求

臨近聖誕節,運營組想了一個活動來拉新,活動的大概內容是這樣的;
使用者訪問活動首頁, 點選 【我想說】 然後呼叫微信的 JSDK 來錄音,錄完音之後上傳到微信的伺服器,然後 前端根據聲音生成一張聖誕樹形狀的聲波圖,使用者點選分享生成一張海報,其他使用者掃描二維碼可以收聽你分享的語音;然後別人參與活動的時候需要先關注公眾號;
這個需求很簡單吧,邏輯清晰的不行…好 開搞

查詢微信開發者文件

微信開發者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版本的;
囉嗦我就不囉嗦了 , 推薦一個解決方案 ,我就是用的這種

Amr轉Mp3

這裡我提供一下 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

真的強,基於這個開發特別方便! 強推!