wav.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. wav编码器+编码引擎
  3. https://github.com/xiangyuecn/Recorder
  4. 当然最佳推荐使用mp3、wav格式,代码也是优先照顾这两种格式
  5. 浏览器支持情况
  6. https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats
  7. 编码原理:给pcm数据加上一个44直接的wav头即成wav文件;pcm数据就是Recorder中的buffers原始数据(重新采样),16位时为LE小端模式(Little Endian),实质上是未经过任何编码处理
  8. */
  9. (function(){
  10. "use strict";
  11. Recorder.prototype.enc_wav={
  12. stable:true
  13. ,testmsg:"支持位数8位、16位(填在比特率里面),采样率取值无限制"
  14. };
  15. Recorder.prototype.wav=function(res,True,False){
  16. var This=this,set=This.set
  17. ,size=res.length
  18. ,sampleRate=set.sampleRate
  19. ,bitRate=set.bitRate==8?8:16;
  20. //编码数据 https://github.com/mattdiamond/Recorderjs https://www.cnblogs.com/blqw/p/3782420.html https://www.cnblogs.com/xiaoqi/p/6993912.html
  21. var dataLength=size*(bitRate/8);
  22. var buffer=new ArrayBuffer(44+dataLength);
  23. var data=new DataView(buffer);
  24. var offset=0;
  25. var writeString=function(str){
  26. for (var i=0;i<str.length;i++,offset++) {
  27. data.setUint8(offset,str.charCodeAt(i));
  28. };
  29. };
  30. var write16=function(v){
  31. data.setUint16(offset,v,true);
  32. offset+=2;
  33. };
  34. var write32=function(v){
  35. data.setUint32(offset,v,true);
  36. offset+=4;
  37. };
  38. /* RIFF identifier */
  39. writeString('RIFF');
  40. /* RIFF chunk length */
  41. write32(36+dataLength);
  42. /* RIFF type */
  43. writeString('WAVE');
  44. /* format chunk identifier */
  45. writeString('fmt ');
  46. /* format chunk length */
  47. write32(16);
  48. /* sample format (raw) */
  49. write16(1);
  50. /* channel count */
  51. write16(1);
  52. /* sample rate */
  53. write32(sampleRate);
  54. /* byte rate (sample rate * block align) */
  55. write32(sampleRate*(bitRate/8));// *1 声道
  56. /* block align (channel count * bytes per sample) */
  57. write16(bitRate/8);// *1 声道
  58. /* bits per sample */
  59. write16(bitRate);
  60. /* data chunk identifier */
  61. writeString('data');
  62. /* data chunk length */
  63. write32(dataLength);
  64. // 写入采样数据
  65. if(bitRate==8) {
  66. for(var i=0;i<size;i++,offset++) {
  67. //16转8据说是雷霄骅的 https://blog.csdn.net/sevennight1989/article/details/85376149 细节比blqw的按比例的算法清晰点,虽然都有明显杂音
  68. var val=(res[i]>>8)+128;
  69. data.setInt8(offset,val,true);
  70. };
  71. }else{
  72. for (var i=0;i<size;i++,offset+=2){
  73. data.setInt16(offset,res[i],true);
  74. };
  75. };
  76. True(new Blob([data.buffer],{type:"audio/wav"}));
  77. }
  78. })();