1. 程式人生 > >微信jssdk圖片、語音開發記錄(二)

微信jssdk圖片、語音開發記錄(二)

後臺 pid for item esc 音頻 locals 動態 clas

接著上篇說的,在使用jssdk之前,需要先驗簽,也就是獲取簽名,而獲取簽名就需要幾個參數,時間戳,隨機數,token等,而token一天的獲取次數是有限的,

所以需要在項目中保存獲取到的token,每次請求token之前先獲取緩存的token,比較一下是否過期,過期的話再請求獲取。

這篇主要說說,jssdk的調用,

所有jssdk的使用都是基礎驗簽成功,並且js必須放在wx.ready{function(){ }}裏面。

在我的項目中目前只用到了選擇照片,預覽照片,照片的上傳下載,語音的上傳下載等

window.onload = function() {
        $.ajax({
            contentType : 
"application/x-www-form-urlencoded; charset=utf-8", type : "post", url : "weixin?getsignature", data : { url : location.href.split(‘#‘)[0] }, dataType : "json", success : function(data) { console.log(data.appId
+ "\n " + data.nonceStr + "\n " + data.signature); console.log("==data==" + data); wx.config({ debug : false,// 打開調試 appId : data.appId, timestamp : data.timestamp, nonceStr : data.nonceStr, signature : data.signature, jsApiList : [
‘startRecord‘, ‘stopRecord‘, ‘onVoiceRecordEnd‘, ‘playVoice‘, ‘pauseVoice‘, ‘stopVoice‘, ‘onVoicePlayEnd‘, ‘uploadVoice‘, ‘downloadVoice‘, ‘chooseImage‘, ‘previewImage‘, ‘uploadImage‘, ‘downloadImage‘ ] }); } }); } var maxCount = 9; // 5.1 拍照、本地選圖 var images = { localId : [], serverId : [] }; // 定義變量 var START, END, recordTimer; var localStorage = { rainAllowRecord : ‘true‘ } var voice = { localId : [] } wx.ready(function() { console.log("ready...."); // 最大上傳圖片數量 // document.querySelector(‘#chooseImage‘).onclick = function() { wx.chooseImage({ count : 9, // 默認同時選擇9張照片 sizeType : [ ‘original‘, ‘compressed‘ ], // 可以指定是原圖還是壓縮圖,默認二者都有 sourceType : [ ‘album‘, ‘camera‘ ], // 可以指定來源是相冊還是相機,默認二者都有 success : function(res) { images.localId = res.localIds;// 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片 console.log(res.localIds);           //如果選擇多張照片,該res.localIds是一個數組,可以遍歷顯示到頁面上,如果想要預覽照片,在wx.ready裏面才能預覽照片 $(res.localIds).each(function(index, val) { $(".chat-thread").append("<li class=‘right‘ ><div class=‘stu_answer_item‘><span class=‘stu_answer_item_text‘><img class=‘answer_image‘ onclick=‘showImage(this)‘ width=‘60px‘ height=‘60px‘ src=‘" + val + "‘/></span></div></li>"); });           //展示區域,動態顯示到最底部 $(‘.chat-thread‘).scrollTop($(‘.chat-thread‘)[0].scrollHeight);           //選擇完照片直接上傳到微信服務器,這裏沒有做照片的選擇刪除操作 $("#uploadImage").click(); console.log(‘已選擇 ‘ + res.localIds.length + ‘ 張圖片‘); console.log(‘一共 ‘ + images.localId.length + ‘ 張圖片‘); } }); }; /** * 5.3 上傳圖片路徑需要修改 */ document.querySelector(‘#uploadImage‘).onclick = function() { if (images.localId.length == 0) { console.log(‘請先選擇圖片‘); return; } var i = 0, length = images.localId.length; images.serverId = []; function upload() { wx.uploadImage({ localId : images.localId[i], success : function(res) { i++; images.serverId.push(res.serverId); console.log("res.serverId") console.log(res.serverId) // images.serverId = res.serverId; // 返回圖片的服務器端ID var answervalues = $("#answervalues").val(); // 給服務端id加圖片標誌方便後臺處理,nvalue是上傳到後臺的數據,用冒號分割數據處理,是文本就直接保存,後綴名一致的時候表示是圖片或者語音需要下載到我的服務器端方便項目中調用
              原因是在微信服務器端保存的數據期限較短,
