From a08e5e1ba610a17a68443dff5319a839497a77e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E5=9D=9A=E6=9E=9C?= <753610399@qq.com> Date: Tue, 21 Apr 2020 09:55:00 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0RecordSDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asset-record-sdk/LICENSE | 6 + asset-record-sdk/README.md | 0 asset-record-sdk/index.html | 0 asset-record-sdk/record-sdk/record-web-sdk.js | 6 + .../record-sdk/src/record-web-sdk.js | 156 ++++++++++++++++++ "assets/use_\350\265\204\346\226\231.rp" | Bin 93188 -> 125427 bytes src/extensions/frequency.histogram.view.js | 2 +- src/package-build.js | 13 +- src/recorder-core.js | 14 +- 9 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 asset-record-sdk/LICENSE create mode 100644 asset-record-sdk/README.md create mode 100644 asset-record-sdk/index.html create mode 100644 asset-record-sdk/record-sdk/record-web-sdk.js create mode 100644 asset-record-sdk/record-sdk/src/record-web-sdk.js diff --git a/asset-record-sdk/LICENSE b/asset-record-sdk/LICENSE new file mode 100644 index 0000000..d71f8b4 --- /dev/null +++ b/asset-record-sdk/LICENSE @@ -0,0 +1,6 @@ +RecordSDK为收费项目,版权归xiangyuecn(753610399@qq.com)所有;付费订购可获得对应功能的使用权或源码的使用权。 + +1. 订购者在所订购功能的使用期限或用量范围内可使用相应功能;当使用期限到期或用量用尽时,将不可继续使用相应功能。 +2. 订购的功能存在多种套餐的情况下,以套餐的服务内容为准,如是否提供技术支持、接口对接支持等。 +3. 涉及使用到我方服务器的功能,受网络、服务器自身等影响,我方不保证服务100%可用。 +4. 对于会提供源码的功能,订购者仅可自己(公司、个人)使用,禁止转售、分发、或其他途径手段将源码提供给其他人。 \ No newline at end of file diff --git a/asset-record-sdk/README.md b/asset-record-sdk/README.md new file mode 100644 index 0000000..e69de29 diff --git a/asset-record-sdk/index.html b/asset-record-sdk/index.html new file mode 100644 index 0000000..e69de29 diff --git a/asset-record-sdk/record-sdk/record-web-sdk.js b/asset-record-sdk/record-sdk/record-web-sdk.js new file mode 100644 index 0000000..848502a --- /dev/null +++ b/asset-record-sdk/record-sdk/record-web-sdk.js @@ -0,0 +1,6 @@ +/* +录音,RecordSDK:无限兼容任何浏览器的全功能录音解决方案 +https://github.com/xiangyuecn/Recorder +src: recorder-core.js,../asset-record-sdk/record-sdk/src/record-web-sdk.js +*/ +!function(p){"use strict";var v=function(){},O=function(e){return new t(e)};O.IsOpen=function(){var e=O.Stream;if(e){var t=e.getTracks&&e.getTracks()||e.audioTracks||[],n=t[0];if(n){var r=n.readyState;return"live"==r||r==n.LIVE}}return!1},O.BufferSize=4096,O.Destroy=function(){for(var e in console.log("Recorder Destroy"),n)n[e]()};var n={};O.BindDestroy=function(e,t){n[e]=t},O.Support=function(){var e=p.AudioContext;if(e||(e=p.webkitAudioContext),!e)return!1;var t=navigator.mediaDevices||{};return t.getUserMedia||(t=navigator).getUserMedia||(t.getUserMedia=t.webkitGetUserMedia||t.mozGetUserMedia||t.msGetUserMedia),!!t.getUserMedia&&(O.Scope=t,O.Ctx&&"closed"!=O.Ctx.state||(O.Ctx=new e,O.BindDestroy("Ctx",function(){var e=O.Ctx;e&&e.close&&e.close()})),!0)},O.SampleData=function(e,t,n,r,a){r||(r={});var o=r.index||0,i=r.offset||0,s=r.frameNext||[];a||(a={});var c=a.frameSize||1;a.frameType&&(c="mp3"==a.frameType?1152:1);for(var f=0,l=o;l"+v.length+" 花:"+(Date.now()-r)+"ms"),setTimeout(function(){r=Date.now(),a[o.type](v,function(e){c(e,u)},function(e){s(e)})})}else s("未加载"+o.type+"编码器");else s("音频被释放");else s("未采集到录音")}},p.Recorder&&p.Recorder.Destroy(),(p.Recorder=O).LM="2020-1-8 10:53:14",O.TrafficImgUrl="//ia.51.la/go1?id=20469973&pvFlag=1",O.Traffic=function(){var e=O.TrafficImgUrl;if(e){var t=O.Traffic,n=location.href.replace(/#.*/,"");if(!t[n]){t[n]=1;var r=new Image;r.src=e,console.log("Traffic Analysis Image: Recorder.TrafficImgUrl="+e)}}}}(window),"function"==typeof define&&define.amd&&define(function(){return Recorder}),"object"==typeof module&&module.exports&&(module.exports=Recorder),function(e){"use strict";var t={LM:"2020-4-19 10:41:03",ConfigSet:{}},i=function(){},n=navigator.userAgent;/\bMSIE\b/i.test(n),/MicroMessenger/i.test(n),t.Config=function(e,t,n){var r=this.ConfigSet,a={onResult:i};for(var o in r)a[o]=r[o];for(var o in e)a[o]=e[o];this.ConfigSet=a},t.Record=function(e){var t={type:"mp3",bitRate:16,sampleRate:16e3,runtime:"default",runtimeSet:{processOnly:!1,args:{},customID:""}};for(var n in e)t[n]=e[n];e=t},e.RecordSDK=t}(window),"function"==typeof define&&define.amd&&define(function(){return RecordSDK}),"object"==typeof module&&module.exports&&(module.exports=RecordSDK); \ No newline at end of file diff --git a/asset-record-sdk/record-sdk/src/record-web-sdk.js b/asset-record-sdk/record-sdk/src/record-web-sdk.js new file mode 100644 index 0000000..c64d2d9 --- /dev/null +++ b/asset-record-sdk/record-sdk/src/record-web-sdk.js @@ -0,0 +1,156 @@ +/*=SET:Desc=*/ +/*<@录音,RecordSDK:无限兼容任何浏览器的全功能录音一站式解决方案,一行代码搞定:语音转文字、HTTP录音、无公众号微信内JsSDK录音@>*/ +/* +https://github.com/xiangyuecn/Recorder +*/ +(function(factory){ + factory(window); + //umd returnExports.js + if(typeof(define)=='function' && define.amd){ + define(function(){ + return RecordSDK; + }); + }; + if(typeof(module)=='object' && module.exports){ + module.exports=RecordSDK; + }; +}(function(window){ +"use strict"; + +var RecordSDK={ +LM:"2020-4-19 10:41:03" +,ConfigSet:{} +}; + + + +/** +RecordSDK配置函数,配置成功会调用True回调,否则走False +True() 配置成功回调 +False(errMsg) 配置失败回调 + +set={ + sdkApi:"" + + ,onResult:fn(res) 当收到录音结果时回调,此回调可能会在录音结束时、Config完毕并且拿到了返回的录音时回调 + res={ + time:123456 //此结果创建的时间,一般为录音结束时的时间 + ,action:"abc" //调用录音时提供的action,如果页面内存在多个功能模块需要录音,此参数用来区分是哪个功能的录音回调 + + ,isCancel:false //如果data为null时,isCancel为true代表用户取消了录音 + ,errMsg:"" //如果data为null时,会提供不能获得录音的错误原因 + + ,data:{//录音结果数据,如果录音成功会是对象,否则是null + ,blob:Blob Object //录音音频文件对象,如果开启实时传输或自定义的不返回音频,blob可能为null + ,duration:123 //录音时长 + ,custom:{} //自定义返回的更多内容 + } + } +} +**/ +RecordSDK.Config=function(set,True,False){ + var This=this,Conf=This.ConfigSet; + var baseSet={ + sdkApi:"//recordsdk.jiebian.life/npi/recordsdk" + ,onResult:NOOP + }; + for(var k in Conf){ + baseSet[k]=Conf[k]; + }; + for(var k in set){ + baseSet[k]=set[k]; + }; + set=baseSet; + This.ConfigSet=set; + + //给api加上http前缀,如果是file协议下,不加前缀没法用 + if(set.sdkApi.indexOf("//")==0){ + if(/^https:/i.test(location.href)){ + set.sdkApi="https:"+set.sdkApi; + }else{ + set.sdkApi="http:"+set.sdkApi; + }; + }; + +}; + +/** +开始录音,会打开录音界面,界面显示方式有两种: +1. 当前网页+浏览器支持录音时,直接在页面内弹出录音界面(embed)。 +2. 当前网页+浏览器不支持录音时(如http网址、ios浏览器),通过跳转到新页面显示录音界面;当前浏览器支持录音:跳转方式默认为window.open(未弹出时使用location.href);当前浏览器不支持录音:显示二维码,通过二维码跳转到新页面显示录音(移动端提示截屏后到微信内扫一扫二维码录音,PC端提示扫一扫二维码录音)。 +**/ +RecordSDK.Record=function(set){ + var baseSet={ + type:"mp3" //录音格式,支持wav、mp3两个 + ,bitRate:16 //比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 录音文件很小 + ,sampleRate:16000 //采样率,wav格式大小=sampleRate*时间;mp3此项对低比特率有影响,高比特率几乎无影响。 + //wav任意值,mp3取值范围:48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 + //采样率参考https://www.cnblogs.com/devin87/p/mp3-recorder.html + + ,embedOnly:false //是否仅仅允许在当前页面内录音;设为true会禁止任何形式的跳出当前页面,当环境不支持录音时只会提示当前环境不支持录音;默认false会使用任何可以行的办法去录音 + + ,runtime:"default" /*录音实现(包括UI、录音逻辑),取值: + custom:完全自定义实现 + default:默认实现,界面内显示开始录音按钮+波形显示 + innerUI:半自定义实现,当网页+浏览器均支持录音时(embed)显示界面的方式为当前页面内自己的UI界面,其他跳转新页面录音的界面和default相同 + */ + ,runtimeSet:{ + processOnly:false //是否必须支持实时回调,在需要实时传输的时候设置为true,当环境不支持实时回调时,将会跳转到支持的浏览器内录音 + ,args:{} /*可选,根据runtime不同,需要的参数也不同: + runtime=custom:你自定义的代码内需要提供哪些参数,开始录音时会传这个args进去 + runtime=default、innerUI:可提供参数{ + transferURL:"" //如果提供,将会开启实时传输,此时processOnly配置项永远为true + } + runtime=default:可提供参数{ + touchMode:false //是否开启按住录音,false时是点击开始,点击结束,true时按住开始录音松手结束录音 + } + */ + + ,customID:"" //runtime为custom时必须提供,此id为账户管理后台的自定义id,显示录音界面时会加载此id内的自定义配置 + } + }; + for(var k in set){ + baseSet[k]=set[k]; + }; + set=baseSet; + +}; + + + + + + + +var NOOP=function(){}; + +var UA=navigator.userAgent; +var IsBad=/\bMSIE\b/i.test(UA);//明确拒绝支持的,或者压根加载不了js的浏览器 +var IsWx=/MicroMessenger/i.test(UA); +var NeedHttps=window.isSecureContext===false; + +var checkSupportH5=function(){ + var AC=window.AudioContext||window.webkitAudioContext; + if(!AC){ + return false; + }; + + var scope=navigator; + var UM=(scope.mediaDevices||{}).getUserMedia; + if(!UM){ + UM=scope.getUserMedia||scope.webkitGetUserMedia||scope.mozGetUserMedia||scope.msGetUserMedia; + }; + if(!UM){ + return false; + }; + + return true; +}; + + + + + +window.RecordSDK=RecordSDK; + +})); \ No newline at end of file diff --git "a/assets/use_\350\265\204\346\226\231.rp" "b/assets/use_\350\265\204\346\226\231.rp" index 3a08799c1e4c1c4e3b7008ea4e9b14f41baa1a74..8f3676be014973c72f6b070b9b7f4dc7d48caa9d 100644 GIT binary patch delta 38974 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 E3m_SM@&Et; delta 6504 zcmZX3Wl)?=)9x+=7AHZ12e;r72oT(zKu93CySv^v0TLV*cTIwYu(*a`!EJGe#hu{G z$MZg?zW1Cu{bR0~o~iDho|@^ZYtAMhVKZpB8p^0oh(I6^2I%yMR1K~<81oS|Y%4n# zSCV|e^g!DIthjl8ocf~@hxjSI_yEfDr;_oG_2-a}A3s*`)Alrr)Hjn@TJ`u@v3}#i zco}8rN#$Apk(NdAUWrLzii7NoAC5gI<{4FM(K0HBP&ras!^Bw?o6noF@8|&t=Z-HZ8HbkE13I^9E`NrJn+ec`~s) zV@nMY9GN*x69sRqhw}P=%;a>aU2Az7GAoAzQz45yobt503_K1K!+Pd2(yoqjvX{AA zGMRmh9s_(Xs%BwlkPhi2oLYY=+Y-iV)p4f6Zkws<>?!6ndW|lAOB-Jqz17dOBgS&k zQTn-Bj8pymCi;|4X|7|XZ>)JD)H4Qs^5jI z8r9!{7h?r4UPsq5to@|@q9xmHqCEJt?Cb?@v31=jdg*f)I=goa26Q=)p7p1ww%I+t z!# zZB$6;=QbqK>B'X<}dP!e{-cEr|O`zHL}h%P%| zr_z8sa%nE$@GeTUdB0wK)9ZqI>7e~ib!%<=2>Q3)(@@Xv6YM81l!48 z&JYjaIqfM{FNtuppBoko01o~Dd>_`JKwGBI$&q+Ql~Es~5q?05_tA_M6?KpJZa5To z$!nXfg_)byBx-T~o!D(rP^bYd~tnW zH-P+<$n|xF2~CiVw9RPIc~~y@wd3)79}r?!WERenMB;EZSX1{W;E)!8UJF@={@TH) z_CTLWh0HV+9gJ7dmyRH3HfG*mVITb^Mkf`fO0-2ilr)5_8nVK*T@5N$UPUY64_ui< z!3)MYze_Luyb9NeYf+wL3EuZMC`2{aH9Dh@TGW2t>6t0W+A)z$ zk|%1>uHgE2RuuYzgfhHr z`vRvYG(JCZswxHn+MM&>5dUMb>+Y(8TIB1)HnENSQv5l1`92%7niKIvbuA8wy^HRj zf|icyBdkLtgK}TT5COh-f$&v)2!!}e(TWLL9LrU8NZgf7sK>jLI96m~-(@yA)LeB9 zbHf8K@Ea2QzcnE4@$JV=*+5H1c`OMuAdq`)B7_(f>z|SUO$v-{e3n#$Wet3QwPCO{ z@2^FCl1s8?qcd@_Frs*>q2H56WFV_G=U%t?CAy!bOa`MeN|}H^f+1FSa@*~T+$4Lh zi^}Ifz9f~UZiHJw-mHF)kM5T$wTp_wuLa)@reDbOd9+uxcsOSJ9SR|G{E&Lus!=oJ z6tmIHmC8%fWz>3J7Wm?S^M-(TbWeke8JZsF6s8SM;ys zg_D;Z+M@zI+1zi_(S=bu%|IOa>X%pyg%jY!d1YHJ)60!hN90hHHSHf=Oill?*lwY$-wn9v$=AOhc4Gh)^ zfBha^Feu3myb2!GggqyHE#Ld@X_IT00wJ+Ip9T6EpN*6q!`B!#OHFdO48xH$Oj5zj z5_g6_1YZ~}C@?v6#?tA7)>m>8H##Q>y=_fHB3Z*ap`sN`DwYF%1T`zlF^n%m6L|Pm z)KenHK8(+i(=%(zCgJN^(ZTgAGCR&THGHEtO+J%J0fA}nIe_9M7Q#2e{n07_IZf#YNFV zD)1I7a^5nDV$_u>;3&p^zNFDf3IoO@dudktOJ zk;WqcedqFb1?7#7&|+R+F|-r0bfzKgED@HEdKMANvNEsG{($sR!PuIoeIPIzW#{ym zeg2byt!i5}b6z_f;c94zw=$pYR~-k1*s<>Gh8}avuMYgMEW2$-gI9#Kq;6#E{)$>c z7W}s{k&xR-_wWSn>8%8$KmmsM_g|=2x@esMTAs?N9@@xx3x^$tWf;ET&Sy#0%t8I- zwV!nUty!Z}&dfIZN@JaQDL>VED*)?PJi^GgH1l6g+&@2CF!~PR`JIxozoA-_t+q+| z{Tojz0fT|r=~l_71C-jgmfV_85N9}D67NQZJ=Y#HOr|p7lD=|>Y>GwIn=|_8yR(S^ zUf*=^^0c-q${1POBpg>gGjf`-ES4mE_0~jD=wL4u<}@?c7BKQ#JCa8DhsU6PWq^7> zuiX#{UhBfixnUYLRYfU=fYNMr(X74k1xh}Aw+xhH`udM5l8!pPBY_0JeWuOStvC2r zd`fADxK?Z9pe*T-u~%wN*s2?*Rtg6*5W|3cc6r9 z=Bl_a&0fyw(Bxo}Rke%sW98ddkot@+i|tg|l&=CZquB=)A^U^0=+<8g09}?0 z$g1~A#p1z8#iwd!+PH&fEbmZ!yTTH~(pTO`kjM#ePsr@(aKGJ|DJGs%B+q>>Q=k)x zV?Hm}o$yYRSN3b7mS*BROvV1FugO}4kST0~S(AeHonSBR%vY6ZZg5Dp%@N)Qt%8r7Y)r=&3+TbH0^MFqhOrS<5B z`?!zsB-D4aqv26b{@66q@OdV6an*VU+)6|uCINAsM)yXQnieZ3jhlP@g^B& z*j(74xyY{?oNW8nPPT2M)s2M*Q_2+(5djC7&-c%`1ySG0!oz}N7(CAkc+c261`VrO zwZkr7vx{vj&=+4K-q?qU61&&(gtREIY4;sa=5b_>)ig75K6A73-c?f4X%&Xmdw%!b zUCUuS*vrAMoq$e_OzUHjVgoa>tFnwB144Tb-WhsY-`PVxJH!S%m%ZVTDoBN^SsfZ3v73A-f*J&i}7 zGw-*mLsADq{VWB5{ub5PC|m99e#0yw7KF&I@5!&v58De-QQ>yIa)H-%M!yTNaj(PI zk+bv_-(s46 z4k12{Aki(!P1!nB7i&RpA4+1N-*GLwFoql#t@Dqry!OLV8OSsarEw|L{8pFsS4e8WH^ zo*lPRry)Hc&~d(?@Jp3w!_8i!^wRy_t&P+0Qc|OsfcPquLtJ0gU@fywr23|x>=xyl zSFR3J8`zPX-bI~?lmcd#E}eQ~)Y0TF)%1M)*VC)JVY3H&sLBu43~u<$8&o3N?tg!k zOz&9?B{T|+AZP16jMfB3%G=+(eX2HDBA9))Tw?{CmM78L>uR04t$xe=DaaJCSmm;Q zK5g*e$HerF<3ipeKwIma|KiSq%U{XL9vNtOzh8ko`6jOKR}Pzx)TOwi79sKX&3M?% zsZAUqrW~*yD=up@s4r*T4DU+eL2ee6j@ZGXXfOuJ0I zb%Jv5d=(V}?;pANa+^6qr#RdEv&6I!Ay3AYLW#Sa0pk!G;1@n~FJNjf*3}E3@%-J! zbSCof;i~km%i`f`Z3u1I-MuK<$BSHDuJdIBp8~Hd z3gv+MAEs9(0g{WQvZY32-dU$tQ>BX3hkAFDS^>FE;;%NE$?7<&{HGT9{LU7{?jrz8 z4nyLm{*B-4jTuc|H!}>&mpOqgt3W~QT|Ux$jKZ%DzGZaOoZn`LTifSW=UclZ?&zrG zzu!N*_Ytr~@|&62J8M+29XVWxQd9$bW-qQeWPO~DUbdYK4{uHP{%OBpTeyl#4EKw~ z$C>^)v{cXHW%BpXOtsdR6R_*ORR)%2w_RI(Cu-nI*zM%LB_w-%eT~(b!QU}6C5_De z&aff-oLBYjUG>e?h#lJtf18&Nax>Ecj8kKJCOL-@_JT06zQ0WA?T0bFYsKtmC0%-+uCi0Hli^-BDOI3AZc#wC8IJK&`fX(~)Q zVRD7h+cNq*xcB^rK4Dvsd_o!*&WJ3FSR6s$Zq#P*cf*DX!L4wZSO||#TboW5hKjtI z(EHF^6I}1!-^Q|ZJc~vv=C4f?RNe9*G$!0SbLew6ejs?Lv#1X5aA?S0+l(Tz69MroN;EkTYlS zLCnP`Lj6dyColk1vhE^E0LLT%L__vu`rqJoyA!}#>&*ib9hxS=*&*}t{l^BUKTp7| z1HZ(UKM;s9&>z`h=GNmFkpu@$&y-Wd+s45Oqbz*;`p#VwNAx-%0MD99T=};kMehLq z%H9=U_AP25*9}!aSAYFvEj>NE4{Bb1c+www=GSpO$Da{0_%B*qx$eh0~=XP&IU zz!wC9A-5e{;7LOV#WsplJa)_F4U=qBetZ)1qQ;DcD_m{`2n2a~h440!NY2J;J_KsO z3MboNBp+cUuXG#aC5LwBbsM#dYD9a9u=wcQ=s9SE25NAzBv?VkpyaH4EQv+ppb+`U zLzFUo2K2JdZ8ebXCs%kFk%p!OCTm_%P$GSCpkLk-iB(RG0cleW-=~Y1ETVZq1ey|x zU`BID@*8&Gqcc@JiUyX%y(bte(0G+IXh7aH$QMHhS0fuY{vkLRMMD8x_Fx|*g~h^} zcRr8C*s#s1@lxW^80liaf!0qHB?T}eT5>#!5*CY)=58B0BfdHIhh`9(xU?6EM0o;f zUIYySv}>rYz$xbG{!;ypDNukjvbr+w=009$u?{$MwhDP4C~#;Wg7mt#Um)jwh{_xk zX|fAxk8&kpA*SPD!Id2jPIQfQdq7_fsLtPRd7X79!rxev(#(We^|;yOW+uT9O`Jps zBQZg!<}+6urQeSS^lNkxjnS*Z=>t;i9hReEA`kOQlMKtZ%B;+NO?LG=ZBXMG+j=qh z9l*357ktJv39mF*-#tT&EN{$PfTqgdc#eSa+t1&y2OP0I)$EW4$N6ErNftk@Lyf*q zxILU?dW;KC-iwMTu7M75b+XR6aB@B4fegTAClEtZp=9wE2ePI9$qVK2Qc@mK%!VW@ zUX)}MgjPsnO_B}$k~+9Mj~}C-$sSw`;Vz75`zkfpcbM-A# zyvw+sLPu|89nO0ZVkJYh)5RV_$NK##$~PU=gt9-V8(atKX?dGepP!@p4sZY)=FNF} zv7u9=L!G3A3c=Q12{q-zD@mC{kz&+L)V?nIhjtr_%L z(i^M{rF;ge?2q)dcPsyC2U_PvN?`&t#^eOz60K7tYyfk9Dg7ToNn`Adm_2#M_ahSZ z^;B5#C!DSXPQHs40A=H%$6~Ld=&f)+$pM4W!~CRRPk7eYh@wG}-a@bW)y7g#3@Y-+ zeNZG`obqSJV;Tu*8flH2wI-=iycTl(qy|ebAAQj2?Y&a)x&(Sq@q1GR;?!O)6!O{U z$y|=PtUG+l1@sS!+S%Qyw!ujOJh_IZsG%cC+zuTV_WBfzfB-00u^>*4`^BWCK72(? z3~yg8wMJwXv-x_ZA!U&jZ~w(+(PE)~wIALgYOj8vGvPT8*;Oj2gFIQIK=6r3b5xpovf8t*wxS%uj zQZ&mspIz|Gj~&bye~g=(OSWp7ig104=^lPZMpn)V%rKNfuAEb3;->l%YbO#&;W?cF zD-Tb+VP`ETtNn}A7)}INJbca%I1t#Mi{PXCDoIm)Bev}c2)@FKP?{ZKx?+Z6exp~(BUnx|39vws)$EL2QAbV0XFzg1Otx> z%v>7~NW;X+f-6bfmLB?S8_Y-ZPZU-rQwU4&qti#n?;qh`p?QS3LnxI!SO+S!1IGE! v()xf>$r#VanU2R0AK_o2c?6qd=%oYL8@jjy#=ye_VS+3lGxy2rAG7}h&G3gY diff --git a/src/extensions/frequency.histogram.view.js b/src/extensions/frequency.histogram.view.js index ebf2116..ecd427c 100644 --- a/src/extensions/frequency.histogram.view.js +++ b/src/extensions/frequency.histogram.view.js @@ -311,7 +311,7 @@ fn.prototype=FrequencyHistogramView.prototype={ }; }; - set.onDraw(frequencyData); + set.onDraw(frequencyData,sampleRate); } }; Recorder.FrequencyHistogramView=FrequencyHistogramView; diff --git a/src/package-build.js b/src/package-build.js index 1221b95..c61de8b 100644 --- a/src/package-build.js +++ b/src/package-build.js @@ -59,6 +59,8 @@ function Run_minify(){ minify("../dist/extensions/lib.fft.js",["extensions/lib.fft.js"]); minify("../dist/extensions/frequency.histogram.view.js",["extensions/frequency.histogram.view.js"]); minify("../dist/extensions/sonic.js",["extensions/sonic.js"]); + + minify("../asset-record-sdk/record-sdk/record-web-sdk.js",["../asset-record-sdk/record-sdk/src/record-web-sdk.js"]); console.log("\x1B[33m%s\x1B[0m","处理完成"); }; @@ -70,10 +72,15 @@ function minify(output,srcs){ for(var i=0;i\*\//g - ,function(a,b,c){ + /\/\*=(?:SET:(\w+)|:)=\*\/([\S\s]+?)\/\*<@([\S\s]+?)@>\*\//g + ,function(a,s,b,c){ console.log("*******使用编译指令:\n"+a+"\n\n"); + if(s){ + sets[s]=c; + return ""; + }; return c; }); @@ -84,7 +91,7 @@ function minify(output,srcs){ code= `/* -录音 +${sets.Desc} https://github.com/xiangyuecn/Recorder src: ${srcs.join(",")} */ diff --git a/src/recorder-core.js b/src/recorder-core.js index 26cf9c1..5f904f3 100644 --- a/src/recorder-core.js +++ b/src/recorder-core.js @@ -17,7 +17,7 @@ https://github.com/xiangyuecn/Recorder "use strict"; //兼容环境 -var LM="2020-1-8 10:53:14"; +var LM="2020-4-20 12:32:42"; var NOOP=function(){}; //end 兼容环境 ****从以下开始copy源码***** @@ -750,12 +750,22 @@ Recorder.Traffic=function(){ if(imgUrl){ var data=Recorder.Traffic; var idf=location.href.replace(/#.*/,""); + + if(imgUrl.indexOf("//")==0){ + //给url加上http前缀,如果是file协议下,不加前缀没法用 + if(/^https:/i.test(idf)){ + imgUrl="https:"+imgUrl; + }else{ + imgUrl="http:"+imgUrl; + }; + }; + if(!data[idf]){ data[idf]=1; var img=new Image(); img.src=imgUrl; - console.log("Traffic Analysis Image: Recorder.TrafficImgUrl="+imgUrl); + console.log("Traffic Analysis Image: Recorder.TrafficImgUrl="+Recorder.TrafficImgUrl); }; }; }; From 29c2c65cfb45393fc481efb14a5cd53b75e45e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E5=9D=9A=E6=9E=9C?= <753610399@qq.com> Date: Thu, 7 May 2020 09:06:03 +0800 Subject: [PATCH 2/3] --- asset-record-sdk/index.html | 318 ++++ asset-record-sdk/record-sdk/record-web-sdk.js | 6 +- .../record-sdk/src/ios-weixin-config.js | 0 .../record-sdk/src/libs/qrcode.js | 1395 +++++++++++++++++ .../record-sdk/src/native-config.js | 0 .../record-sdk/src/record-web-sdk.js | 265 +++- .../record-sdk/web-server/README.txt | 19 + src/package-build.js | 4 +- 8 files changed, 1995 insertions(+), 12 deletions(-) create mode 100644 asset-record-sdk/record-sdk/src/ios-weixin-config.js create mode 100644 asset-record-sdk/record-sdk/src/libs/qrcode.js create mode 100644 asset-record-sdk/record-sdk/src/native-config.js create mode 100644 asset-record-sdk/record-sdk/web-server/README.txt diff --git a/asset-record-sdk/index.html b/asset-record-sdk/index.html index e69de29..5b7837c 100644 --- a/asset-record-sdk/index.html +++ b/asset-record-sdk/index.html @@ -0,0 +1,318 @@ + + + + + + + +RecordSDK测试 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/asset-record-sdk/record-sdk/record-web-sdk.js b/asset-record-sdk/record-sdk/record-web-sdk.js index 848502a..5215c23 100644 --- a/asset-record-sdk/record-sdk/record-web-sdk.js +++ b/asset-record-sdk/record-sdk/record-web-sdk.js @@ -1,6 +1,6 @@ /* -录音,RecordSDK:无限兼容任何浏览器的全功能录音解决方案 +录音,RecordSDK:无限兼容任何浏览器的全功能录音一站式解决方案,一行代码搞定:语音转文字、HTTP录音、无公众号微信内JsSDK录音 https://github.com/xiangyuecn/Recorder -src: recorder-core.js,../asset-record-sdk/record-sdk/src/record-web-sdk.js +src: ../asset-record-sdk/record-sdk/src/record-web-sdk.js,../asset-record-sdk/record-sdk/src/qrcode.js */ -!function(p){"use strict";var v=function(){},O=function(e){return new t(e)};O.IsOpen=function(){var e=O.Stream;if(e){var t=e.getTracks&&e.getTracks()||e.audioTracks||[],n=t[0];if(n){var r=n.readyState;return"live"==r||r==n.LIVE}}return!1},O.BufferSize=4096,O.Destroy=function(){for(var e in console.log("Recorder Destroy"),n)n[e]()};var n={};O.BindDestroy=function(e,t){n[e]=t},O.Support=function(){var e=p.AudioContext;if(e||(e=p.webkitAudioContext),!e)return!1;var t=navigator.mediaDevices||{};return t.getUserMedia||(t=navigator).getUserMedia||(t.getUserMedia=t.webkitGetUserMedia||t.mozGetUserMedia||t.msGetUserMedia),!!t.getUserMedia&&(O.Scope=t,O.Ctx&&"closed"!=O.Ctx.state||(O.Ctx=new e,O.BindDestroy("Ctx",function(){var e=O.Ctx;e&&e.close&&e.close()})),!0)},O.SampleData=function(e,t,n,r,a){r||(r={});var o=r.index||0,i=r.offset||0,s=r.frameNext||[];a||(a={});var c=a.frameSize||1;a.frameType&&(c="mp3"==a.frameType?1152:1);for(var f=0,l=o;l"+v.length+" 花:"+(Date.now()-r)+"ms"),setTimeout(function(){r=Date.now(),a[o.type](v,function(e){c(e,u)},function(e){s(e)})})}else s("未加载"+o.type+"编码器");else s("音频被释放");else s("未采集到录音")}},p.Recorder&&p.Recorder.Destroy(),(p.Recorder=O).LM="2020-1-8 10:53:14",O.TrafficImgUrl="//ia.51.la/go1?id=20469973&pvFlag=1",O.Traffic=function(){var e=O.TrafficImgUrl;if(e){var t=O.Traffic,n=location.href.replace(/#.*/,"");if(!t[n]){t[n]=1;var r=new Image;r.src=e,console.log("Traffic Analysis Image: Recorder.TrafficImgUrl="+e)}}}}(window),"function"==typeof define&&define.amd&&define(function(){return Recorder}),"object"==typeof module&&module.exports&&(module.exports=Recorder),function(e){"use strict";var t={LM:"2020-4-19 10:41:03",ConfigSet:{}},i=function(){},n=navigator.userAgent;/\bMSIE\b/i.test(n),/MicroMessenger/i.test(n),t.Config=function(e,t,n){var r=this.ConfigSet,a={onResult:i};for(var o in r)a[o]=r[o];for(var o in e)a[o]=e[o];this.ConfigSet=a},t.Record=function(e){var t={type:"mp3",bitRate:16,sampleRate:16e3,runtime:"default",runtimeSet:{processOnly:!1,args:{},customID:""}};for(var n in e)t[n]=e[n];e=t},e.RecordSDK=t}(window),"function"==typeof define&&define.amd&&define(function(){return RecordSDK}),"object"==typeof module&&module.exports&&(module.exports=RecordSDK); \ No newline at end of file +!function(g){"use strict";var t={LM:"2020-4-19 10:41:03",ConfigSet:{},Config:function(t,e,r){var o=this.ConfigSet,n={sdkApi:"",onResult:c};for(var i in o)n[i]=o[i];for(var i in t)n[i]=t[i];t=n,(this.ConfigSet=t).sdkApi=t.sdkApi||"//jiebian.life/api/paas/recordsdk",0==t.sdkApi.indexOf("//")&&(/^https:/i.test(location.href)?t.sdkApi="https:"+t.sdkApi:t.sdkApi="http:"+t.sdkApi)},Record:function(t){var e={type:"mp3",bitRate:16,sampleRate:16e3,embedOnly:!1,runtime:"default",runtimeSet:{processOnly:!1,args:{},customID:""}};for(var r in t)e[r]=t[r];t=e}},c=function(){},p=t.RandomKey=function(t){for(var e=[],r=0;r=o.length)n();else{var e=o[t],r=e.url;!1!==e.check()?s({url:r,timeout:e.timeout||6e4},function(){u(t+1)},function(t){i(t+","+r)},a):u(t+1)}};u(0)},t.LoadJsp=function(t,e,r){"string"==typeof t&&(t={url:t}),t.jsonp||(t.jsonp=!0),s(t,e,r)},t.LoadJs=function(e,t,r,o){var n=(o=o||g).document;"string"==typeof e&&(e={url:e});var i={url:"",jsonp:"",jsonpName:"",timeout:3e4,True:t||c,False:r||c};for(var a in e)i[a]=e[a];var u,s=!1;(e=i).True==c&&e.False==c||(u=setTimeout(function(){d.onerror({message:"超时"}),s=!0},e.timeout));var h=!0===e.jsonp?"callback":e.jsonp;if(h&&!e.jsonpName){var l="RecordSDK_Jsp"+p(16),f={};f[h]=l,e.url=m(e.url,f),o[l]=function(t){clearTimeout(u),s=!0,delete o[l],0===t.c?e.True(t.v,t):e.False(t.m||"接口调用失败",t)}}var d=n.createElement("script");d.setAttribute("type","text/javascript"),d.setAttribute("src",e.url),d.onload=function(){clearTimeout(u),s||h||e.True()},d.onerror=function(t){clearTimeout(u),s||e.False("请求失败:"+t.message)},n.body.appendChild(d)});g.RecordSDK=t}(window),"function"==typeof define&&define.amd&&define(function(){return RecordSDK}),"object"==typeof module&&module.exports&&(module.exports=RecordSDK),function(){"use strict";function r(t){this.mode=o.MODE_8BIT_BYTE,this.data=t}function m(t,e){this.typeNumber=t,this.errorCorrectLevel=e,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array}r.prototype={getLength:function(t){return this.data.length},write:function(t){for(var e=0;e>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(r=0;r<18;r++){o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=M.getBCHTypeInfo(r),n=0;n<15;n++){var i=!t&&1==(o>>n&1);n<6?this.modules[n][8]=i:n<8?this.modules[n+1][8]=i:this.modules[this.moduleCount-15+n][8]=i}for(n=0;n<15;n++){i=!t&&1==(o>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=i:n<9?this.modules[8][15-n-1+1]=i:this.modules[8][15-n-1]=i}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,n=7,i=0,a=this.moduleCount-1;0>>n&1)),M.getMask(e,o,a-u)&&(s=!s),this.modules[o][a-u]=s,-1==--n&&(i++,n=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},m.PAD0=236,m.PAD1=17,m.createData=function(t,e,r){for(var o=g.getRSBlocks(t,e),n=new c,i=0;i8*u)throw new Error("code length overflow. ("+n.getLengthInBits()+">"+8*u+")");for(n.getLengthInBits()+4<=8*u&&n.put(0,4);n.getLengthInBits()%8!=0;)n.putBit(!1);for(;!(n.getLengthInBits()>=8*u||(n.put(m.PAD0,8),n.getLengthInBits()>=8*u));)n.put(m.PAD1,8);return m.createBytes(n,o)},m.createBytes=function(t,e){for(var r=0,o=0,n=0,i=new Array(e.length),a=new Array(e.length),u=0;u>>=1;return e},getPatternPosition:function(t){return M.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case n:return(e+r)%2==0;case i:return e%2==0;case a:return r%3==0;case u:return(e+r)%3==0;case s:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case h:return e*r%2+e*r%3==0;case l:return(e*r%2+e*r%3)%2==0;case f:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new C([1],0),r=0;r>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};var e=function(t){"string"==typeof t&&(t={text:t});var e={size:256,expand:0,typeNumber:-1,correctLevel:v.L,expandBackground:"",expandForeground:"",background:"#ffffff",foreground:"#000000"};for(var r in t)e[r]=t[r];(t=e).expandBackground||(t.expandBackground=t.background),t.expandForeground||(t.expandForeground=t.foreground);var o=new m(t.typeNumber,t.correctLevel);o.addData(t.text),o.make();var n=document.createElement("canvas");if(n.getContext){n.width=t.size+2*t.expand,n.height=t.size+2*t.expand;for(var i=n.getContext("2d"),a=t.size/o.getModuleCount(),u=t.expand,s=0;0'],c=(a=t.size/o.getModuleCount(),t.size/o.getModuleCount());for(s=0;s');for(h=0;h');g.push("")}g.push("");var p=document.createElement("div");return p.innerHTML=g.join("\n"),p};e.Level=v,RecordSDK.QRCode=e}(); \ No newline at end of file diff --git a/asset-record-sdk/record-sdk/src/ios-weixin-config.js b/asset-record-sdk/record-sdk/src/ios-weixin-config.js new file mode 100644 index 0000000..e69de29 diff --git a/asset-record-sdk/record-sdk/src/libs/qrcode.js b/asset-record-sdk/record-sdk/src/libs/qrcode.js new file mode 100644 index 0000000..b4f3bb2 --- /dev/null +++ b/asset-record-sdk/record-sdk/src/libs/qrcode.js @@ -0,0 +1,1395 @@ +/* +二维码https://github.com/jeromeetienne/jquery-qrcode + +自定义:屏蔽变量,提供RecordSDK.QRCode、RecordSDK.QRCode.Level,QRCode()返回canvas节点对象,有限支持低版本浏览器返回table div节点对象 +QRCode(str||{ + text: str,//二维码数据 + size : 256,//二维码尺寸 + expand : 0,//二维码外部扩展显示尺寸,类似padding,内容为随机点,table无效 + typeNumber : -1, //计算模式 + correctLevel : QRErrorCorrectLevel.L,//纠错等级 + expandBackground:background//扩展背景色,默认为背景色 + expandForeground:foreground//扩展前景色,默认为前景色 + background : "#ffffff",//背景颜色 + foreground : "#000000" //前景颜色 +}); +*/ + +(function(){ +"use strict"; + +//--------------------------------------------------------------------- +// QRCode for JavaScript +// +// Copyright (c) 2009 Kazuhiko Arase +// +// URL: http://www.d-project.com/ +// +// Licensed under the MIT license: +// http://www.opensource.org/licenses/mit-license.php +// +// The word "QR Code" is registered trademark of +// DENSO WAVE INCORPORATED +// http://www.denso-wave.com/qrcode/faqpatent-e.html +// +//--------------------------------------------------------------------- + +//--------------------------------------------------------------------- +// QR8bitByte +//--------------------------------------------------------------------- + +function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; +} + +QR8bitByte.prototype = { + + getLength : function(buffer) { + return this.data.length; + }, + + write : function(buffer) { + for (var i = 0; i < this.data.length; i++) { + // not JIS ... + buffer.put(this.data.charCodeAt(i), 8); + } + } +}; + +//--------------------------------------------------------------------- +// QRCode +//--------------------------------------------------------------------- + +function QRCode(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = new Array(); +} + +QRCode.prototype = { + + addData : function(data) { + var newData = new QR8bitByte(data); + this.dataList.push(newData); + this.dataCache = null; + }, + + isDark : function(row, col) { + if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { + throw new Error(row + "," + col); + } + return this.modules[row][col]; + }, + + getModuleCount : function() { + return this.moduleCount; + }, + + make : function() { + // Calculate automatically typeNumber if provided is < 1 + if (this.typeNumber < 1 ){ + var typeNumber = 1; + for (typeNumber = 1; typeNumber < 40; typeNumber++) { + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); + + var buffer = new QRBitBuffer(); + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + for (var i = 0; i < this.dataList.length; i++) { + var data = this.dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) ); + data.write(buffer); + } + if (buffer.getLengthInBits() <= totalDataCount * 8) + break; + } + this.typeNumber = typeNumber; + } + this.makeImpl(false, this.getBestMaskPattern() ); + }, + + makeImpl : function(test, maskPattern) { + + this.moduleCount = this.typeNumber * 4 + 17; + this.modules = new Array(this.moduleCount); + + for (var row = 0; row < this.moduleCount; row++) { + + this.modules[row] = new Array(this.moduleCount); + + for (var col = 0; col < this.moduleCount; col++) { + this.modules[row][col] = null;//(col + row) % 3; + } + } + + this.setupPositionProbePattern(0, 0); + this.setupPositionProbePattern(this.moduleCount - 7, 0); + this.setupPositionProbePattern(0, this.moduleCount - 7); + this.setupPositionAdjustPattern(); + this.setupTimingPattern(); + this.setupTypeInfo(test, maskPattern); + + if (this.typeNumber >= 7) { + this.setupTypeNumber(test); + } + + if (this.dataCache == null) { + this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); + } + + this.mapData(this.dataCache, maskPattern); + }, + + setupPositionProbePattern : function(row, col) { + + for (var r = -1; r <= 7; r++) { + + if (row + r <= -1 || this.moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c++) { + + if (col + c <= -1 || this.moduleCount <= col + c) continue; + + if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) + || (0 <= c && c <= 6 && (r == 0 || r == 6) ) + || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + }, + + getBestMaskPattern : function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i++) { + + this.makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }, + + createMovieClip : function(target_mc, instance_name, depth) { + + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); + var cs = 1; + + this.make(); + + for (var row = 0; row < this.modules.length; row++) { + + var y = row * cs; + + for (var col = 0; col < this.modules[row].length; col++) { + + var x = col * cs; + var dark = this.modules[row][col]; + + if (dark) { + qr_mc.beginFill(0, 100); + qr_mc.moveTo(x, y); + qr_mc.lineTo(x + cs, y); + qr_mc.lineTo(x + cs, y + cs); + qr_mc.lineTo(x, y + cs); + qr_mc.endFill(); + } + } + } + + return qr_mc; + }, + + setupTimingPattern : function() { + + for (var r = 8; r < this.moduleCount - 8; r++) { + if (this.modules[r][6] != null) { + continue; + } + this.modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < this.moduleCount - 8; c++) { + if (this.modules[6][c] != null) { + continue; + } + this.modules[6][c] = (c % 2 == 0); + } + }, + + setupPositionAdjustPattern : function() { + + var pos = QRUtil.getPatternPosition(this.typeNumber); + + for (var i = 0; i < pos.length; i++) { + + for (var j = 0; j < pos.length; j++) { + + var row = pos[i]; + var col = pos[j]; + + if (this.modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r++) { + + for (var c = -2; c <= 2; c++) { + + if (r == -2 || r == 2 || c == -2 || c == 2 + || (r == 0 && c == 0) ) { + this.modules[row + r][col + c] = true; + } else { + this.modules[row + r][col + c] = false; + } + } + } + } + } + }, + + setupTypeNumber : function(test) { + + var bits = QRUtil.getBCHTypeNumber(this.typeNumber); + + for (var i = 0; i < 18; i++) { + var mod = (!test && ( (bits >> i) & 1) == 1); + this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i++) { + var mod = (!test && ( (bits >> i) & 1) == 1); + this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }, + + setupTypeInfo : function(test, maskPattern) { + + var data = (this.errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i++) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 6) { + this.modules[i][8] = mod; + } else if (i < 8) { + this.modules[i + 1][8] = mod; + } else { + this.modules[this.moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i++) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 8) { + this.modules[8][this.moduleCount - i - 1] = mod; + } else if (i < 9) { + this.modules[8][15 - i - 1 + 1] = mod; + } else { + this.modules[8][15 - i - 1] = mod; + } + } + + // fixed module + this.modules[this.moduleCount - 8][8] = (!test); + + }, + + mapData : function(data, maskPattern) { + + var inc = -1; + var row = this.moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + var True=true; + + for (var col = this.moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col--; + + while (True) { + + for (var c = 0; c < 2; c++) { + + if (this.modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = QRUtil.getMask(maskPattern, row, col - c); + + if (mask) { + dark = !dark; + } + + this.modules[row][col - c] = dark; + bitIndex--; + + if (bitIndex == -1) { + byteIndex++; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || this.moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + + } + +}; + +QRCode.PAD0 = 0xEC; +QRCode.PAD1 = 0x11; + +QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = new QRBitBuffer(); + + for (var i = 0; i < dataList.length; i++) { + var data = dataList[i]; + buffer.put(data.mode, 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) ); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error("code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + + ")"); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(QRCode.PAD1, 8); + } + + return QRCode.createBytes(buffer, rsBlocks); +} + +QRCode.createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r++) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i++) { + dcdata[r][i] = 0xff & buffer.buffer[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i++) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0; + } + + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i++) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < dcdata[r].length) { + data[index++] = dcdata[r][i]; + } + } + } + + for (var i = 0; i < maxEcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < ecdata[r].length) { + data[index++] = ecdata[r][i]; + } + } + } + + return data; + +} + +//--------------------------------------------------------------------- +// QRMode +//--------------------------------------------------------------------- + +var QRMode = { + MODE_NUMBER : 1 << 0, + MODE_ALPHA_NUM : 1 << 1, + MODE_8BIT_BYTE : 1 << 2, + MODE_KANJI : 1 << 3 +}; + +//--------------------------------------------------------------------- +// QRErrorCorrectLevel +//--------------------------------------------------------------------- + +var QRErrorCorrectLevel = { + L : 1, + M : 0, + Q : 3, + H : 2 +}; + +//--------------------------------------------------------------------- +// QRMaskPattern +//--------------------------------------------------------------------- + +var QRMaskPattern = { + PATTERN000 : 0, + PATTERN001 : 1, + PATTERN010 : 2, + PATTERN011 : 3, + PATTERN100 : 4, + PATTERN101 : 5, + PATTERN110 : 6, + PATTERN111 : 7 +}; + +//--------------------------------------------------------------------- +// QRUtil +//--------------------------------------------------------------------- + +var QRUtil = { + + PATTERN_POSITION_TABLE : [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ], + + G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), + G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), + G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), + + getBCHTypeInfo : function(data) { + var d = data << 10; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { + d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); + } + return ( (data << 10) | d) ^ QRUtil.G15_MASK; + }, + + getBCHTypeNumber : function(data) { + var d = data << 12; + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { + d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); + } + return (data << 12) | d; + }, + + getBCHDigit : function(data) { + + var digit = 0; + + while (data != 0) { + digit++; + data >>>= 1; + } + + return digit; + }, + + getPatternPosition : function(typeNumber) { + return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; + }, + + getMask : function(maskPattern, i, j) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0; + case QRMaskPattern.PATTERN001 : return i % 2 == 0; + case QRMaskPattern.PATTERN010 : return j % 3 == 0; + case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0; + case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; + case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0; + case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; + case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; + + default : + throw new Error("bad maskPattern:" + maskPattern); + } + }, + + getErrorCorrectPolynomial : function(errorCorrectLength) { + + var a = new QRPolynomial([1], 0); + + for (var i = 0; i < errorCorrectLength; i++) { + a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0) ); + } + + return a; + }, + + getLengthInBits : function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch(mode) { + case QRMode.MODE_NUMBER : return 10; + case QRMode.MODE_ALPHA_NUM : return 9; + case QRMode.MODE_8BIT_BYTE : return 8; + case QRMode.MODE_KANJI : return 8; + default : + throw new Error("mode:" + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch(mode) { + case QRMode.MODE_NUMBER : return 12; + case QRMode.MODE_ALPHA_NUM : return 11; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 10; + default : + throw new Error("mode:" + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch(mode) { + case QRMode.MODE_NUMBER : return 14; + case QRMode.MODE_ALPHA_NUM : return 13; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 12; + default : + throw new Error("mode:" + mode); + } + + } else { + throw new Error("type:" + type); + } + }, + + getLostPoint : function(qrCode) { + + var moduleCount = qrCode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row++) { + + for (var col = 0; col < moduleCount; col++) { + + var sameCount = 0; + var dark = qrCode.isDark(row, col); + + for (var r = -1; r <= 1; r++) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c++) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrCode.isDark(row + r, col + c) ) { + sameCount++; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + } + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row++) { + for (var col = 0; col < moduleCount - 1; col++) { + var count = 0; + if (qrCode.isDark(row, col ) ) count++; + if (qrCode.isDark(row + 1, col ) ) count++; + if (qrCode.isDark(row, col + 1) ) count++; + if (qrCode.isDark(row + 1, col + 1) ) count++; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount - 6; col++) { + if (qrCode.isDark(row, col) + && !qrCode.isDark(row, col + 1) + && qrCode.isDark(row, col + 2) + && qrCode.isDark(row, col + 3) + && qrCode.isDark(row, col + 4) + && !qrCode.isDark(row, col + 5) + && qrCode.isDark(row, col + 6) ) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount - 6; row++) { + if (qrCode.isDark(row, col) + && !qrCode.isDark(row + 1, col) + && qrCode.isDark(row + 2, col) + && qrCode.isDark(row + 3, col) + && qrCode.isDark(row + 4, col) + && !qrCode.isDark(row + 5, col) + && qrCode.isDark(row + 6, col) ) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount; row++) { + if (qrCode.isDark(row, col) ) { + darkCount++; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + } + +}; + + +//--------------------------------------------------------------------- +// QRMath +//--------------------------------------------------------------------- + +var QRMath = { + + glog : function(n) { + + if (n < 1) { + throw new Error("glog(" + n + ")"); + } + + return QRMath.LOG_TABLE[n]; + }, + + gexp : function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return QRMath.EXP_TABLE[n]; + }, + + EXP_TABLE : new Array(256), + + LOG_TABLE : new Array(256) + +}; + +for (var i = 0; i < 8; i++) { + QRMath.EXP_TABLE[i] = 1 << i; +} +for (var i = 8; i < 256; i++) { + QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] + ^ QRMath.EXP_TABLE[i - 5] + ^ QRMath.EXP_TABLE[i - 6] + ^ QRMath.EXP_TABLE[i - 8]; +} +for (var i = 0; i < 255; i++) { + QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i; +} + +//--------------------------------------------------------------------- +// QRPolynomial +//--------------------------------------------------------------------- + +function QRPolynomial(num, shift) { + + if (num.length == undefined) { + throw new Error(num.length + "/" + shift); + } + + var offset = 0; + + + while (offset < num.length && num[offset] == 0) { + offset++; + } + + this.num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i++) { + this.num[i] = num[i + offset]; + } +} + +QRPolynomial.prototype = { + + get : function(index) { + return this.num[index]; + }, + + getLength : function() { + return this.num.length; + }, + + multiply : function(e) { + + var num = new Array(this.getLength() + e.getLength() - 1); + + for (var i = 0; i < this.getLength(); i++) { + for (var j = 0; j < e.getLength(); j++) { + num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i) ) + QRMath.glog(e.get(j) ) ); + } + } + + return new QRPolynomial(num, 0); + }, + + mod : function(e) { + + if (this.getLength() - e.getLength() < 0) { + return this; + } + + var ratio = QRMath.glog(this.get(0) ) - QRMath.glog(e.get(0) ); + + var num = new Array(this.getLength() ); + + for (var i = 0; i < this.getLength(); i++) { + num[i] = this.get(i); + } + + for (var i = 0; i < e.getLength(); i++) { + num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio); + } + + // recursive call + return new QRPolynomial(num, 0).mod(e); + } +}; + +//--------------------------------------------------------------------- +// QRRSBlock +//--------------------------------------------------------------------- + +function QRRSBlock(totalCount, dataCount) { + this.totalCount = totalCount; + this.dataCount = dataCount; +} + +QRRSBlock.RS_BLOCK_TABLE = [ + + // L + // M + // Q + // H + + // 1 + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + + // 2 + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + + // 3 + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + + // 4 + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + + // 5 + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + + // 6 + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + + // 7 + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + + // 8 + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + + // 9 + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + + // 10 + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + + // 11 + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + + // 12 + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + + // 13 + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + + // 14 + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + + // 15 + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12], + + // 16 + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + + // 17 + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + + // 18 + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + + // 19 + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + + // 20 + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + + // 21 + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + + // 22 + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + + // 23 + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + + // 24 + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + + // 25 + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + + // 26 + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + + // 27 + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + + // 28 + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + + // 29 + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + + // 30 + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + + // 31 + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + + // 32 + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + + // 33 + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + + // 34 + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + + // 35 + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + + // 36 + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + + // 37 + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + + // 38 + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + + // 39 + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + + // 40 + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] +]; + +QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); + + if (rsBlock == undefined) { + throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i++) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j++) { + list.push(new QRRSBlock(totalCount, dataCount) ); + } + } + + return list; +} + +QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch(errorCorrectLevel) { + case QRErrorCorrectLevel.L : + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M : + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q : + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H : + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default : + return undefined; + } +} + +//--------------------------------------------------------------------- +// QRBitBuffer +//--------------------------------------------------------------------- + +function QRBitBuffer() { + this.buffer = new Array(); + this.length = 0; +} + +QRBitBuffer.prototype = { + + get : function(index) { + var bufIndex = Math.floor(index / 8); + return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; + }, + + put : function(num, length) { + for (var i = 0; i < length; i++) { + this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); + } + }, + + getLengthInBits : function() { + return this.length; + }, + + putBit : function(bit) { + + var bufIndex = Math.floor(this.length / 8); + if (this.buffer.length <= bufIndex) { + this.buffer.push(0); + } + + if (bit) { + this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) ); + } + + this.length++; + } +}; + + + + + + + + + +var QRCodeFn=function(options){ + // if options is string, + if( typeof options === 'string' ){ + options = { text: options }; + } + + // set default values + // typeNumber < 1 for automatic calculation + var baseOpt={ + size : 256, + expand : 0, + typeNumber : -1, + correctLevel : QRErrorCorrectLevel.L, + expandBackground:"", + expandForeground:"", + background : "#ffffff", + foreground : "#000000" + }; + for(var k in options){ + baseOpt[k]=options[k]; + }; + options = baseOpt; + options.expandBackground||(options.expandBackground=options.background); + options.expandForeground||(options.expandForeground=options.foreground); + + // create the qrcode itself + var qrcode = new QRCode(options.typeNumber, options.correctLevel); + qrcode.addData(options.text); + qrcode.make(); + + // create canvas element + var canvas = document.createElement('canvas'); + if(canvas.getContext){ +//**浏览器兼容canvas** + + canvas.width = options.size+options.expand*2; + canvas.height = options.size+options.expand*2; + var ctx = canvas.getContext('2d'); + + var tileW = options.size / qrcode.getModuleCount(); + + var expand=options.expand,row=0; + while(expand>0){ + expand-=tileW; + for(var col=0,len=Math.ceil((options.size+options.expand*2)/tileW);col=0;col--){ + ctx.fillStyle = Math.random()<0.45 ? options.expandForeground : options.expandBackground; + var w = (Math.ceil((col+1)*tileW) - Math.floor(col*tileW)); + var h = (Math.ceil((row+1)*tileW) - Math.floor(row*tileW)); + ctx.fillRect(Math.round(col*tileW),options.expand+Math.round(row*tileW), w, h); + }; + for( var col = 0; col < qrcode.getModuleCount(); col++ ){ + ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background; + var w = (Math.ceil((col+1)*tileW) - Math.floor(col*tileW)); + var h = (Math.ceil((row+1)*tileW) - Math.floor(row*tileW)); + ctx.fillRect(options.expand+Math.round(col*tileW),options.expand+Math.round(row*tileW), w, h); + }; + for(var col=0,len=Math.ceil(options.expand/tileW);col']; + +// compute tileS percentage +var tileW = options.size / qrcode.getModuleCount(); +var tileH = options.size / qrcode.getModuleCount(); + +// draw in the table +for(var row = 0; row < qrcode.getModuleCount(); row++ ){ + $table.push(''); + + for(var col = 0; col < qrcode.getModuleCount(); col++ ){ + $table.push(''); + }; + $table.push(''); +}; +$table.push(''); +// return just built canvas +var div=document.createElement("div"); +div.innerHTML=$table.join("\n"); +return div; +}; + +QRCodeFn.Level=QRErrorCorrectLevel; +RecordSDK.QRCode=QRCodeFn; + +})(); \ No newline at end of file diff --git a/asset-record-sdk/record-sdk/src/native-config.js b/asset-record-sdk/record-sdk/src/native-config.js new file mode 100644 index 0000000..e69de29 diff --git a/asset-record-sdk/record-sdk/src/record-web-sdk.js b/asset-record-sdk/record-sdk/src/record-web-sdk.js index c64d2d9..1aef684 100644 --- a/asset-record-sdk/record-sdk/src/record-web-sdk.js +++ b/asset-record-sdk/record-sdk/src/record-web-sdk.js @@ -19,18 +19,19 @@ https://github.com/xiangyuecn/Recorder var RecordSDK={ LM:"2020-4-19 10:41:03" -,ConfigSet:{} +,ConfigSet:{} //Config设置的配置 +,ConfigSrv:{} //加载到的服务器端配置,数据参考服务器端getConfig接口 }; /** -RecordSDK配置函数,配置成功会调用True回调,否则走False +RecordSDK配置函数,配置成功会调用True回调,否则走False;可以多次进行参数配置,js加载后立即进行一次调用,拉取服务器端配置信息;页面准备完毕后再进行一次调用,配置onResult回调,会尝试拿到上次可能存在的录音结果。 True() 配置成功回调 False(errMsg) 配置失败回调 set={ - sdkApi:"" + sdkApi:"" //sdk的api服务地址,一般情况下无需设置;如果已获得服务器端源码部署了时提供你的地址,参考RecordSDK服务器端部署相关文档 ,onResult:fn(res) 当收到录音结果时回调,此回调可能会在录音结束时、Config完毕并且拿到了返回的录音时回调 res={ @@ -51,7 +52,7 @@ set={ RecordSDK.Config=function(set,True,False){ var This=this,Conf=This.ConfigSet; var baseSet={ - sdkApi:"//recordsdk.jiebian.life/npi/recordsdk" + sdkApi:"" ,onResult:NOOP }; for(var k in Conf){ @@ -61,17 +62,53 @@ RecordSDK.Config=function(set,True,False){ baseSet[k]=set[k]; }; set=baseSet; - This.ConfigSet=set; + This.ConfigSet=Conf=set; //给api加上http前缀,如果是file协议下,不加前缀没法用 - if(set.sdkApi.indexOf("//")==0){ + Conf.sdkApi=Conf.sdkApi||"//jiebian.life/paas/recordsdk"; + if(Conf.sdkApi.indexOf("//")==0){ if(/^https:/i.test(location.href)){ - set.sdkApi="https:"+set.sdkApi; + Conf.sdkApi="https:"+Conf.sdkApi; }else{ - set.sdkApi="http:"+set.sdkApi; + Conf.sdkApi="http:"+Conf.sdkApi; }; }; + var state=Conf._state;//0 未初始化 1 配置加载中 2 配置加载失败 3 配置加载成功 + var callbacks=Conf._cbs||[]; + Conf._cbs=callbacks; + if(state==3){ + True&&True(); + return; + }; + callbacks.push({t:True||NOOP,f:False||NOOP}); + if(state==1){ + return; + }; + + var end=function(s,m){ + Conf._state=s; + for(var i=0;i=urls.length){ + True(); + return; + }; + var itm=urls[idx]; + var url=itm.url; + if(itm.check()===false){ + load(idx+1); + return; + }; + + LoadJs({ + url:url + ,timeout:itm.timeout||60000 + },function(){ + load(idx+1); + },function(msg){ + False(msg+","+url); + },win); + }; + load(0); +}; +/** +发起一个POST请求。此方法无需低版本兼容处理,能调用此方法的说明浏览器能录音 +True(data,apiData) +False(msg, apiDataOrNull) + +set={ + url:"" 请求地址,可以不填,默认为sdkApi + ,timeout:30000 请求超时,默认30秒 +} +**/ +var LoadData=RecordSDK.LoadData=function(set,data,True,False){ + True=True||NOOP; + False=False||NOOP; + if(typeof(set)=="string"){ + set={url:set}; + }; + set.url=set.url||RecordSDK.ConfigSet.sdkApi; + + var xhr=new XMLHttpRequest(); + xhr.timeout=set.timeout||30000; + xhr.open("POST",set.url,true); + xhr.onreadystatechange=function(){ + if(xhr.readyState==4){ + if(xhr.status==200){ + try{ + var o=JSON.parse(xhr.responseText); + }catch(e){ + var m="接口返回未知格式数据"; + Log(m,e,1); + False(m); + return; + }; + if(o.c!==0){ + False(o.m,o); + return; + }; + True(o.v,o); + }else{ + False("请求失败["+xhr.status+"]"); + } + } + }; + var arr=[]; + for(var k in data){ + arr.push(k+"="+encodeURIComponent(data[k])); + }; + xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); + xhr.send(arr.join("&")); +}; +/** +发起一个jsonp GET请求 +True(data,apiData) +False(msg, apiDataOrNull) + +data:{} 可选请求参数,会拼接到url中 +set={ + url:"" 请求地址,可以不填,默认为sdkApi + ,allowCache:false 是否允许缓存,默认不允许会在url中添加t当前时间参数 + ,timeout:30000 请求超时,默认30秒 +} +**/ +var LoadJsp=RecordSDK.LoadJsp=function(set,data,True,False){ + if(typeof(set)=="string"){ + set={url:set}; + }; + set.url=set.url||RecordSDK.ConfigSet.sdkApi; + + data=data||{}; + if(!set.allowCache&&!data.t){ + data.t=Now().toString(36); + }; + set.url=SetParam(set.url,data); + + if(!set.jsonp){ + set.jsonp=true; + }; + LoadJs(set,True,False); +}; +var LoadJs=RecordSDK.LoadJs=function(set,True,False,win){ + win=win||window; + var doc=win.document; + if(typeof(set)=="string"){ + set={url:set}; + }; + + var baseSet={ + url:"" + ,jsonp:"" //true="callback"||"param" 存在为jsonp请求 + ,timeout:30000 + ,True:True||NOOP //True()|True(data,apiData) jsonp时为后面这个 + ,False:False||NOOP //False(msg, apiDataOrNull) + }; + for(var k in set){ + baseSet[k]=set[k]; + }; + set=baseSet; + + var isTimeout=false,int; + if(set.True!=NOOP || set.False!=NOOP){ + int=setTimeout(function(){ + elem.onerror({message:"超时"}); + isTimeout=true; + },set.timeout); + }; + var jsonp=set.jsonp===true?"callback":set.jsonp; + var jsonpOk=0; + if(jsonp){ + var key="RecordSDK_Jsp"+RandomKey(16); + var param={};param[jsonp]=key; + set.url=SetParam(set.url,param); + win[key]=function(data){ + clearTimeout(int); + jsonpOk=isTimeout=true; + delete win[key]; + + if(data.c!==0){ + set.False(data.m||"接口调用失败",data); + return; + }; + set.True(data.v,data); + }; + }; + + var elem=doc.createElement("script"); + elem.setAttribute("type","text/javascript"); + elem.setAttribute("src",set.url); + elem.onload=function(){ + clearTimeout(int); + if(jsonp){ + if(jsonpOk){ + return; + }; + set.False("请求失败:无响应"); + return; + }; + if(isTimeout){ + return; + }; + set.True(); + }; + elem.onerror=function(e){ + clearTimeout(int); + if(isTimeout){ + return; + }; + set.False("请求失败:"+(e.message||"-")); + }; + doc.body.appendChild(elem); +}; + + + var checkSupportH5=function(){ var AC=window.AudioContext||window.webkitAudioContext; if(!AC){ diff --git a/asset-record-sdk/record-sdk/web-server/README.txt b/asset-record-sdk/record-sdk/web-server/README.txt new file mode 100644 index 0000000..188814b --- /dev/null +++ b/asset-record-sdk/record-sdk/web-server/README.txt @@ -0,0 +1,19 @@ + + +# 接口定义 +入口URL只有一个(默认为`https://xxx/paas/recordsdk`),通过请求action参数区分不同接口。接口调用方式为两种:GET(jsonp),POST(xhr)。 + + +## getConfig +### GET参数 +无 + +### 响应 +``` javascript +{ + limit:"" //是否受限,如果不为空将限制使用 + ,logMsg:"" //控制台提示消息 + ,url_RecordAppConfigFolder:"https://cdn.jsdelivr.net/gh/xiangyuecn/Recorder@latest/asset-record-sdk/record-sdk/dist/" //RecordApp配置目录,里面包含ios-weixin-config.js、native-config.js文件,必须为完整https url /结尾 + ,url_RecordAppBaseFolder:"https://cdn.jsdelivr.net/gh/xiangyuecn/Recorder@latest/dist/" //Recorder目录,会从里面加载RecordApp和Recorder,必须为完整https url /结尾 +} +``` \ No newline at end of file diff --git a/src/package-build.js b/src/package-build.js index c61de8b..ffe571d 100644 --- a/src/package-build.js +++ b/src/package-build.js @@ -60,7 +60,9 @@ function Run_minify(){ minify("../dist/extensions/frequency.histogram.view.js",["extensions/frequency.histogram.view.js"]); minify("../dist/extensions/sonic.js",["extensions/sonic.js"]); - minify("../asset-record-sdk/record-sdk/record-web-sdk.js",["../asset-record-sdk/record-sdk/src/record-web-sdk.js"]); + minify("../asset-record-sdk/record-sdk/record-web-sdk.js",["../asset-record-sdk/record-sdk/src/record-web-sdk.js","../asset-record-sdk/record-sdk/src/libs/qrcode.js"]); + minify("../asset-record-sdk/record-sdk/dist/ios-weixin-config.js",["../asset-record-sdk/record-sdk/src/ios-weixin-config.js"]); + minify("../asset-record-sdk/record-sdk/dist/native-config.js",["../asset-record-sdk/record-sdk/src/native-config.js"]); console.log("\x1B[33m%s\x1B[0m","处理完成"); }; From eb214c30eaf9a5b7a3f6b5faacada43d959d4d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AB=98=E5=9D=9A=E6=9E=9C?= <753610399@qq.com> Date: Thu, 7 May 2020 09:17:42 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=B8=BB=E7=BA=BF?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +++++++----- assets/qq_group_421882406.png | Bin 0 -> 29984 bytes 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 assets/qq_group_421882406.png diff --git a/README.md b/README.md index 522ea5b..1b2bc33 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # :open_book:Recorder用于html5录音 -[​](?Ref=Desc&Start)[在线测试](https://xiangyuecn.github.io/Recorder/),支持大部分已实现`getUserMedia`的移动端、PC端浏览器;主要包括:Chrome、Firefox、Safari、Android WebView、腾讯Android X5内核(QQ、微信);不支持:UC系内核(典型的支付宝,大部分国产手机厂商的浏览器),IOS上除Safari外的其他任何形式的浏览器(含PWA、WebClip、任何App内网页)。快捷方式: [【QuickStart】](https://xiangyuecn.github.io/Recorder/QuickStart.html),[【RecordApp测试】](https://jiebian.life/web/h5/github/recordapp.aspx),[【vue+webpack测试】](https://xiangyuecn.github.io/Recorder/assets/demo-vue),[【Android、IOS App Demo】](https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample),[【工具】Recorder代码运行和静态分发](https://xiangyuecn.github.io/Recorder/assets/%E5%B7%A5%E5%85%B7-%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E5%92%8C%E9%9D%99%E6%80%81%E5%88%86%E5%8F%91Runtime.html),[【工具】裸(RAW、WAV)PCM转WAV播放测试和转码](https://xiangyuecn.github.io/Recorder/assets/%E5%B7%A5%E5%85%B7-%E8%A3%B8PCM%E8%BD%ACWAV%E6%92%AD%E6%94%BE%E6%B5%8B%E8%AF%95.html) ,[无用户操作测试](https://xiangyuecn.github.io/Recorder/assets/ztest_no_user_operation.html),[【Can I Use】查看浏览器支持情况](https://caniuse.com/#search=getUserMedia)。 +[​](?Ref=Desc&Start)[在线测试](https://xiangyuecn.github.io/Recorder/),支持大部分已实现`getUserMedia`的移动端、PC端浏览器;主要包括:Chrome、Firefox、Safari、Android WebView、腾讯Android X5内核(QQ、微信);不支持:~~UC系内核(典型的支付宝),大部分国产手机厂商自研套壳娱乐浏览器,IOS上除Safari外的其他任何形式的浏览器(含PWA、WebClip、任何App内网页)~~。快捷方式: [【QuickStart】](https://xiangyuecn.github.io/Recorder/QuickStart.html),[【RecordApp测试】](https://jiebian.life/web/h5/github/recordapp.aspx),[【vue+webpack测试】](https://xiangyuecn.github.io/Recorder/assets/demo-vue),[【Android、IOS App Demo】](https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample),[【工具】Recorder代码运行和静态分发](https://xiangyuecn.github.io/Recorder/assets/%E5%B7%A5%E5%85%B7-%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E5%92%8C%E9%9D%99%E6%80%81%E5%88%86%E5%8F%91Runtime.html),[【工具】裸(RAW、WAV)PCM转WAV播放测试和转码](https://xiangyuecn.github.io/Recorder/assets/%E5%B7%A5%E5%85%B7-%E8%A3%B8PCM%E8%BD%ACWAV%E6%92%AD%E6%94%BE%E6%B5%8B%E8%AF%95.html) ,[【无用户操作测试】](https://xiangyuecn.github.io/Recorder/assets/ztest_no_user_operation.html),[【Can I Use】查看浏览器支持情况](https://caniuse.com/#search=getUserMedia)。 录音默认输出mp3格式,另外可选wav格式;有限支持ogg(beta)、webm(beta)、amr(beta)格式;支持任意格式扩展(前提有相应编码器)。 @@ -10,7 +10,7 @@ mp3使用lamejs编码(CBR),压缩后的recorder.mp3.min.js文件150kb左右( 如需在Hybrid App内使用(支持IOS、Android),或提供IOS微信的支持,请参阅[app-support-sample](https://github.com/xiangyuecn/Recorder/tree/master/app-support-sample)目录。 -*IOS、国产厂商系统浏览器上的使用限制等问题和兼容请参阅下面的知识库部分;打开录音后对音频播放的影响、录音中途来电话等问题也参阅下面的知识库。* +*IOS、国产厂商自研套壳娱乐浏览器上的使用限制等问题和兼容请参阅下面的知识库部分;打开录音后对音频播放的影响、录音中途来电话等问题也参阅下面的知识库。*

Recorder logo

@@ -266,7 +266,7 @@ $.ajax({ 浏览器Audio Media[兼容性](https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats#Browser_compatibility)mp3最好,wav还行,其他要么不支持播放,要么不支持编码;因此本库最佳推荐使用mp3、wav格式,代码也是优先照顾这两种格式。 -**特别注**:`IOS(11.X、12.X)`上只有`Safari`支持`getUserMedia`,IOS上其他浏览器均不支持,参考下面的已知问题。 +**特别注**:`IOS(11.X、12.X、13.X)`上只有`Safari`支持`getUserMedia`,IOS上其他浏览器均不支持,唯一有点卵用的Safari `getUserMedia` 底层实现bug奇多(严重关切他们团队水准,临时工少发工资了吧),参考下面的已知问题。 **特别注**:大部分国产手机厂商的浏览器(系统浏览器,都用的UC内核?)虽然支持`getUserMedia`方法,但并不能使用,表现为直接返回拒绝或者干脆没有任何回调;UC系列目测全部阵亡(含支付宝)。 @@ -297,7 +297,7 @@ IOS其他浏览器|| ## 已知问题 -*2018-09-19* [caniuse](https://caniuse.com/#search=getUserMedia) 注明`IOS` `11.X - 12.X` 上 只有`Safari`支持调用`getUserMedia`,其他App下WKWebView(UIWebView?)([相关资料](https://forums.developer.apple.com/thread/88052))均不支持。经用户测试验证IOS 12上chrome、UC都无法录音,部分IOS 12 Safari可以获取到并且能正常录音,但部分不行,原因未知,参考[ios 12 支不支持录音了](https://www.v2ex.com/t/490695)。在IOS上不支持录音的环境下应该采用其他解决方案,参考`案例演示`、`关于微信JsSDK`部分。 +*2018-09-19* [caniuse](https://caniuse.com/#search=getUserMedia) 注明`IOS` `11.X - 12.X(13.X)` 上 只有`Safari`支持调用`getUserMedia`,其他App下WKWebView(UIWebView?)([相关资料](https://forums.developer.apple.com/thread/88052))均不支持。经用户测试验证IOS 12上chrome、UC都无法录音,部分IOS 12 Safari可以获取到并且能正常录音,但部分不行,原因未知,参考[ios 12 支不支持录音了](https://www.v2ex.com/t/490695)。在IOS上不支持录音的环境下应该采用其他解决方案,参考`案例演示`、`关于微信JsSDK`部分。 *2019-02-28* [issues#14](https://github.com/xiangyuecn/Recorder/issues/14) 如果`getUserMedia`返回的[`MediaStreamTrack.readyState == "ended"`,`"ended" which indicates that the input is not giving any more data and will never provide new data.`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack) ,导致无法录音。如果产生这种情况,目前在`rec.open`方法调用时会正确检测到,并执行`fail`回调。造成`issues#14` `ended`原因是App源码中`AndroidManifest.xml`中没有声明`android.permission.MODIFY_AUDIO_SETTINGS`权限,导致腾讯X5不能正常录音。 @@ -305,12 +305,14 @@ IOS其他浏览器|| *2019-06-14* 经[#29](https://github.com/xiangyuecn/Recorder/issues/29)反馈,稍微远程真机测试了部分厂商的比较新的Android手机系统浏览器的录音支持情况;华为:直接返回拒绝,小米:没有回调,OPPO:好像是没有回调,vivo:好像是没有回调;另外专门测试了一下UC最新版(支付宝):直接返回拒绝。另[参考](https://www.jianshu.com/p/6cd5a7fa562c)。也许他们都商量好了或者本身都是用的UC?至于没有任何回调的,此种浏览器没有良心。 -*2019-07-22* 对[#34](https://github.com/xiangyuecn/Recorder/issues/34)反馈研究后发现,问题一:macOS、IOS的Safari对连续调用录音(中途未调用close)是有问题的,但只要调用close后再重复录音就没有问题。问题二:IOS上如果录音之前先播放了任何Audio,录音过程可能会变得很诡异,但如果先录音,就不存在此问题(19-09-18 Evan:QQ1346751357反馈发现本问题并非必现,[功能页面](https://hft.bigdatahefei.com/LocateSearchService/sfc/index),但本库的Demo内却必现,原因不明)。chrome、firefox正常的很。目测这两个问题是非我等屌丝能够解决的,于是报告给苹果家程序员看看,因此发了个[帖子](https://forums.developer.apple.com/message/373108),顺手在`Feedback Assistant`提交了`bug report`,但好几天过去了没有任何回应(顺带给微软一个好评)。问题一目前已通过全局共享一个MediaStream连接来解决,原因在于Safari上MediaStream断开后就无法再次进行连接使用(表现为静音),改成了全局只连接一次就避免了此问题;全局处理也有利于屏蔽底层细节,start时无需再调用底层接口,提升兼容、可靠性。 +*2019-07-22* 对[#34](https://github.com/xiangyuecn/Recorder/issues/34)反馈研究后发现,问题一:~~macOS、IOS的Safari对连续调用录音(中途未调用close)是有问题的,但只要调用close后再重复录音就没有问题~~(已通过特殊手段解决)。问题二:IOS上如果录音之前先播放了任何Audio,录音过程可能会变得很诡异,但如果先录音,就不存在此问题(19-09-18 Evan:QQ1346751357反馈发现本问题并非必现,[功能页面](https://hft.bigdatahefei.com/LocateSearchService/sfc/index),但本库的Demo内却必现,原因不明)。chrome、firefox正常的很。目测这两个问题是非我等屌丝能够解决的,于是报告给苹果家程序员看看,因此发了个[帖子](https://forums.developer.apple.com/message/373108),顺手在`Feedback Assistant`提交了`bug report`,但好几天过去了没有任何回应(顺带给微软一个好评)。问题一目前已通过全局共享一个MediaStream连接来解决,原因在于Safari上MediaStream断开后就无法再次进行连接使用(表现为静音),改成了全局只连接一次就避免了此问题;全局处理也有利于屏蔽底层细节,start时无需再调用底层接口,提升兼容、可靠性。 *2019-10-26* 针对[#51](https://github.com/xiangyuecn/Recorder/issues/51)的问题研究后发现,如果录音时设备偶尔出现很卡的情况下(CPU被其他程序大量占用),浏览器采集到的音频是断断续续的,导致10秒的录音可能就只返回了5秒的数据量,这个时候最终编码得到的音频时长明显变短,播放时的效果就像快放一样。此问题能够稳定复现(使用别的程序大量占用CPU来模拟),目前已在`envIn`内部函数中进行了补偿处理,在浏览器两次传入PCM数据之间填充一段静默数据已弥补丢失的时长;最终编码得到的音频时长将和实际录音时长基本一致,消除了快放效果,但由于丢失的音频已被静默数据代替,听起来就是数据本身的断断续续的效果。在设备不卡时录音没有此问题。 *2019-11-03* lamejs原版编码器编码出来的mp3文件首尾存在填充数据并且会占据一定时长(这种数据播放时静默,记录的信息数据或者填充),同一录音mp3格式的时长会比wav格式的时长要长0-100ms左右,大部分情况下不会有影响,但如果涉及到实时转码并传输的话,这些数据将会造成多段mp3片段的总时长比实际录音要长,最终播放时会均匀的感觉到停顿,并且mp3片段越小越明显。本库已对lamejs编码出来的mp3文件进行了处理,去掉了头部的非音频数据,但由于编码出来的mp3每一帧数据都有固定时长,文件结尾最后一帧可能录音的时长不能刚好填满,就会产生填充数据;因此本库编码出来的mp3文件会比wav格式长0-30ms左右,多出来的时长在mp3的结尾处;mp3解码出来的pcm数据直接去掉结尾多出来的部分,就和wav中的pcm数据基本一致了;另外可以通过调节待编码的pcm数据长度以达到刚好填满最后一帧来规避此问题,参考`Recorder.SampleData`方法提供的连续转码针对此问题的处理。[参考wiki](https://github.com/xiangyuecn/Recorder/wiki/lamejs编码出来的mp3时长修正)。 +*2020-04-26* Safari Bug:据QQ群内`1048506792`、`190451148`开发者反馈研究发现,IOS ?-13.X Safari内打开录音后,如果切换到了其他标签、或其他App并且播放了任何声音,此时将会中断已打开的录音(系统级的?),切换回正在录音的页面,这个页面的录音功能将会彻底失效,并且刷新也无法恢复录音;表现为关闭录音后再次打开录音,能够正常获得权限,但浏览器返回的采集到的音频为静默的PCM,此时地址栏也并未显示出麦克风图标,刷新这个标签也也是一样不能正常获得录音,只有关掉此标签新打开页面才可正常录音。如果打开录音后关闭了录音,然后切换到其他标签或App播放声音,然后返回录音页面,不会出现此问题。此为Safari的底层Bug(也许是少给临时工工钱了吧,无能为力)。使用长按录音类似的用户交互可大幅度避免踩到这坨翔。 + diff --git a/assets/qq_group_421882406.png b/assets/qq_group_421882406.png new file mode 100644 index 0000000000000000000000000000000000000000..8311a98f001c6d171b8bb55994b9642212ca65a7 GIT binary patch literal 29984 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
+ + +
+ +
+
+ + +
+ + + + + + + + + + + + +
+ + +
+
+
+
+
+
+
+
+
+
+ + +
+
+ +
+
+