AudioRenderer.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. /* RIFF identifier */
  62. this.writeString(viewTalk, 0, 'RIFF');
  63. /* file length */
  64. viewTalk.setUint32(4, 32 + dataLen * 2, true);
  65. /* RIFF type */
  66. this.writeString(viewTalk, 8, 'WAVE');
  67. /* format chunk identifier */
  68. this.writeString(viewTalk, 12, 'fmt ');
  69. /* format chunk length */
  70. viewTalk.setUint32(16, 16, true);
  71. /* sample format (raw) */
  72. viewTalk.setUint16(20, 1, true);
  73. /* channel count */
  74. viewTalk.setUint16(22, channels, true);
  75. /* sample rate */
  76. viewTalk.setUint32(24, sampleRates, true);
  77. /* byte rate (sample rate * block align) */
  78. viewTalk.setUint32(28, sampleRates * 2, true);
  79. /* block align (channel count * bytes per sample)/8 */
  80. viewTalk.setUint16(32, channels * bitsPerSample / 8, true);
  81. /* bits per sample */
  82. viewTalk.setUint16(34, bitsPerSample, true);
  83. /* data chunk identifier */
  84. this.writeString(viewTalk, 36, 'data');
  85. /* data chunk length */
  86. viewTalk.setUint32(40, dataLen, true);
  87. this.setBufferToDataview(viewTalk, 44, dataBuf);
  88. var self = this;
  89. this.oAudioContext.decodeAudioData(viewTalk.buffer, function (buffer) {
  90. var bufferSource = self.oAudioContext.createBufferSource();
  91. if (bufferSource == null) {
  92. return -1;
  93. }
  94. bufferSource.buffer = buffer;
  95. bufferSource.start(0);
  96. if (self.gainNode == null || self.bSetVolume) {
  97. self.gainNode = self.oAudioContext.createGain();
  98. // self.gainNode.gain.value = self.currentVolume;
  99. // // self.currentVolume = self.gainNode.gain.value;
  100. // self.gainNode.connect(self.oAudioContext.destination);
  101. self.bSetVolume = false;
  102. }
  103. self.gainNode.gain.value = self.currentVolume;
  104. // self.currentVolume = self.gainNode.gain.value;
  105. self.gainNode.connect(self.oAudioContext.destination);
  106. bufferSource.connect(self.gainNode);
  107. }, function (e) {
  108. console.log("decode error");
  109. return -1;
  110. });
  111. return 0;
  112. }
  113. /**
  114. * @synopsis 停止播放
  115. *
  116. * @returns 返回音量
  117. */
  118. }, {
  119. key: 'Stop',
  120. value: function Stop() {
  121. if (this.gainNode != null) {
  122. this.gainNode.disconnect();
  123. this.gainNode = null;
  124. }
  125. // this.oAudioContext.close();
  126. // AudioRenderer.unique = undefined;
  127. // __instance() = null;
  128. return true;
  129. }
  130. /**
  131. * @synopsis 设置音量
  132. *
  133. * @param iVolume [IN] 音量
  134. *
  135. * @returns 状态码
  136. */
  137. }, {
  138. key: 'SetVolume',
  139. value: function SetVolume(iVolume) {
  140. this.bSetVolume = true;
  141. this.currentVolume = iVolume;
  142. // 储存当前窗口设置音量值
  143. this.mVolumes.set(this.iWndNum, iVolume);
  144. return true;
  145. }
  146. /**
  147. * @synopsis 设置窗口号
  148. *
  149. * @param iWndNum [IN] 窗口号
  150. *
  151. * @returns 状态码
  152. */
  153. }, {
  154. key: 'SetWndNum',
  155. value: function SetWndNum(iWndNum) {
  156. this.iWndNum = iWndNum;
  157. // 获取当前窗口设置音量值
  158. var iVolume = this.mVolumes.get(iWndNum);
  159. if (iVolume == undefined) {
  160. iVolume = 0.8; // 默认音量
  161. }
  162. this.currentVolume = iVolume;
  163. return true;
  164. }
  165. /**
  166. * @synopsis 获取音量
  167. *
  168. * @returns 返回音量
  169. */
  170. }, {
  171. key: 'GetVolume',
  172. value: function GetVolume() {
  173. // 获取当前窗口设置音量值
  174. var iVolume = this.mVolumes.get(this.iWndNum);
  175. if (iVolume == undefined) {
  176. iVolume = 0.8; // 默认音量
  177. }
  178. return iVolume;
  179. }
  180. }]);
  181. return AudioRenderer;
  182. }();
  183. //# sourceMappingURL=AudioRenderer.js.map