var nvalue = answervalues + ‘:‘ + res.serverId + ".SUFFIX_JPG_JPEG_PICTURE"; $("#answervalues").val(nvalue); if (i < length) { upload();// 遞歸上傳 } }, fail : function(res) { console.log(JSON.stringify(res)); } }); } upload(); }; // TODO 5.4 下載圖片,該功能盡量少用,微信服務器下載有次數限制,如果使用量少的話可以使用 document.querySelector(‘#downloadImage‘).onclick = function() { if (images.serverId.length === 0) { console.log(‘請先上傳圖片‘); return; } var i = 0, length = images.serverId.length; images.localId = []; function download() { wx.downloadImage({ serverId : images.serverId[i], success : function(res) { i++; console.log(‘已下載:‘ + i + ‘/‘ + length); images.localId.push(res.localId); if (i < length) { download(); } } }); } download(); };
  /**錄音鍵,在頁面上寫一個按鈕,按下的時候錄音*/ $(
‘#wenwen‘).on(‘touchstart‘, function(event) { console.log("按住錄音。。"); event.preventDefault();     //給按下圖標變化 $(‘.wenwen_text‘).css(‘background‘, ‘#c1c1c1‘); $(‘.wenwen_text span‘).css(‘color‘, ‘#fff‘); $(‘.saying‘).show();     //記錄按下時間,時間過短則不使用錄音功能 START = new Date().getTime();     //這裏是0.3秒 recordTimer = setTimeout(function() { wx.startRecord({ success : function() { localStorage.rainAllowRecord = ‘true‘; }, cancel : function() { console.log(‘用戶拒絕授權錄音‘); } }); }, 300); }); // 松手結束錄音 $(‘#wenwen‘).on(‘touchend‘, function(event) { event.preventDefault(); END = new Date().getTime(); $(‘.wenwen_text‘).css(‘background‘, ‘#fff‘); $(‘.wenwen_text .circle-button‘).css(‘color‘, ‘#666‘); $(‘.saying‘).hide(); console.log("結束錄音"); if ((END - START) < 300) { END = 0; START = 0; // 小於300ms,不錄音 console.log("小於300ms,不錄音"); clearTimeout(recordTimer); } else { console.log("大於300ms,錄音"); wx.stopRecord({ success : function(res) { voice.localId = res.localId;
            //錄音結束上傳錄音 uploadVoice(res.localId); }, fail :
function(res) { console.log(JSON.stringify(res)); } }); } }); // 上傳錄音 function uploadVoice(reslocalId) { // 調用微信的上傳錄音接口把本地錄音先上傳到微信的服務器 // 不過,微信只保留3天,而我們需要長期保存,我們需要把資源從微信服務器下載到自己的服務器 wx.uploadVoice({ localId : voice.localId, // 需要上傳的音頻的本地ID,由stopRecord接口獲得 isShowProgressTips : 1, // 默認為1,顯示進度提示 success : function(res) {           //上傳成功後再頁面顯示一個圖標用於播放錄音 $(".chat-thread").append("<li class=‘right‘ ><div class=‘stu_answer_item‘><span class=‘stu_answer_item_text‘><img class=‘answer_voice‘ onclick=‘play_voice(this)‘ width=‘60px‘ height=‘25px‘ src=‘image/yj/media.png‘/><input type=\"text\" value=‘" + reslocalId + "‘ style=\"display: none;\"></span></div></li>"); $(‘.chat-thread‘).scrollTop($(‘.chat-thread‘)[0].scrollHeight); var value = $("#answervalues").val(); var nvalue = value + ‘:‘ + res.serverId + ".SUFFIX_MP3_RADIO_VOICES"; $("#answervalues").val(nvalue); } }); } // 註冊微信播放錄音結束事件【一定要放在wx.ready函數內】 wx.onVoicePlayEnd({ success : function(res) { stopWave(); } }); }); // 切換輸入文字 function to_write() { $(‘.wenwen_btn img‘).attr(‘src‘, ‘image/wx/yy_btn.png‘); $(‘.wenwen_btn‘).attr(‘onclick‘, ‘to_say()‘); $(‘.write_box,.wenwen_help button‘).show(); $(‘.circle-button,.wenwen_help a‘).hide(); $(‘.write_box input‘).focus(); for_bottom(); } // 切換輸入語音 function to_say() { $(‘.write_list‘).remove(); $(‘.wenwen_btn img‘).attr(‘src‘, ‘image/wx/jp_btn.png‘); $(‘.wenwen_btn‘).attr(‘onclick‘, ‘to_write()‘); $(‘.write_box,.wenwen_help button‘).hide(); $(‘.circle-button,.wenwen_help a‘).show(); } // 發送文字到緩存區顯示 function up_say() { $(‘.write_list‘).remove(); var a = $(‘.write_box input‘).val().replace(":", ":"); if (a != "") { if (a.indexOf("{") != -1 || a.indexOf("}") != -1 || a.indexOf("\\") != -1 || a.indexOf("/") != -1 || a.indexOf("\"") != -1 || a.indexOf("]") != -1 || a.indexOf("[") != -1) { console.log("<fmt:message key=‘special_character‘/>"); return; } else { $(".chat-thread").append("<li class=‘right‘><div class=‘stu_answer_item‘><span class=‘stu_answer_item_text‘>" + a + "</span></div></li>"); } var value = $("#answervalues").val(); var nvalue = value + ‘:‘ + a; $("#answervalues").val(nvalue); $(‘.write_box input‘).val(‘‘); $(‘.write_box input‘).focus(); $(‘.chat-thread‘).scrollTop($(‘.chat-thread‘)[0].scrollHeight); } } // 顯示輸入input的文字,單獨顯示在一個div中,方便查看 function keyup() { var footer_height = $(‘.wenwen-footer‘).outerHeight(), text = $(‘.write_box input‘).val(), str = ‘<div class="write_list">‘ + text + ‘</div>‘; if (text == ‘‘ || text == undefined) { $(‘.write_list‘).remove(); } else { $(‘.wenwen-footer‘).append(str); $(‘.write_list‘).css(‘bottom‘, footer_height); } } function for_bottom() { var speak_height = $(‘.speak_box‘).height(); $(‘.speak_box,.speak_window‘).animate({ scrollTop : speak_height }, 500); } // 綁定圖片點擊事件 function showImage(node) { var thisimg = $(node).attr(‘src‘); var imglist = $(‘.answer_image‘); var srcs = new Array(); for (var i = 0; i < imglist.length; i++) { srcs.push(imglist.eq(i).attr(‘src‘)); } console.log(‘srcs=‘ + srcs); console.log(‘thisImage=‘ + thisimg); wx.ready(function() { wx.previewImage({ current : thisimg, // 當前顯示圖片的http鏈接 urls : srcs // 需要預覽的圖片http鏈接列表 }); }); } // 播放錄音 function play_voice(node) { var voice_localId = $(node).parent().find("input").val(); wx.ready(function() { wx.playVoice({ localId : voice_localId }); }); }


