AudioRenderer.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /**
  2. * Created by wangweijie5 on 2016/12/16.
  3. */
  4. "use strict";
  5. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  6. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7. var __instance = function () {
  8. var instance = void 0;
  9. return function (newInstance) {
  10. if (newInstance) instance = newInstance;
  11. return instance;
  12. };
  13. }();
  14. var AudioRenderer = function () {
  15. function AudioRenderer() {
  16. _classCallCheck(this, AudioRenderer);
  17. if (__instance()) return __instance();
  18. // 确保只有单例
  19. if (AudioRenderer.unique !== undefined) {
  20. return AudioRenderer.unique;
  21. }
  22. AudioRenderer.unique = this;
  23. this.oAudioContext = null;
  24. this.currentVolume = 0.8; // 初始音量
  25. this.bSetVolume = false;
  26. this.gainNode = null;
  27. this.iWndNum = -1; // 窗口号
  28. this.mVolumes = new Map(); // 用于存储所有音量
  29. // Init AudioContext
  30. var AudioContext = window.AudioContext || window.webkitAudioContext;
  31. this.oAudioContext = new AudioContext();
  32. this.writeString = function (view, offset, string) {
  33. for (var i = 0; i < string.length; i++) {
  34. view.setUint8(offset + i, string.charCodeAt(i));
  35. }
  36. };
  37. this.setBufferToDataview = function (output, offset, input) {
  38. for (var i = 0; i < input.length; i++, offset++) {
  39. output.setUint8(offset, input[i]);
  40. }
  41. };
  42. __instance(this);
  43. }
  44. /**
  45. * @synopsis 音频播放
  46. *
  47. * @param dataBuf [IN] 音频缓存
  48. * @param dataLen [IN] 缓存长度
  49. * @param audioInfo [IN] 音频参数
  50. *
  51. * @returns 状态码
  52. */
  53. _createClass(AudioRenderer, [{
  54. key: 'Play',
  55. value: function Play(dataBuf, dataLen, audioInfo) {
  56. var bufferData = new ArrayBuffer(44 + dataLen);
  57. var viewTalk = new DataView(bufferData);
  58. var sampleRates = audioInfo.samplesPerSec;
  59. var channels = audioInfo.channels;
  60. var bitsPerSample = audioInfo.bitsPerSample;
  61. //console.log("audiorender sampleRates"+sampleRates+"channels:"+channels+"bitsPerSample:"+bitsPerSample);
  62. /* RIFF identifier */
  63. this.writeString(viewTalk, 0, 'RIFF');
  64. /* file length */
  65. viewTalk.setUint32(4, 32 + dataLen * 2, true);
  66. /* RIFF type */
  67. this.writeString(viewTalk, 8, 'WAVE');
  68. /* format chunk identifier */
  69. this.writeString(viewTalk, 12, 'fmt ');
  70. /* format chunk length */
  71. viewTalk.setUint32(16, 16, true);
  72. /* sample format (raw) */
  73. viewTalk.setUint16(20, 1, true);
  74. /* channel count */
  75. viewTalk.setUint16(22, channels, true);
  76. /* sample rate */
  77. viewTalk.setUint32(24, sampleRates, true);
  78. /* byte rate (sample rate * block align) */
  79. viewTalk.setUint32(28, sampleRates * 2, true);
  80. /* block align (channel count * bytes per sample)/8 */
  81. viewTalk.setUint16(32, channels * bitsPerSample / 8, true);
  82. /* bits per sample */
  83. viewTalk.setUint16(34, bitsPerSample, true);
  84. /* data chunk identifier */
  85. this.writeString(viewTalk, 36, 'data');
  86. /* data chunk length */
  87. viewTalk.setUint32(40, dataLen, true);
  88. this.setBufferToDataview(viewTalk, 44, dataBuf);
  89. var self = this;
  90. this.oAudioContext.decodeAudioData(viewTalk.buffer, function (buffer) {
  91. var bufferSource = self.oAudioContext.createBufferSource();
  92. if (bufferSource == null) {
  93. return -1;
  94. }
  95. bufferSource.buffer = buffer;
  96. bufferSource.start(0);
  97. if (self.gainNode == null || self.bSetVolume) {
  98. self.gainNode = self.oAudioContext.createGain();
  99. // self.gainNode.gain.value = self.currentVolume;
  100. // // self.currentVolume = self.gainNode.gain.value;
  101. // self.gainNode.connect(self.oAudioContext.destination);
  102. self.bSetVolume = false;
  103. }
  104. self.gainNode.gain.value = self.currentVolume;
  105. // self.currentVolume = self.gainNode.gain.value;
  106. self.gainNode.connect(self.oAudioContext.destination);
  107. bufferSource.connect(self.gainNode);
  108. }, function (e) {
  109. console.log("decode error");
  110. return -1;
  111. });
  112. return 0;
  113. }
  114. /**
  115. * @synopsis 停止播放
  116. *
  117. * @returns 返回音量
  118. */
  119. }, {
  120. key: 'Stop',
  121. value: function Stop() {
  122. if (this.gainNode != null) {
  123. this.gainNode.disconnect();
  124. this.gainNode = null;
  125. }
  126. // this.oAudioContext.close();
  127. // AudioRenderer.unique = undefined;
  128. // __instance() = null;
  129. return true;
  130. }
  131. /**
  132. * @synopsis 设置音量
  133. *
  134. * @param iVolume [IN] 音量
  135. *
  136. * @returns 状态码
  137. */
  138. }, {
  139. key: 'SetVolume',
  140. value: function SetVolume(iVolume) {
  141. this.bSetVolume = true;
  142. this.currentVolume = iVolume;
  143. // 储存当前窗口设置音量值
  144. this.mVolumes.set(this.iWndNum, iVolume);
  145. return true;
  146. }
  147. /**
  148. * @synopsis 设置窗口号
  149. *
  150. * @param iWndNum [IN] 窗口号
  151. *
  152. * @returns 状态码
  153. */
  154. }, {
  155. key: 'SetWndNum',
  156. value: function SetWndNum(iWndNum) {
  157. this.iWndNum = iWndNum;
  158. // 获取当前窗口设置音量值
  159. var iVolume = this.mVolumes.get(iWndNum);
  160. if (iVolume == undefined) {
  161. iVolume = 0.8; // 默认音量
  162. }
  163. this.currentVolume = iVolume;
  164. return true;
  165. }
  166. /**
  167. * @synopsis 获取音量
  168. *
  169. * @returns 返回音量
  170. */
  171. }, {
  172. key: 'GetVolume',
  173. value: function GetVolume() {
  174. // 获取当前窗口设置音量值
  175. var iVolume = this.mVolumes.get(this.iWndNum);
  176. if (iVolume == undefined) {
  177. iVolume = 0.8; // 默认音量
  178. }
  179. return iVolume;
  180. }
  181. }]);
  182. return AudioRenderer;
  183. }();
  184. //# sourceMappingURL=AudioRenderer.js.map