微信開發之錄音檔案

Younger成發表於2019-07-09

一、呼叫微信錄音介面前端

1、獲取微信簽名

使用ajax去後臺獲取微信簽名

2、微信配置

wx.config({
				   // beta: true,// 必須這麼寫,否則wx.invoke呼叫形式的jsapi會有問題
				    debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
				    appId: data.appId, // 必填,企業微信的corpID
				    timestamp: data.timestamp, // 必填,生成簽名的時間戳
				    nonceStr: data.nonceStr, // 必填,生成簽名的隨機串
				    signature: data.signature,// 必填,簽名,見附錄1
				    jsApiList: ['startRecord','stopRecord','playVoice','onVoiceRecordEnd','uploadVoice'] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2
				});
				
				wx.ready(function(){
					//按下開始錄音
					$("#talk").on('touchstart',function(event){
						event.preventDefault();
					    START = new Date().getTime();
					    
					    recordTimer = setTimeout(function(){
					    	wx.startRecord({
					            success: function(){
					                localStorage.rainAllowRecord = 'true';
					                $("#start").css("display","block");
					            },
					            cancel: function () {
					                $("#start").css("display","block");
					                $("#start").html("使用者拒絕授權錄音");
					            }
					        });
					    },300);
					});
					
					//鬆手停止錄音
					$("#talk").on('touchend',function(event){
						event.preventDefault();
					    END = new Date().getTime();
					    
					    if((END - START) < 300){
					        END = 0;
					        START = 0;
					        //小於300ms,不錄音
					        clearTimeout(recordTimer);
					    }else{
					        wx.stopRecord({
					          success: function (res) {
					        	$("#end").css("display","block");
					            localId = res.localId;
					            uploadVoice();
					          },
					          fail: function (res) {
					        	  $("#end").css("display","block");
					        	  $("#end").html("錄音失敗!");
					            alert("失敗"+JSON.stringify(res));
					          }
					        });
					    }
					    uploadVoice();
					});
					
					//播放語音介面
					$("#bf").click(function(){
						wx.playVoice({
							localId: localId // 需要播放的音訊的本地ID,由stopRecord介面獲得
					    });
					})
					
					//監聽錄音自動停止介面
					wx.onVoiceRecordEnd({
					// 錄音時間超過一分鐘沒有停止的時候會執行 complete 回撥
						complete: function (res) {
							var localId = res.localId;
						}
					});
					
					//上傳錄音
					function uploadVoice(){
					    //呼叫微信的上傳錄音介面把本地錄音先上傳到微信的伺服器
					    //不過,微信只保留3天,而我們需要長期儲存,我們需要把資源從微信伺服器下載到自己的伺服器
					    wx.uploadVoice({
					        localId: localId, // 需要上傳的音訊的本地ID,由stopRecord介面獲得
					        isShowProgressTips: 1, // 預設為1,顯示進度提示
					        success: function (res) {
					            //把錄音在微信伺服器上的id(res.serverId)傳送到自己的伺服器供下載。
					            // data: JSON.stringify(res),
					            $.ajax({
					                url: basePath + '/weixin/video_insertVoice.do?serverId='+res.serverId,
					                type: 'post',
					                dataType: "json",
					                success: function (data) {
					                    alert('檔案已經儲存到伺服器!');
					                },
					                error: function (xhr, errorType, error) {
					                    console.log(error);
					                }
					            }); 
					        }
					    });
					}
				});
				
				wx.error(function(res){
				    // config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。
				});

頁面效果如下:

二、微信api的缺陷是儲存的錄音檔案不是mp3格式、而是amr檔案格式

