以前在前人基礎(chǔ)上重復(fù)造了一個(gè)網(wǎng)頁錄音的輪子,順帶把github倉庫使用研究了一下,扔到了github上。
優(yōu)勢(shì)在于結(jié)構(gòu)簡單,可插拔式的錄音格式支持,幾乎可以支持任意格式(前提有相應(yīng)的編碼器);默認(rèn)提供實(shí)時(shí)音量反饋、有一個(gè)波形顯示擴(kuò)展支持。錄音結(jié)果非常容易立即播放錄音或者上傳錄音到服務(wù)器(提供參考源碼)。
2018-05-16首發(fā),2019-04-21更新
GitHub地址:https://github.com/xiangyuecn/Recorder
在線測(cè)試demo傳送門:https://xiangyuecn.github.io/Recorder/
效果圖

自述
以前準(zhǔn)備做一個(gè)網(wǎng)頁版聊天界面,表情啊、圖片啊、上傳文件啊都應(yīng)該要有,視頻就算了,語音還是要的。
當(dāng)下環(huán)境html5的錄音功能支持情況大為良好(IOS上偏落后點(diǎn))

如是,就有了這個(gè)輪子。
以下內(nèi)容copy自README
Recorder用于html5錄音
在線測(cè)試,支持大部分已實(shí)現(xiàn)getUserMedia的移動(dòng)端、PC端瀏覽器,包括騰訊Android X5內(nèi)核(QQ、微信)。點(diǎn)此查看瀏覽器支持情況。
錄音默認(rèn)輸出mp3格式,另外可選wav格式(此格式錄音文件超大);有限支持ogg(beta)、webm(beta)、amr(beta)格式;支持任意格式擴(kuò)展(前提有相應(yīng)編碼器)。
mp3默認(rèn)16kbps的比特率,2kb每秒的錄音大小,音質(zhì)還可以(如果使用8kbps可達(dá)到1kb每秒,不過音質(zhì)太渣)。
mp3使用lamejs編碼,壓縮后的recorder.mp3.min.js文件150kb左右(開啟gzip后54kb)。如果對(duì)錄音文件大小沒有特別要求,可以僅僅使用錄音核心+wav編碼器,源碼不足300行,壓縮后的recorder.wav.min.js不足4kb。
瀏覽器Audio Media兼容性mp3最好,wav還行,其他要么不支持播放,要么不支持編碼。
特別注:IOS(11.X、12.X)上只有Safari支持getUserMedia,其他瀏覽器均不支持,參考下面的已知問題。
快速使用
【1】加載框架
在需要錄音功能的頁面引入壓縮好的recorder..min.js文件即可 (注意:需要在https等安全環(huán)境下才能進(jìn)行錄音*)
<script src="recorder.mp3.min.js"></script>
或者直接使用源碼(src內(nèi)的為源碼、dist內(nèi)的為壓縮后的),可以引用src目錄中的recorder-core.js+相應(yīng)類型的實(shí)現(xiàn)文件,比如要mp3錄音:
<script src="src/recorder-core.js"></script> <!--必須引入的錄音核心-->
<script src="src/engine/mp3.js"></script> <!--相應(yīng)格式支持文件-->
<script src="src/engine/mp3-engine.js"></script> <!--如果此格式有額外的編碼引擎的話,也要加上-->
【2】調(diào)用錄音
然后使用,假設(shè)立即運(yùn)行,只錄3秒
var rec=Recorder();//使用默認(rèn)配置,mp3格式
rec.open(function(){//打開麥克風(fēng)授權(quán)獲得相關(guān)資源
rec.start();//開始錄音
setTimeout(function(){
rec.stop(function(blob,duration){//到達(dá)指定條件停止錄音
console.log(URL.createObjectURL(blob),"時(shí)長:"+duration+"ms");
rec.close();//釋放錄音資源
//已經(jīng)拿到blob文件對(duì)象想干嘛就干嘛:立即播放、上傳
/*立即播放例子*/
var audio=document.createElement("audio");
audio.controls=true;
document.body.appendChild(audio);
//簡單的一嗶
audio.src=URL.createObjectURL(blob);
audio.play();
},function(msg){
console.log("錄音失敗:"+msg);
});
},3000);
},function(msg,isUserNotAllow){//用戶拒絕未授權(quán)或不支持
console.log((isUserNotAllow?"UserNotAllow,":"")+"無法錄音:"+msg);
});
【附】錄音上傳示例
var TestApi="/test_request";//用來在控制臺(tái)network中能看到請(qǐng)求數(shù)據(jù),測(cè)試的請(qǐng)求結(jié)果無關(guān)緊要
var rec=Recorder();rec.open(function(){rec.start();setTimeout(function(){rec.stop(function(blob,duration){
//-----↓↓↓以下才是主要代碼↓↓↓-------
//本例子假設(shè)使用jQuery封裝的請(qǐng)求方式,實(shí)際使用中自行調(diào)整為自己的請(qǐng)求方式
//錄音結(jié)束時(shí)拿到了blob文件對(duì)象,可以用FileReader讀取出內(nèi)容,或者用FormData上傳
var api=TestApi;
/***方式一:將blob文件轉(zhuǎn)成base64純文本編碼,使用普通application/x-www-form-urlencoded表單上傳***/
var reader=new FileReader();
reader.onloadend=function(){
$.ajax({
url:api //上傳接口地址
,type:"POST"
,data:{
mime:blob.type //告訴后端,這個(gè)錄音是什么格式的,可能前后端都固定的mp3可以不用寫
,upfile_b64:(/.+;\s*base64\s*,\s*(.+)$/i.exec(reader.result)||[])[1] //錄音文件內(nèi)容,后端進(jìn)行base64解碼成二進(jìn)制
//...其他表單參數(shù)
}
,success:function(v){
console.log("上傳成功",v);
}
,error:function(s){
console.error("上傳失敗",s);
}
});
};
reader.readAsDataURL(blob);
/***方式二:使用FormData用multipart/form-data表單上傳文件***/
var form=new FormData();
form.append("upfile",blob,"recorder.mp3"); //和普通form表單并無二致,后端接收到upfile參數(shù)的文件,文件名為recorder.mp3
//...其他表單參數(shù)
$.ajax({
url:api //上傳接口地址
,type:"POST"
,contentType:false //讓xhr自動(dòng)處理Content-Type header,multipart/form-data需要生成隨機(jī)的boundary
,processData:false //不要處理data,讓xhr自動(dòng)處理
,data:form
,success:function(v){
console.log("上傳成功",v);
}
,error:function(s){
console.error("上傳失敗",s);
}
});
//-----↑↑↑以上才是主要代碼↑↑↑-------
},function(msg){console.log("錄音失敗:"+msg);});},3000);},function(msg){console.log("無法錄音:"+msg);});
【附】問題排查
- 打開Demo頁面試試看,是不是也有同樣的問題。
- 檢查是不是在https之類的安全環(huán)境下調(diào)用的。
- 檢查是不是IOS系統(tǒng),確認(rèn)caniuseIOS對(duì)
getUserMedia的支持情況。 - 檢查上面第1步是否把框架加載到位,在Demo頁面有應(yīng)該加載哪些js的提示。
- 提交Issue,熱心網(wǎng)友幫你解答。
方法文檔
【構(gòu)造】rec=Recorder(set)
構(gòu)造函數(shù),拿到Recorder的實(shí)例,然后可以進(jìn)行請(qǐng)求獲取麥克風(fēng)權(quán)限和錄音。
set參數(shù)為配置對(duì)象,默認(rèn)配置值如下:
set={
type:"mp3" //輸出類型:mp3,wav等,使用一個(gè)類型前需要先引入對(duì)應(yīng)的編碼引擎
,bitRate:16 //比特率 wav(位):16、8,MP3(單位kbps):8kbps時(shí)文件大小1k/s,16kbps 2k/s,錄音文件很小
,sampleRate:16000 //采樣率,wav格式文件大小=sampleRate*時(shí)間;mp3此項(xiàng)對(duì)低比特率文件大小有影響,高比特率幾乎無影響。
//wav任意值,mp3取值范圍:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
,bufferSize:4096 //AudioContext緩沖大小。會(huì)影響onProcess調(diào)用速度,相對(duì)于AudioContext.sampleRate=48000時(shí),4096接近12幀/s,調(diào)節(jié)此參數(shù)可生成比較流暢的回調(diào)動(dòng)畫。
//取值256, 512, 1024, 2048, 4096, 8192, or 16384
//注意,取值不能過低,2048開始不同瀏覽器可能回調(diào)速率跟不上造成音質(zhì)問題(低端瀏覽器→說的就是騰訊X5)
,onProcess:NOOP //接收到錄音數(shù)據(jù)時(shí)的回調(diào)函數(shù):fn(this.buffer,powerLevel,bufferDuration,bufferSampleRate)
//buffer=[緩沖PCM數(shù)據(jù),...],powerLevel:當(dāng)前緩沖的音量級(jí)別0-100,bufferDuration:已緩沖時(shí)長,bufferSampleRate:緩沖使用的采樣率
//如果需要繪制波形之類功能,需要實(shí)現(xiàn)此方法即可,使用以計(jì)算好的powerLevel可以實(shí)現(xiàn)音量大小的直觀展示,使用buffer可以達(dá)到更高級(jí)效果
}
注意:set內(nèi)是數(shù)字的明確傳數(shù)字,不要傳字符串之類的導(dǎo)致不可預(yù)測(cè)的異常,其他有配置的地方也是一樣(感謝214282049@qq.com19-01-10發(fā)的反饋郵件)。
【方法】rec.open(success,fail)
請(qǐng)求打開錄音資源,如果瀏覽器不支持錄音或用戶拒絕麥克風(fēng)權(quán)限將會(huì)調(diào)用fail,打開后需要調(diào)用close。
注意:此方法是異步的;一般使用時(shí)打開,用完立即關(guān)閉;可重復(fù)調(diào)用,可用來測(cè)試是否能錄音。
另外:因?yàn)榇朔椒〞?huì)調(diào)起用戶授權(quán)請(qǐng)求,如果僅僅想知道瀏覽器是否支持錄音(比如:如果瀏覽器不支持就走另外一套錄音方案),應(yīng)使用Recorder.Support()方法。
success=fn();
fail=fn(errMsg,isUserNotAllow); 如果是用戶主動(dòng)拒絕的錄音權(quán)限,除了有錯(cuò)誤消息外,isUserNotAllow=true,方便程序中做不同的提示,提升用戶主動(dòng)授權(quán)概率
【方法】rec.close(success)
關(guān)閉釋放錄音資源,釋放完成后會(huì)調(diào)用success()回調(diào)
【方法】rec.start()
開始錄音,需先調(diào)用open;如果不支持、錯(cuò)誤,不會(huì)有任何提示,因?yàn)閟top時(shí)自然能得到錯(cuò)誤。
【方法】rec.stop(success,fail)
結(jié)束錄音并返回錄音數(shù)據(jù)blob對(duì)象,拿到blob對(duì)象就可以為所欲為了,不限于立即播放、上傳
success(blob,duration):blob:錄音數(shù)據(jù)audio/mp3|wav...格式,duration:錄音時(shí)長,單位毫秒
fail(errMsg):錄音出錯(cuò)回調(diào)
提示:stop時(shí)會(huì)進(jìn)行音頻編碼,音頻編碼可能會(huì)很慢,10幾秒錄音花費(fèi)2秒左右算是正常,編碼并未使用Worker方案(文件多),內(nèi)部采取的是分段編碼+setTimeout來處理,界面卡頓不明顯。
【方法】rec.pause()
暫停錄音。
【方法】rec.resume()
恢復(fù)繼續(xù)錄音。
【方法】rec.mock(pcmData,pcmSampleRate)
模擬一段錄音數(shù)據(jù),后面可以調(diào)用stop進(jìn)行編碼。需提供pcm數(shù)據(jù)int[],和pcm數(shù)據(jù)的采樣率。
可用于將一個(gè)音頻解碼出來的pcm數(shù)據(jù)方便的轉(zhuǎn)換成另外一個(gè)格式:
var amrBlob=...;//amr音頻blob對(duì)象
var amrSampleRate=8000;//amr音頻采樣率
//解碼amr得到pcm數(shù)據(jù)
var reader=new FileReader();
reader.onload=function(){
Recorder.AMR.decode(new Uint8Array(reader.result),function(pcm){
transformOgg(pcm);
});
};
reader.readAsArrayBuffer(amrBlob);
//將pcm轉(zhuǎn)成ogg
function transformOgg(pcmData){
Recorder({type:"ogg",bitRate:64,sampleRate:32000})
.mock(pcmData,amrSampleRate)
.stop(function(blob,duration){
//我們就得到了新采樣率和比特率的ogg文件
console.log(blob,duration);
});
};
【靜態(tài)方法】Recorder.Support()
判斷瀏覽器是否支持錄音,隨時(shí)可以調(diào)用。注意:僅僅是檢測(cè)瀏覽器支持情況,不會(huì)判斷和調(diào)起用戶授權(quán)(rec.open()會(huì)判斷用戶授權(quán)),不會(huì)判斷是否支持特定格式錄音。
【靜態(tài)方法】Recorder.IsOpen()
由于Recorder持有的錄音資源是全局唯一的,可通過此方法檢測(cè)是否有Recorder已調(diào)用過open打開了錄音功能。
壓縮合并一個(gè)自己需要的js文件
可參考/src/package-build.js中如何合并的一個(gè)文件,比如mp3是由recorder-core.js,engine/mp3.js,engine/mp3-engine.js組成的。
除了recorder-core.js其他引擎文件都是可選的,可以把全部編碼格式合到一起也,也可以只合并幾種,然后就可以支持相應(yīng)格式的錄音了。
可以修改/src/package-build.js后,在src目錄內(nèi)執(zhí)行壓縮:
cnpm install
npm start
關(guān)于現(xiàn)有編碼器
如果你有其他格式的編碼器并且想貢獻(xiàn)出來,可以提交新增格式文件的pull(文件放到/src/engine中),我們升級(jí)它。
wav
wav格式編碼器時(shí)參考網(wǎng)上資料寫的,會(huì)發(fā)現(xiàn)代碼和別人家的差不多。源碼2kb大小。
mp3
采用的是lamejs(LGPL License)這個(gè)庫的代碼,https://github.com/zhuker/lamejs/blob/bfb7f6c6d7877e0fe1ad9e72697a871676119a0e/lame.all.js這個(gè)版本的文件代碼;已對(duì)lamejs源碼進(jìn)行了部分改動(dòng),用于修復(fù)發(fā)現(xiàn)的問題。LGPL協(xié)議涉及到的文件:mp3-engine.js;這些文件也采用LGPL授權(quán),不適用MIT協(xié)議。源碼518kb大小,壓縮后150kb左右,開啟gzip后50來k。
beta-ogg
采用的是ogg-vorbis-encoder-js(MIT License),https://github.com/higuma/ogg-vorbis-encoder-js/blob/7a872423f416e330e925f5266d2eb66cff63c1b6/lib/OggVorbisEncoder.js這個(gè)版本的文件代碼。此編碼器源碼2.2M,超級(jí)大,壓縮后1.6M,開啟gzip后327K左右。對(duì)錄音的壓縮率比lamejs高出一倍, 但Vorbis in Ogg好像Safari不支持(真的假的)。
beta-webm
這個(gè)編碼器時(shí)通過查閱MDN編寫的一個(gè)玩意,沒多大使用價(jià)值:錄幾秒就至少要幾秒來編碼。。。原因是:未找到對(duì)已有pcm數(shù)據(jù)進(jìn)行快速編碼的方法。數(shù)據(jù)導(dǎo)入到MediaRecorder,音頻有幾秒就要等幾秒,類似邊播放邊收聽形。(想接原始錄音Stream?我不可能給的!)輸出音頻雖然可以通過比特率來控制文件大小,但音頻文件中的比特率并非設(shè)定比特率,采樣率由于是我們自己采樣的,到這個(gè)編碼器隨他怎么搞。只有比較新的瀏覽器支持(需實(shí)現(xiàn)瀏覽器MediaRecorder),壓縮率和mp3差不多。源碼2kb大小。
beta-amr
采用的是benz-amr-recorder(MIT License)優(yōu)化后的amr.js(Unknown License),https://github.com/BenzLeung/benz-amr-recorder/blob/462c6b91a67f7d9f42d0579fb5906fad9edb2c9d/src/amrnb.js這個(gè)版本的文件代碼,已對(duì)此代碼進(jìn)行過調(diào)整更方便使用。支持編碼和解碼操作。由于最高只有12.8kbps的碼率,音質(zhì)和同比配置的mp3、ogg差一個(gè)檔次。由于支持解碼操作,理論上所有支持Audio的瀏覽器都可以播放(需要自己寫代碼實(shí)現(xiàn))。源碼1M多,蠻大,壓縮后445K,開啟gzip后136K。優(yōu)點(diǎn):錄音文件小。
Recorder.amr2wav(amrBlob,True,False)
已實(shí)現(xiàn)的一個(gè)把a(bǔ)mr轉(zhuǎn)成wav格式來播放的方法,True=fn(wavBlob,duration)。要使用此方法需要帶上上面的wav格式編碼器。仿照此方法可輕松轉(zhuǎn)成別的格式,參考mock方法介紹那節(jié)。
其他音頻格式支持辦法
//比如增加aac格式支持 (可參考/src/engine/mp3.js實(shí)現(xiàn))
//新增一個(gè)aac.js,編寫以下格式代碼即可實(shí)現(xiàn)這個(gè)類型
Recorder.prototype.aac=function(pcmData,successCall,failCall){
//通過aac編碼器把pcm數(shù)據(jù)轉(zhuǎn)成aac格式數(shù)據(jù),通過this.set拿到傳入的配置數(shù)據(jù)
... pcmData->aacData
//返回?cái)?shù)據(jù)
successCall(new Blob(aacData,{type:"audio/aac"}));
}
//調(diào)用
Recorder({type:"aac"})
擴(kuò)展
在src/extensions目錄內(nèi)為擴(kuò)展支持庫,這些擴(kuò)展庫默認(rèn)都沒有合并到生成代碼中,需單獨(dú)引用(dist或src中的)才能使用。
WaveView擴(kuò)展
waveview.js,4kb大小源碼,錄音時(shí)動(dòng)態(tài)顯示波形,具體樣子參考演示地址頁面。此擴(kuò)展參考MCVoiceWave庫編寫的,具體代碼在https://github.com/HaloMartin/MCVoiceWave/blob/f6dc28975fbe0f7fc6cc4dbc2e61b0aa5574e9bc/MCVoiceWave/MCVoiceWaveView.m中。
此擴(kuò)展是在錄音時(shí)onProcess回調(diào)中使用;bufferSize會(huì)影響繪制幀率,越小越流暢(但越消耗cpu),默認(rèn)配置的大概12幀/s?;A(chǔ)使用方法:
var wave;
var rec=Recorder({
onProcess:function(buffers,powerLevel,bufferDuration,bufferSampleRate){
wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate);//輸入音頻數(shù)據(jù),更新顯示波形
}
});
rec.open(function(){
wave=Recorder.WaveView({elem:".elem"}); //創(chuàng)建wave對(duì)象,寫這里面瀏覽器妥妥的
rec.start();
});
【構(gòu)造】wave=Recorder.WaveView(set)
構(gòu)造函數(shù),set參數(shù)為配置對(duì)象,默認(rèn)配置值如下:
set={
elem:"css selector" //自動(dòng)顯示到dom,并以此dom大小為顯示大小
//或者配置顯示大小,手動(dòng)把waveviewObj.elem顯示到別的地方
,width:0 //顯示寬度
,height:0 //顯示高度
//以上配置二選一
scale:2 //縮放系數(shù),因?yàn)檎麛?shù),使用2(3? no!)倍寬高進(jìn)行繪制,避免移動(dòng)端繪制模糊
,speed:8 //移動(dòng)速度系數(shù),越大越快
,lineWidth:2 //線條基礎(chǔ)粗細(xì)
//漸變色配置:[位置,css顏色,...] 位置: 取值0.0-1.0之間
,linear1:[0,"rgba(150,97,236,1)",1,"rgba(54,197,252,1)"] //線條漸變色1,從左到右
,linear2:[0,"rgba(209,130,253,0.6)",1,"rgba(54,197,252,0.6)"] //線條漸變色2,從左到右
,linearBg:[0,"rgba(255,255,255,0.2)",1,"rgba(54,197,252,0.2)"] //背景漸變色,從上到下
}
【方法】wave.input(pcmData,powerLevel,sampleRate)
輸入音頻數(shù)據(jù),更新波形顯示,這個(gè)方法調(diào)用的越快,波形越流暢。pcmData為當(dāng)前的錄音數(shù)據(jù)片段,其他參數(shù)和onProcess回調(diào)相同。
兼容性
對(duì)于支持錄音的瀏覽器能夠正常錄音并返回錄音數(shù)據(jù);對(duì)于不支持的瀏覽器,引入js和執(zhí)行相關(guān)方法都不會(huì)產(chǎn)生異常,并且進(jìn)入相關(guān)的fail回調(diào)。一般在open的時(shí)候就能檢測(cè)到是否支持或者被用戶拒絕,可在用戶開始錄音之前提示瀏覽器不支持錄音或授權(quán)。
Android Hybrid App中錄音示例
在Android Hybrid App中使用本庫來錄音,需要在App源碼中實(shí)現(xiàn)以下兩步分:
- 在
AndroidManifest.xml聲明需要用到的兩個(gè)權(quán)限
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
-
WebChromeClient中實(shí)現(xiàn)onPermissionRequest網(wǎng)頁授權(quán)請(qǐng)求
@Override
public void onPermissionRequest(PermissionRequest request) {
...此處應(yīng)包裹一層系統(tǒng)權(quán)限請(qǐng)求
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
request.grant(request.getResources());
}
}
注:如果應(yīng)用的
騰訊X5內(nèi)核,除了上面兩個(gè)權(quán)限外,還必須提供android.permission.CAMERA權(quán)限。另外無法重寫此onPermissionRequest方法,他會(huì)自己彈框詢問,如果被拒絕了就永遠(yuǎn)拒絕了,參考已知問題部分。
如果不出意外,App內(nèi)顯示的網(wǎng)頁就能正常錄音了。
附帶測(cè)試項(xiàng)目
.assets/android_test目錄中提供了Android測(cè)試源碼(如果不想自己打包可以用打包好的apk來測(cè)試,位于.assets/android_test/app-debug-xxx.apk)。提供了系統(tǒng)自帶WebView、和騰訊X5內(nèi)核兩個(gè)測(cè)試界面。
關(guān)于微信JsSDK
微信內(nèi)瀏覽器他家的JsSDK也支持錄音,涉及笨重難調(diào)的公眾號(hào)開發(fā)(光sdk初始化就能阻礙很多新奇想法的產(chǎn)生,signature限制太多),只能滿足最基本的使用(大部分情況足夠了)。如果JsSDK錄完音能返回音頻數(shù)據(jù),這個(gè)SDK將好用10000倍,如果能實(shí)時(shí)返回音頻數(shù)據(jù),將好用100000倍。關(guān)鍵是他們家是拒絕給這種簡單好用的功能的,必須繞一個(gè)大圈:錄好音了->上傳到微信服務(wù)器->自家服務(wù)器請(qǐng)求微信服務(wù)器多進(jìn)行媒體下載->保存錄音(微信小程序以前也是二逼路子,現(xiàn)在稍微好點(diǎn)能實(shí)時(shí)拿到錄音mp3數(shù)據(jù)),如果能升級(jí):錄好音了拿到音頻數(shù)據(jù)->上傳保存錄音,目測(cè)對(duì)最終結(jié)果是沒有區(qū)別的,還簡單不少,對(duì)微信自家也算是非常經(jīng)濟(jì)實(shí)用。[2018]由于微信IOS上不支持原生JS錄音,Android上又支持,為了兼容而去兼容的事情我是拒絕的(而且是僅僅為了兼容IOS上面的微信),其實(shí)也算不上去兼容,因?yàn)槲⑿臞sSDK中的接口完全算是另外一種東西,接入的話對(duì)整個(gè)錄音流程都會(huì)產(chǎn)生完全不一樣的變化,還不如沒有進(jìn)入錄音流程之前就進(jìn)行分支判斷處理。
最后:如果是在微信上用的多,應(yīng)優(yōu)先直接接入他家的JsSDK(沒有公眾號(hào)開個(gè)訂閱號(hào)又不要錢),基本上可以忽略兼容性問題,就是麻煩點(diǎn)。
已知問題
2018-09-19 caniuse 注明IOS 11.X - 12.X 上 只有Safari支持調(diào)用getUserMedia,其他App下WKWebView(UIWebView?)(相關(guān)資料)均不支持。經(jīng)用戶測(cè)試驗(yàn)證IOS 12上chrome、UC都無法錄音,部分IOS 12 Safari可以獲取到并且能正常錄音,但部分不行,原因未知,參考ios 12 支不支持錄音了。在IOS上不支持錄音的環(huán)境下應(yīng)該采用其他解決方案,參考案例演示、關(guān)于微信JsSDK部分。
2019-02-28 issues#14 如果getUserMedia返回的MediaStreamTrack.readyState == "ended","ended" which indicates that the input is not giving any more data and will never provide new data. ,導(dǎo)致無法錄音。如果產(chǎn)生這種情況,目前在rec.open方法調(diào)用時(shí)會(huì)正確檢測(cè)到,并執(zhí)行fail回調(diào)。造成issues#14 ended原因是App源碼中AndroidManifest.xml中沒有聲明android.permission.MODIFY_AUDIO_SETTINGS權(quán)限,導(dǎo)致騰訊X5不能正常錄音。
2019-03-09 在Android上QQ、微信里,請(qǐng)求授權(quán)使用麥克風(fēng)的提示,經(jīng)過長時(shí)間觀察發(fā)現(xiàn),他們的表現(xiàn)很隨機(jī)、很奇特??赡苊看卧谡{(diào)用getUserMedia時(shí)候都會(huì)彈選擇,也可能選擇一次就不會(huì)再彈提示,也可能重啟App后又會(huì)彈。如果用戶拒絕了,可能第二天又會(huì)彈,或者永遠(yuǎn)都不彈了,要么重置(裝)App。使用騰訊X5內(nèi)核的App測(cè)試也是一樣奇特表現(xiàn),拒絕權(quán)限后可能必須要重置(裝)。這個(gè)問題貌似跟X5內(nèi)核自動(dòng)升級(jí)的版本有關(guān)。
如果這個(gè)庫有幫助到您,請(qǐng) Star 一下。GitHub:https://github.com/xiangyuecn/Recorder