function submit(){
//這個是包含了文本,語音的serverId,圖片的serverId
var value = $("#answervalues").val();
$.ajax({
contentType : "application/x-www-form-urlencoded; charset=utf-8",

type : "post",
url : "xxx?xxxx",
data : {
answer: value
},
success : function(result) {

}
});


}

後臺的處理

 /**
     * 下載文件
     * 
     * @param media_id
     *            微信jssdk上傳成功返回的serverId
     * @param answer
     * @param asmId
     */
    public void downloadMedia(String media_id, StuAnswerItem answer, String asmId)
    {

        String access_token = weixinService.getAccessToken();
        String url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + access_token + "&media_id="
                + media_id;
    //下載路徑,自定義
        String uploadFileDir = Constants.PATH_FILE + Utils.groupUserId(getCurrentUserId()) + "/" + asmId + "_a/"
                + asmId + "0/";
        Utils.makeSureDirExists(uploadFileDir);//不存在的話可以創建該路徑

        // 微信音頻文件默認是amr格式,需要將serverId下載成amr格式之後再轉換成mp3格式,由於項目的原因這裏只是做大概的
      描述,更簡單的是直接上傳到服務器,不需要判斷是圖片或者語音,而我這裏事先處理了相應的數據,到這裏是需要判斷,該文件的類型,
String fileName = answer.getAnswerItem().replace("mp3", "amr"); fileName = uploadFileDir + fileName; System.out.println("文件路徑+名稱==" + fileName); // 下載圖片到本地服務器 download(url, fileName, answer.getAnswerType()); } /** * 下載多媒體文件到服務器 * * @param url * 微信語音圖片下載url * @param filename * 保存至服務器的路徑和文件名 * @param mediaType * 自定義多媒體的類型,此處根據上面定義的2代表圖片,3代表音頻 * @return */ public boolean download(String url, String filename, int mediaType) { try { HttpGet httpGet = new HttpGet(url); HttpResponse response = client.execute(httpGet); if (response.getStatusLine().getStatusCode() == 200) { System.out.println("url下載請求code===200"); InputStream is = response.getEntity().getContent(); OutputStream out = new FileOutputStream(filename); byte[] b = new byte[1024]; int size = is.read(b); while (size > 0) { out.write(b, 0, size); size = is.read(b); } out.close(); is.close(); System.out.println("download success!!");           //如果是語音消息,則需要將下載下來的格式轉換為mp3格式,方便安卓和iso的調用,沒做過比較,amr格式的音頻在iso中的兼容性似乎不理想,這裏直接轉 if (mediaType == 3) { changeToMp3(filename, filename.replace("amr", "mp3")); } } httpGet.releaseConnection(); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 把amr格式的語音轉換成MP3, * * @Title: changeToMp3 * @Description: TODO(把amr格式的語音轉換成MP3) * @author pll * @param @param sourcePath amr格式文件路徑 * @param @param targetPath 存放mp3格式文件路徑 * @return void 返回類型 * @throws */ public static void changeToMp3(String sourcePath, String targetPath) { System.out.println("sourcePath====" + sourcePath); System.out.println("targetPath====" + 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); System.out.println("====change to mp3 successful===="); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); } catch (InputFormatException e) { System.out.println(e.getMessage()); } catch (EncoderException e) { System.out.println(e.getMessage()); } // System.out.println("刪除amr文件"); source.delete(); }

特別標註一下,項目中,amr格式轉mp3格式是使用ffmpeg,需要下載一個包jave-ffmpegjave-1.0.2.jar

jar包鏈接

微信jssdk圖片、語音開發記錄(二)