後端需將amr轉換為MP3的格式並上傳到伺服器

	//1.呼叫微信提供的介面serverId獲取錄音的InputStream位元組流
	public InputStream getInputStream(String mediaId) {
		
		InputStream is = null;
	     HttpURLConnection http;
		 try {
			 String access_token=WxUtil.getAccessToken();
		     String url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token="+access_token+"&media_id="+serverId;
		      
		 	 URL urlGet = new URL(url);
		 	 http = (HttpURLConnection) urlGet.openConnection();
		     http.setRequestMethod("GET"); // 必須是get方式請求
		     http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		     http.setDoOutput(true);
		     http.setDoInput(true);
		     System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 連線超時30秒
		     System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 讀取超時30秒
		     http.connect();
		     // 獲取檔案轉化為byte流
		     is = http.getInputStream();
		 } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	       
	       
	    return is;
	}
	
	//2.將獲取到的位元組流儲存為amr檔案
	public String downloadMediaId( String mediaId,String savePath) {
	    String relfilePath = null;
	    InputStream inputStream = getInputStream(mediaId);
	    FileOutputStream fileOutputStream = null;
	    try {
	        //伺服器資源儲存路徑
	    	//臨時路徑
	    	//String path=TemplateUtil.getTempPath();
	        //String savePath = request.getSession().getServletContext().getRealPath("/") + "upload/" + DateUtil.getYear(new Date()) + "/wxmedia/audio/";
	        //savePath = savePath + "audio/"; 
	        String filename = String.valueOf(System.currentTimeMillis()) + ".amr";
	        relfilePath = savePath + filename;
	        File file = new File(savePath);
	        if (!file.exists()) {
	            file.mkdirs();
	        }
	        byte[] data = new byte[1024];
	        int len = 0;
	        fileOutputStream = new FileOutputStream(savePath + filename);
	        while ((len = inputStream.read(data)) != -1) {
	            // 判斷結果是否有錯
	            if (new String(data).indexOf("errmsg") > -1) {
	                return null;
	            }
	            fileOutputStream.write(data, 0, len);
	        }
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally {
	        if (inputStream != null) {
	            try {
	                inputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	        if (fileOutputStream != null) {
	            try {
	                fileOutputStream.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	    return relfilePath;
	}
	
	 /**
	  * @author yfc
	  * @createTime 2019年6月27日 下午2:29:34
	  * @description 4、音訊存入,將MP3檔案上傳至伺服器
	  */
	public void insertVoice(){
		logger.info("================================臨時檔案路徑:"+TemplateUtil.getTempPath());
		String sourcePath="d:/upload/a.mp3";
		String savepath=request.getSession().getServletContext().getRealPath("/") + "upload/" + DateUtil.getYear(new Date()) + "/wxmedia/audio/";
		logger.info("================================savepath:"+savepath);
		logger.info("================================serverId"+serverId);
		//目標路徑
		String targetPath=downloadMediaId(serverId,savepath);
		logger.info("================================targetPath:"+targetPath);
		//arm轉MP3
		changeToMp3(targetPath, sourcePath);  
		try {
			File fileName=new File(sourcePath);
			FileInputStream file;
			file = new FileInputStream(fileName);
			String path=FileStoreService.uploadFile("voice",System.currentTimeMillis()+".mp3" , file);
			logger.info("================================path:"+path);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	public static void main(String[] args) throws Exception {  
        String path1 = "D:/upload/1562649533821.amr";  
        String path2 = "D:/upload/a.mp3";  
        changeToMp3(path1, path2);  
    }  
  
	//3、將amr檔案轉換為mp3格式
    public static void changeToMp3(String sourcePath, String targetPath) {  
        File source = new File(sourcePath);  
        File target = new File(targetPath);  
        AudioAttributes audio = new AudioAttributes();  
        Encoder encoder = new Encoder();  
  
        audio.setCodec("libmp3lame");  
        EncodingAttributes attrs = new EncodingAttributes();  
        attrs.setFormat("mp3");  
        attrs.setAudioAttributes(audio);  
  
        try {  
            encoder.encode(source, target, attrs);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } 
    }  

三、依賴jar包

<!--amr檔案轉音訊map檔案-->
<dependency>
    <groupId>com.github.dadiyang</groupId>
    <artifactId>jave</artifactId>
    <version>1.0.3</version>
</dependency>

 

相關文章