我的語音實現

此處輸入圖片的描述

本身挖的坑,果真要本身填!html

因爲以前開啓了CRSF,想加強安全性。過了一段時間,本身吧這事給忘了,致使JS的ajax消息沒法發送到後臺,一直提示400 BAD request。找了很久才發現,詳情前端

可是也找到個能夠檢測而且建議的辦法,ajax提供error反饋錯誤信息。程序員

$.ajax({
    url: "/profile/{{ user_id }}",
    type: 'POST',
    data: {data: "failed"},
    error: function(e) { //增長錯誤反饋
        console.log(e);
    }
})
.done(function (data) {
    console.log(data);
});

先後端交互

  • 訪問我的主頁(wx_config)ajax

  • 微信上傳語音數據庫

  • 傳遞mediaId和record_time到後臺segmentfault

  • 獲取token從微信下載語音後端

  • 上傳語音到qiniu(發起任務轉換amr爲mp3)緩存

  • 存儲url+time到數據庫安全

下載語音

獲取token和ticket

說明一下:兩處須要用到access_token,一是在微信帳號綁定的域名下使用JS-SDK上傳文件時,經過token來生成ticket來初始化JS-SDK;二是在下載文件時須要認證號產生的token。服務器

本覺得JS-SDK的可使用未認證帳號來產生access_token從而產生ticket用於JS端上傳數據,從而避免出現提示「XXXX」須要使用錄音功能。可是下載時發現,微信會校驗mediaId是否來自同一個公衆號(不校驗纔怪勒)。因此上傳和下載必須使用同一個已認證微信公衆號的APPID和APPSECRET來產生token。

兩個不一樣的服務器都須要token和ticket,爲了不搶走致使一方失效。一個服務器產生token和ticket存於緩存中,每小時更新一次(微信限制天天不超過2000次),並提供其餘服務器獲取token和ticket的接口。其餘服務器須要使用直接經過接口獲取便可。

錄音時間

錄音時間不須要單獨存儲,直接存儲在audio的連接中,經過錨點的方式
http://7xogxw.com1.z0.glb.clouddn.com/2015-11-26 23:11:06.709113#time23
每次讀取audio_url,先分割獲取錄音時間,url和time分別傳到前端渲染。

真正的自適應:關於圖片,之後能夠經過相似的方式,用錨點記錄圖片的實際長寬,而在前端加載以前,經過url便可獲取長寬數據,從而根據設備實際分辨率,折算合適長寬併發起請求,減小大圖加載緩慢。同時能夠在圖片加載以前就能夠生成固定比例的圖片佔位符,避免加載過程當中出現頁面跳動。

上傳語音

上傳文件

以前已經實現過七牛圖片的上傳,可是當初的接口複雜難用(@Lee 佩服),想着要修改以前的上傳接口來上傳語音文件,我決定仍是使用最新qiniu-sdk來上傳文件,以前圖牀是用到過,使用簡潔了不少。

可是一個麻煩的問題,新版本的sdk向下兼容性不是很好,若是使用最新的,以前的會報錯,具體不知。而要去修改以前的接口和上傳部分代碼,工做量太大,因而兩個版本sdk同時使用,導入新的包爲qiniu2,修改全部引用qiniu位置爲qiniu2,OK,一切正常。

通常狀況,直接獲取token上傳數據,至關簡單。

import qiniu2
from datetime import datetime
import config
from qiniu2 import BucketManager
import base64

def get_token():
    q = qiniu.Auth(config.QINIU_ACCESS_KEY, config.QINIU_SECRET_KEY)
    token = q.upload_token(config.PIC_BUCKET)
    return token
    
up_token, key = upload.get_token()
ret, info = qiniu2.put_data(up_token, key, resp)
assert ret['key'] == key

格式轉換

而微信默認amr格式,html不支持。上傳語音須要預處理,須要policy用於存儲轉換的格式、另存到位置和名稱等信息來產生up_token。而且若是policy和put_data中的key相同且bucket相同,便可同名覆蓋,減小空間使用。

這一段單獨看七牛的文檔你是啥也看不到的,只告訴你預處理格式。segmentfault上有七牛程序員入駐,可查到不少東西

def get_token():
    q = qiniu2.Auth(config.QN_ACCESS_KEY, config.QN_SECRET_KEY)
    # 文件名稱
    key = str(datetime.now())
    # 轉換格式
    format = "avthumb/ogg"
    # 另存到bucket和對應名稱key
    entry_uri = config.AUDIO_BUCKET + ':' + key
    entry_uri = "saveas/"+ base64.urlsafe_b64encode(entry_uri)
    # 獨立隊列audioQueue轉換
    policy = {
        "persistentOps": format + "|" + entry_uri,
        "persistentPipeline": "audioQueue"
    }
    token = q.upload_token(config.AUDIO_BUCKET, policy=policy)
    return token, key

up_token, key = upload.get_token()
ret, info = qiniu2.put_data(up_token, key, resp)
assert ret['key'] == key

刪除文件

上傳新的語音的時候,須要刪除原來的語音文件。一樣很簡單,提供須要刪除的問題件的key便可。

def del_file(upkey):
    q = qiniu2.Auth(config.QN_ACCESS_KEY, config.QN_SECRET_KEY)
    bucket = BucketManager(q)
    ret, info = bucket.delete(config.AUDIO_BUCKET, upkey)
    return ret, info

語音播放

兼容格式

一開始看html的audio標籤的時候,默認ogg和mp3都可。因此默認轉換爲ogg。最後iOS上不沒法播放,因而檢查發現iOS壓根就不兼容ogg格式,最終轉換爲mp3格式。

  • iOS錄音PC能播放,不是前端、後臺緣由。

  • 肯定iOS的微信兼容audio
    全民K哥能播放,全民K哥的js判斷支持h5則使用audio不然flash,而微信支持h5。經過canPlayType屬性便可檢測。

  • 測試audio兼容性(若是最先就加入並進行檢測,前面的都不用折騰)

// 檢測可否兼容audio
function support_audio(){
    return !!document.createElement('audio').canPlayType;
}
// 檢測可否兼容ogg
function support_audio_ogg(){
    var elem = document.createElement('audio');
    return elem.canPlayType('audio/ogg; codecs="vorbis"');
}
// 檢測可否兼容mp3
function support_audio_mp3(){
    var elem = document.createElement('audio');
    return elem.canPlayType('audio/mpeg;');
}

console.log('audio:' + support_audio());
console.log('audio-ogg:'+ support_audio_ogg());
console.log('audio-mp3:'+ support_audio_mp3());

參考:http://www.vnadd.com/25160.htm

  • 使用jsconsole遠程調試
    經過該工具能夠遠程查看訪問機器輸出到console的數據,便可知道是否兼容。

【總結】感受仍是晚起比較好,成天都有狀態,11點起來,吃了個飯,而後一直寫到晚上12點,以上絕大部分都是這期間完成的,中間吃了個晚飯。緣由:牛津大學教授:早睡早起是錯誤觀念,其實我就是想給睡懶覺找藉口。

原文連接

相關文章
相關標籤/搜索