代码拉取完成,页面将自动刷新
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="shortcut icon" type="image/png" href="assets/icon.png">
<title>Recorder测试</title>
<script>
console.log(
["%c "
," "
," "
," %c REC WARNING %c "
," "
," "
,"%c 请不要试图阅读本demo的源码,不然你会去想这么丑的代码是谁写的 "
," 本文件包括附属的js文件的代码是经过长时间积累出来的 "
," 代码虽然已经分层/分开写了,也许者作者也已经不认识了 "
," "
," 如果想要快速入门,请阅读github项目内首页README文档 "
," 参考文档内的快速使用部分,简单快捷高效 "
," "
," 请不要试图阅读本demo的源码,正常情况下意义不大 "
," "
," "
,""].join("\n"),
'background: #000; font-size: 18px; font-family: monospace',
'background: #f33; font-size: 18px; font-family: monospace; color: #eee; text-shadow:0 0 1px #fff',
'background: #000; font-size: 18px; font-family: monospace',
'background: #000; font-size: 18px; font-family: monospace; color: #ddd; text-shadow:0 0 2px #fff'
)
</script>
</head>
<body>
<!--加载核心库,其他类型支持库在下面根据用户点击选择加载-->
<script src="src/recorder-core.js"></script>
<!--加载可选扩展库-->
<script src="src/extensions/waveview.js"></script>
<style>
body{
word-wrap: break-word;
background:#fff;
}
pre{
white-space:pre-wrap;
}
.pd{
padding:0 0 6px 0;
}
.btns button{
padding: 5px 10px;
}
</style>
<script>
//兼容环境
var PageLM="2019-11-7 21:48:00";
function BuildHtml(html,o,notEncode,loop){return o||(o={}),html=(null==html?"":html+"").replace(/\{(fn:)?(:)?(.+?)\}/gi,function(a,b,c,code){try{var v=eval(b?code:"o."+code);return v=void 0===v?"":v+"",c||notEncode?v:v}catch(e){return console.log("BuildHtml Fail",a+"\n"+e.stack),""}}),loop&&/\{(fn:)?(.+?)\}/.test(html)&&(html=BuildHtml(html,o,notEncode,loop)),html};
function RandomKey(){
return "randomkey"+(RandomKey.idx++);
};
RandomKey.idx=0;
</script>
<script src="assets/ztest-jquery.min-1.9.1.js"></script>
<div class="demoHead">
<style>
.navItem{
display:inline-block;
width:40%;
max-width:300px;
margin-right:20px;
vertical-align: top;
background:#eee;
border-bottom: 5px solid #ccc;
color:#666;
text-decoration:none;
border-radius: 8px;
padding: 0 5px 3px;
}
.navItem.slc{
border-bottom: 5px solid #0B1;
color:#000;
}
.navItem:hover{
color:#d44;
}
.navTitle{
text-align: center;
font-size:18px;
font-weight: bold;
}
.navDesc{
font-size:12px;
}
</style>
<a class="navItem slc" href="https://xiangyuecn.github.io/Recorder/">
<div class="navTitle">Recorder H5</div>
<div class="navDesc">Recorder H5使用简单,功能丰富,支持PC、Android,但IOS上仅Safari支持录音</div>
</a>
<a class="navItem" href="https://jiebian.life/web/h5/github/recordapp.aspx">
<div class="navTitle">RecordApp</div>
<div class="navDesc">RecordApp除Recorder支持的外,支持Hybrid App,IOS上支持微信网页和小程序web-view</div>
</a>
</div>
<!-- begin 开始copy源码 -->
<div class="demoMain">
<div class="pd gitUrl">
GitHub:<a href="https://github.com/xiangyuecn/Recorder">https://github.com/xiangyuecn/Recorder</a> , 更多Demo:<a href="https://xiangyuecn.github.io/Recorder/assets/工具-代码运行和静态分发Runtime.html" target="_blank">在线编辑和运行</a> , <a href="https://xiangyuecn.github.io/Recorder/assets/demo-vue" target="_blank">vue+webpack测试</a>
</div>
<div class="pd">
类型:<span class="types">
<label><input type="radio" name="type" value="mp3" engine="mp3,mp3-engine" min="/recorder.mp3.min" class="initType" checked>mp3</label>
<label><input type="radio" name="type" value="wav" engine="wav" min="/recorder.wav.min">wav</label>
<label><input type="radio" name="type" value="ogg" engine="beta-ogg,beta-ogg-engine" min=",beta-ogg">ogg(beta)</label>
<label><input type="radio" name="type" value="webm" engine="beta-webm" min=",beta-webm">webm(beta)</label>
<label><input type="radio" name="type" value="amr" engine="beta-amr,beta-amr-engine,wav" min=",beta-amr">amr(beta)</label>
</span>
<label><input type="checkbox" class="loadMinJs">请求压缩版</label>
</div>
<div class="pd">
提示:<span class="typeTips">-</span>
</div>
<div class="pd">
比特率: <input type="text" class="bit" value="16" style="width:60px"> kbps,越大音质越好
</div>
<div class="pd">
采样率: <input type="text" class="sample" value="16000" style="width:60px"> hz,越大细节越丰富
</div>
<div class="pd btns">
<button onclick="recopen()">打开录音</button>
<button onclick="recclose()">关闭录音</button>
</div>
<div class="pd btns">
<button onclick="recstart()">录制</button>
<button onclick="recstop()">停止</button>
<button onclick="recpause()" style="margin-left:60px">暂停</button>
<button onclick="recresume()">继续</button>
</div>
<div class="pd recpower">
<div style="height:40px;width:300px;background:#999;position:relative;">
<div class="recpowerx" style="height:40px;background:#0B1;position:absolute;"></div>
<div class="recpowert" style="padding-left:50px; line-height:40px; position: relative;"></div>
</div>
</div>
<div class="pd">
<button onclick="recstop2()" class="batEnc">批量编码</button>
<input type="text" class="bits" value="8 to 96 step 8">kbps 测试音质用的,除比特率外其他参数可调整
</div>
<div class="pd waveBox">
<div style="height:100px;width:300px;border:1px solid #ccc;box-sizing: border-box;display:inline-block" class="recwave"></div>
<input type="checkbox" class="recwaveSet" checked>
</div>
<div class="pd webrtcBox">
<label><input type="checkbox" class="realTimeSendSet">模拟准实时编码传输(H5版语音通话聊天)</label>
,发送间隔<input type="text" class="realTimeSend" value="996" style="width:60px">ms
<div class="webrtcView" style="display:none;"></div>
</div>
<hr>
<audio class="recPlay" style="width:100%"></audio>
<div class="reclog"></div>
<hr>
<div class="pd">
<label><input type="checkbox" class="disableEnvInFixSet">禁用设备卡顿时音频输入丢失补偿功能(通过别的程序大量占用CPU来模拟设备卡顿)</label>
<div><a href="https://github.com/xiangyuecn/Recorder/issues/51">issues#51</a>如果没有进行补偿,录音时设备偶尔出现很卡的情况下(CPU被其他程序大量占用),浏览器采集到的音频是断断续续的,导致10秒的录音可能就只返回了5秒的数据量,这个时候最终编码得到的音频时长明显变短,播放时的效果就像快放一样。未禁用时会在卡顿时自动补偿静默音频,消除了快放效果,但由于丢失的音频已被静默数据代替,听起来就是数据本身的断断续续的效果。在设备不卡时录音没有此问题。</div>
</div>
<hr>
<div class="pd">
【测试App】
IOS Demo App:<a href="https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample/demo_ios">下载源码</a> 自行编译
,Android Demo App:<a href="https://xiangyuecn.github.io/Recorder/app-support-sample/demo_android/app-debug.apk.zip" download="app-debug.apk">下载APK</a> (40kb,删除.zip后缀,<a href="https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample/demo_android">源码</a>)
</div>
<hr>
<div class="pd">
<button onclick="goiframe()">把页面放到IFrame里面测试权限请求</button>
测试在iframe里面请求录音权限的兼容性。最佳实践应该是让window.top(不适用于跨域)去加载Recorder,iframe里面使用top.Recorder;此测试未遵照此最佳实践,以模拟跨域iframe和同域下的复杂真实情况,跨域时未设置相应策略权限永远是拒绝的
</div>
<hr>
<div class="pd">
音乐播放测试:
<button onclick="recplay2(this,'rec-4000ms-8kbps-16000hz.wav')">wav</button>
<button onclick="recplay2(this,'rec-4000ms-64kbps-16000hz.mp3')">mp3</button>
<button onclick="recplay2(this,'rec-4000ms-64kbps-16000hz.ogg')">ogg</button>
<button onclick="recplay2(this,'rec-4000ms-64kbps-16000hz.webm')">webm</button>
<button onclick="recplay2(this,'rec-4000ms-12.8kbps-8000hz.amr')">amr</button>
Audio对录音的影响测试(<a href="https://github.com/xiangyuecn/Recorder/issues/34">issues#34</a>);IOS Safari如果未开始过录音并且播放了音乐,然后后续录音将会有问题;再现方法(<a href="https://xiangyuecn.github.io/Recorder/assets/ztest_apple_developer_forums_getusermedia.html">test apple developer forums</a>):刷新页面后首先先播放音乐,然后开始测试录音,会发现波形显示掉帧或者保持直线。另测试浏览器对音频的支持情况。
</div>
<div class="recinfo"></div>
</div>
<script type="text/template" class="tp_recinfo">
<hr/>
浏览器环境情况:
<pre>
AudioContext:{fn:!!window.AudioContext}
webkitAudioContext:{fn:!!window.webkitAudioContext}
mediaDevices:{fn:!!navigator.mediaDevices}
mediaDevices.getUserMedia:{fn:!!(navigator.mediaDevices&&navigator.mediaDevices.getUserMedia)}
navigator.getUserMedia:{fn:!!navigator.getUserMedia}
navigator.webkitGetUserMedia:{fn:!!navigator.webkitGetUserMedia}
URL:{fn:location.href.replace(/#.+/g,"")}
UA:{fn:navigator.userAgent}
Recorder库修改时间(有可能修改了忘改):{fn:Recorder.LM}
本页面修改时间(有可能修改了忘改):{fn:PageLM}
</pre>
<div>
<hr>
<span style="color:#f60;font-size:16px;font-weight:bold;">问题自检:</span>录音时注意观察灰色区域是否有绿色音量跳动,没有绿色跳动说明Recorder没有获取到声音数据。如果测试发现mp3没有声音,可以试一下wav格式,如果wav格式有声音,说明内置lamejs mp3编码器有问题。如果都没有,下载下来播放看看有没有。下载下来也没有声音可以反馈一下。
</div>
<div style="padding-top:20px">
如果浏览器不能正常录音,并且不确定是不是这个库的问题,可以到 <a href="https://xiangyuecn.github.io/Recorder/assets/ztext_collab-project_videojs-record.html">assets/ztext_collab-project_videojs-record.html</a> 试一下。
</div>
</script>
<script>
function reclog(s,e){
var now=new Date();
var t=("0"+now.getHours()).substr(-2)
+":"+("0"+now.getMinutes()).substr(-2)
+":"+("0"+now.getSeconds()).substr(-2);
$(".reclog").prepend('<div style="color:'+(e?"red":"")+'">['+t+']'+s+'</div>');
};
$(window).bind("error",function(e){
reclog('<span style="color:red">【Error】:<pre>'+(e.error?e.error.stack:event.message)+'</pre></span>');
});
</script>
<script>
var rec;
function recopen(){
var type=$("[name=type]:checked").val();
var bit=+$(".bit").val();
var sample=+$(".sample").val();
var wave,waveSet=$(".recwaveSet")[0].checked;
var disableEnvInFixSet=$(".disableEnvInFixSet")[0].checked;
if(disableEnvInFixSet){
reclog("已禁用设备卡顿时音频输入丢失补偿,可以通过别的程序大量占用CPU来模拟设备卡顿,然后录音听听未补偿时的播放效果,然后再试试不禁用的效果");
};
var realTimeSendSet=$(".realTimeSendSet")[0].checked;
var realTimeSendTime=+$(".realTimeSend").val();
rec=Recorder({
type:type
,bitRate:bit
,sampleRate:sample
,disableEnvInFix:disableEnvInFixSet
,onProcess:function(buffers,level,time,sampleRate){
$(".recpowerx").css("width",level+"%");
$(".recpowert").html(time+"/"+level);
waveSet && wave.input(buffers[buffers.length-1],level,sampleRate);
if(realTimeSendSet&&window.realTimeSendTry){
realTimeSendTry(rec.set,realTimeSendTime,buffers,sampleRate);
};
}
});
dialogInt=setTimeout(function(){//定时8秒后打开弹窗,用于监测浏览器没有发起权限请求的情况,在open前放置定时器利于收到了回调能及时取消(不管open是同步还是异步回调的)
showDialog();
},8000);
rec.open(function(){
dialogCancel();
reclog("<span style='color:#0b1'>已打开:"+type+" "+sample+"hz "+bit+"kbps</span>");
wave=Recorder.WaveView({elem:".recwave"});
},function(e,isUserNotAllow){
dialogCancel();
reclog((isUserNotAllow?"UserNotAllow,":"")+"打开失败:"+e);
});
window.waitDialogClick=function(){
dialogCancel();
reclog("打开失败:权限请求被忽略,<span style='color:#f00'>用户主动点击的弹窗</span>");
};
};
//我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调
var showDialog=function(){
if(!/mobile/i.test(navigator.userAgent)){
return;//只在移动端开启没有权限请求的检测
};
dialogCancel();
$("body").append(''
+'<div class="waitDialog" style="z-index:99999;width:100%;height:100%;top:0;left:0;position:fixed;background:rgba(0,0,0,0.3);">'
+'<div style="display:flex;height:100%;align-items:center;">'
+'<div style="flex:1;"></div>'
+'<div style="width:240px;background:#fff;padding:15px 20px;border-radius: 10px;">'
+'<div style="padding-bottom:10px;">录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~</div>'
+'<div style="text-align:center;"><a onclick="waitDialogClick()" style="color:#0B1">忽略</a></div>'
+'</div>'
+'<div style="flex:1;"></div>'
+'</div>'
+'</div>');
};
var dialogInt;
var dialogCancel=function(){
clearTimeout(dialogInt);
$(".waitDialog").remove();
};
//弹框End
function recclose(){
if(rec){
rec.close(function(){
reclog("已关闭");
});
}else{
reclog("未打开录音",1);
};
};
function recstart(call){
call||(call=function(msg){
msg&&reclog(msg,1);
});
if(rec){
window.realTimeSendTryReset&&realTimeSendTryReset();
rec.start();
var set=rec.set;
reclog("录制中:"+set.type+" "+set.sampleRate+"hz "+set.bitRate+"kbps");
call();
}else{
call("未打开录音");
};
};
function recpause(){
if(rec){
rec.pause();
reclog("已暂停");
};
};
function recresume(){
if(rec){
rec.resume();
reclog("继续录音中...");
};
};
var recblob={};
function recstop(call){
recstopFn(call,true,function(){
setTimeout(function(){
window.realTimeSendTryStop&&realTimeSendTryStop(rec.set);
});
});
};
function recstopFn(call,isClick,endCall,rec){
call||(call=function(msg){
msg&&reclog(msg,1);
});
rec=rec||window.rec;
if(rec){
if(isClick){
reclog("正在编码"+rec.set.type+"...");
};
var t1=Date.now();
rec.stop(function(blob,time){
var tag=endCall("",blob,time);
if(tag==-1){
return;
};
var id=RandomKey(16);
recblob[id]={blob:blob,set:$.extend({},rec.set),time:time};
reclog((tag||"已录制")+":"+intp(rec.set.bitRate,3)+"kbps "+intp(rec.set.sampleRate,5)+"hz 花"+intp(Date.now()-t1,4)+"ms编码"+intp(blob.size,6)+"b ["+rec.set.type+"]"+intp(time,6)+'ms <button onclick="recdown(\''+id+'\')">下载</button> <button onclick="recplay(\''+id+'\')">播放</button> <span class="p'+id+'"></span> <span class="d'+id+'"></span>');
call(null,{data:blob,duration:time});
},function(s){
endCall(s);
call("失败:"+s);
});
}else{
call("未打开录音");
};
};
var intp=function(s,len){
s=s==null?"-":s+"";
if(s.length>=len)return s;
return ("_______"+s).substr(-len);
};
function recstop2(){
if(!rec||!rec.buffers){
reclog("需先录个音");
return;
};
var type=$("[name=type]:checked").val();
var sample=+$(".sample").val();
var bits=/(\d+)\s+to\s+(\d+)\s+step\s+(\d+)\s*/i.exec($(".bits").val());
if(!bits){
reclog("码率列表有误,需要? to ? step ?结构");
return;
};
reclog("开始批量编码,请勿进行其他操作~");
rec.set.type=type;
rec.set.sampleRate=sample;
var list=[];
for(var i=+bits[1];i<+bits[2]+1;i+=+bits[3]){
list.push(i);
};
if(rec.set.type=="wav"){
list=[8,16];
};
var i=-1;
var bak=rec.set.bitRate;
var run=function(){
i++;
if(i>=list.length){
rec.set.bitRate=bak;
reclog("批量编码完成");
return;
};
rec.set.bitRate=list[i];
rec.isMock=1;
recstopFn(null,0,function(){
setTimeout(run);
});
};
run();
};
function recplay(key){
var audio=$(".recPlay")[0];
audio.controls=true;
if(!(audio.ended || audio.paused)){
audio.pause();
};
var o=recblob[key];
if(o){
o.play=(o.play||0)+1;
var logmsg=function(msg){
$(".p"+key).html('<span style="color:green">'+o.play+'</span> '+new Date().toLocaleTimeString()+" "+msg);
};
logmsg("");
audio.onerror=function(e){
logmsg('<span style="color:red">播放失败['+audio.error.code+']'+audio.error.message+'</span>');
};
if(o.play2Name){
audio.src="assets/audio/"+o.play2Name;
audio.play();
return;
};
var end=function(blob){
audio.src=(window.URL||webkitURL).createObjectURL(blob);
audio.play();
};
var wav=Recorder[o.set.type+"2wav"];
if(wav){
logmsg("正在转码成wav...");
wav(o.blob,function(blob){
end(blob);
logmsg("已转码成wav播放");
},function(msg){
logmsg("转码成wav失败:"+msg);
});
}else{
end(o.blob);
};
};
};
function recplay2(elem,name){
elem=$(elem);
var key="recplay2"+elem.html();
recblob[key]||(recblob[key]={
play2Name:name
});
if(!$(".p"+key).length){
elem.before('<br>');
elem.after('<span class="p'+key+'"></span><br>');
};
recplay(key);
};
function recdown(key){
var o=recblob[key];
if(o){
var cls=RandomKey(16);
var name="rec-"+o.time+"ms-"+o.set.bitRate+"kbps-"+o.set.sampleRate+"hz."+o.set.type;
o.down=(o.down||0)+1;
$(".d"+key).html('<span style="color:red">'+o.down+'</span> <span class="'+cls+'"> 没弹下载?试一下链接或复制文本<button onclick="recdown64(\''+key+'\',\''+cls+'\')">生成Base64文本</button></span>');
var downA=document.createElement("A");
downA.innerHTML="下载 "+name;
downA.href=(window.URL||webkitURL).createObjectURL(o.blob);
downA.download=name;
$("."+cls).prepend(downA);
downA.click();
};
};
function recdown64(key, cls){
var o=recblob[key];
var reader = new FileReader();
reader.onloadend = function() {
var id=RandomKey(16);
$("."+cls).append('<textarea class="'+id+'"></textarea>');
$("."+id).val(reader.result);
};
reader.readAsDataURL(o.blob);
};
$(".recinfo").html(BuildHtml($(".tp_recinfo").html()));
if(window.isSecureContext===false){
reclog("当前网页不是安全环境(HTTPS),将无法获取录音权限,<a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Privacy_and_security'>MDN Privacy and security</a>",1);
}else if(window.isSecureContext){
reclog("<span style='color:#0b1'>当前网页处在安全环境中</span>(<a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Privacy_and_security'>https、file:///等</a>)");
};
reclog("点击打开录音开始哦,此浏览器<span style='color:"+(Recorder.Support()?"green'>":"red'>不")+"支持录音</span>");
reclog("WaveView Extensions已启用");
function goiframe(){
$(".demoHead").hide();
$(".demoMain").html(''
+'<div>IFrame测试,提示:`RecordApp测试`可以模拟跨域,跨域时未设置相应策略权限永远是拒绝的</div>'
+'<iframe src="?t='+Date.now()+'" style="width:98%;height:'+($(window).height()-100)+'px; border:4px solid #0B1"></iframe>');
};
if(window.top!=window){
var isSelf=false;
try{
window.top.aa=123;
isSelf=true;
}catch(e){};
reclog("<span style='color:#f60'>当前页面处在在iframe中,但故意未进行任何处理,"+(isSelf?"当前是同域":"并且已发生跨域,未设置相应策略权限永远是拒绝的")+"</span>");
};
//实时传输数据模拟开关
$(".realTimeSendSet").bind("change",function(e){
var open=e.target.checked;
$(".webrtcView")[open?"show":"hide"]();
if(open && !window.webrtcCreate){
var file="zdemo.index.webrtc.js";
reclog("正在加载"+file+" ...");
var elem=document.createElement("script");
elem.setAttribute("type","text/javascript");
elem.setAttribute("src",window.webrtcJSPath||("assets/"+file));
$("head")[0].appendChild(elem);
};
});
</script>
<hr>
<div>
<h3>移动端js运行简易控制台</h3>
<textarea id="cmdExecTxt" style="width:300px;height:160px;" placeholder="js代码,为一段表达式,可以返回结果显示。异步可读写JsVal.value,为结果输入框内容">JsVal.value+="尝试请求录音权限...";
var scope=navigator.mediaDevices||navigator;
var True=function(){
JsVal.value+="\n已获得录音权限";
console.log(JsVal.value);
};
var False=function(e){
JsVal.value+="\n"+(e.name||e.message||e)
console.error(e);
};
var fn=scope.webkitGetUserMedia||scope.getUserMedia;
if(fn){
var p=fn.call(scope,{audio:true},True,False);
p.then&&(p.then(True)["catch"](False));
"wait..."
}else{
False("不支持getUserMedia");
"end"
};
</textarea>
<input type="button" value="执行js" onclick="cmdExec()">
<textarea id="cmdExecVal" style="width:300px;height:160px;" placeholder="运行结果"></textarea>
<script>
var JsVal;
var cmdExec=function(){
JsVal=document.getElementById("cmdExecVal");
JsVal.value="";
var cmd=document.getElementById("cmdExecTxt").value;
var val="";
try{
val=eval(cmd);
}catch(e){
val="执行出错:"+(e.stack||e.message);
};
JsVal=document.getElementById("cmdExecVal");
JsVal.value+=(JsVal.value?"\n":"")+val;
};
</script>
<h3>ConsoleX:</h3>
<textarea class="Xlog" style="width:300px;height:160px;"></textarea>
<script>
var XLogInput=$(".Xlog")[0];
(function(){
if(!/mobile/i.test(navigator.userAgent)){
XLogInput.value="非移动端不开启ConsoleX引擎";
return;
};
window.ConsoleX=function(tag,arr){
try{
if(parent!=window){
parent.ConsoleX(tag,arr);
return;
};
}catch(e){}
ConsoleX.log(tag,arr);
};
var logx=console.log;
var infox=console.info;
var warnx=console.warn;
var errorx=console.error;
console.log=function(){
ConsoleX("log",arguments);logx.apply(console,arguments);
};
console.info=function(){
ConsoleX("info",arguments);infox.apply(console,arguments);
};
console.warn=function(){
ConsoleX("warn",arguments);warnx.apply(console,arguments);
};
console.error=function(){
ConsoleX("error",arguments);errorx.apply(console,arguments);
};
ConsoleX.log=function(tag,arr){
var msg=[];
for(var i=0;i<arr.length;i++){
if(i!=0){
msg.push("");
}
msg.push(xobjv(arr[i],1));
};
msg.push("---↑["+tag+"]"+new Date().toLocaleTimeString()+"↑---\n");
XLogInput.value=msg.join("\n")+XLogInput.value;
};
function xobjv(v,deep){
if(v===null)return "null";
if(v==undefined)return "undefined";
if(typeof(v)!="object"){
v=v+"";
if(v.length<500)return v;
return v.substring(0,500)+"[省略"+(v.length-500)+"字]";
}
if(deep&&deep<=3){
v= xobj(v,deep+1);
if(deep==1){
return xobjv(v);
};
return v;
}
return xobjv(v+"");
};
function xobj(obj,deep){
if($.isArray(obj)){
var arr=[];
for(var i=0;i<obj.length;i++){
arr.push(xobjv(obj[i],deep));
};
}else{
var arr={};
for(var k in obj){
arr[k]=xobjv(obj[k],deep);
};
};
if(deep>2){
return arr;
};
return JSON.stringify(arr);
};
console.log("ConsoleX引擎已开启");
})();
</script>
</div>
<div style="padding:100px;"></div>
<!-- end 结束copy源码 -->
<script>
$(function(){
var prev;
$(".types").bind("click",function(e){
var input=$(e.target);
if(input[0].nodeName=="LABEL"){
input=$(input).find("input");
};
var minjs=$(".loadMinJs")[0].checked;
if(prev!=input[0]||prev.minjs!==minjs){
prev=input[0];
prev.minjs=minjs;
loadEngine($(input));
};
});
});
function loadEngine(input){
if(input.length&&input[0].nodeName=="INPUT"){
var type=input.val();
var srcs=input.attr("engine").split(",");
var mins=input.attr("min").split(",");
for(var i=0;i<srcs.length;i++){
srcs[i]="src/engine/"+srcs[i]+".js";
};
for(var i=0;i<mins.length;i++){
var v=mins[i];
if(!v){
v="/dist/recorder-core";
};
if(v.substr(0,1)=="/"){
v=v.substr(1);
}else{
v="dist/engine/"+v;
};
mins[i]=v+".js";
};
var minjs=$(".loadMinJs")[0].checked;
var engines=minjs?mins:srcs;
var end=function(){
var enc=Recorder.prototype["enc_"+type];
var tips=[!enc?"这个编码器无提示信息":type+"编码器"+(enc.stable?"稳定版":"beta版")+",<span style='color:"+(type=="wav"?"#0b1'>wav转码超快":Recorder.prototype[type+"_start"]?"#0b1'>支持边录边转码(Worker)":"red'>仅支持标准UI线程转码")+"</span>,"+enc.testmsg];
tips.push('<div style="color:green;padding-left:50px">');
tips.push("使用"+type+"录音需要加载的js:");
tips.push("<br>【压缩版】:"+mins.join(","))
tips.push("<br>【源文件】:src/recorder-core.js, "+srcs.join(", "));
tips.push("</div>");
$(".typeTips").html(tips.join(""));
};
if(!Recorder.prototype[type] || loadEngineState[type]!==minjs){
reclog("<span style='color:#f60'>正在加载"+type+"编码器"+(minjs?"压缩版":"源码版")+",请勿操作...</span>");
var i=-1;
var load=function(){
i++;
if(i>=engines.length){
loadEngineState[type]=minjs;
Recorder.WaveView=WaveViewBak;
reclog("<span style='color:#0b1'>"+type+"编码器"+(minjs?"压缩版":"源码版")+"已加载,可以录音了</span>");
end();
return;
}
var elem=document.createElement("script");
elem.setAttribute("type","text/javascript");
elem.setAttribute("src",engines[i]);
elem.onload=function(){
load();
};
$("head")[0].appendChild(elem);
};
load();
}else{
end();
};
};
};
loadEngineState={};
var WaveViewBak=Recorder.WaveView;
(function(){try{
var minjs=$(".loadMinJs");
minjs[0].checked=localStorage["loadMinJs"]!="0";
minjs.bind("change",function(){
localStorage["loadMinJs"]=minjs[0].checked?"1":"0";
location.reload();
});
$(".batEnc").bind("click",function(){
if(minjs[0].checked){
reclog("<span style='color:#f60'>当前为压缩版模式,由于不同录音格式之间存在Recorder对象覆盖行为,切换类型将导致不能编码,关掉请求压缩版后无此限制</span>");
};
});
loadEngine($(".initType"));
//pcm测试页面来的
if(/ispcm=1/.test(location.href)){
$(".demoHead,.gitUrl,.btns,.recpower,.waveBox,.webrtcBox").hide();
};
}catch(e){console.error(e)}})();
</script>
<!-- 加载打赏挂件 -->
<script src="assets/zdemo.widget.donate.js"></script>
<script>
DonateWidget({
log:function(msg){reclog(msg)}
,mobElem:$(".reclog").append('<div class="DonateView"></div>').find(".DonateView")[0]
});
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。