sounds.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import config from "@/config";
  2. import { IsWechat } from "./platform";
  3. Howler._unlockAudio();
  4. // Howl.prototype.setSRC = function(newSrc) {
  5. // var self = this;
  6. // self.stop();
  7. // self._src = newSrc;
  8. // self._sprite = {};
  9. // self._duration = 0;
  10. // if (self._sounds[0] && self._sounds[0]._node) {
  11. // self._sounds[0]._node.src = newSrc;
  12. // }
  13. // self.load();
  14. // }
  15. let isReady = false;
  16. export const checkReadyToPlay = function(resolve, isTouchToPlay) {
  17. if (isReady === true) {
  18. return resolve();
  19. }
  20. try {
  21. function ready() {
  22. if (typeof parent.WeixinJSBridge !== "undefined") {
  23. console.log("wx play");
  24. parent.WeixinJSBridge.invoke(
  25. "getNetworkType",
  26. {},
  27. function(e) {
  28. resolve((isReady = true));
  29. },
  30. false
  31. );
  32. } else if (isTouchToPlay) {
  33. resolve((isReady = true));
  34. document.querySelector("body").removeEventListener("touchend", ready);
  35. document.querySelector("#player") && document.querySelector("#player").removeEventListener("touchend", ready);
  36. }
  37. }
  38. if (config.isMobile) {
  39. if (IsWechat) {
  40. if (typeof parent.WeixinJSBridge !== "undefined") {
  41. ready();
  42. } else {
  43. parent.document.addEventListener("WeixinJSBridgeReady", ready);
  44. }
  45. } else if (isTouchToPlay) {
  46. document.querySelector("body").addEventListener("touchend", ready);
  47. document.querySelector("#player") && document.querySelector("#player").addEventListener("touchend", ready);
  48. ready();
  49. }
  50. } else {
  51. resolve((isReady = true));
  52. }
  53. } catch (error) {
  54. resolve((isReady = true));
  55. }
  56. };
  57. class SoundPlayer extends EventEmitter {
  58. constructor(options = {}) {
  59. super();
  60. this._pause_byother = false;
  61. this._disable = false;
  62. this._canplay = false;
  63. this._options = options;
  64. // this._sound = new Howl({
  65. // src: [''],
  66. // loop: options.loop ? true : false,
  67. // html5: options.html5 ? true : false,
  68. // format: ['mp3', 'webm'],
  69. // })
  70. // this._sound.on('play', () => this.emit('play'))
  71. // this._sound.on('end', () => this.emit('end') && this.emit('off'))
  72. // this._sound.on('pause', () => this.emit('pause') && this.emit('off'))
  73. // this._sound.on('stop', () => this.emit('stop') && this.emit('off'))
  74. // this._sound.on('loaderror', err => this.emit('error', err))
  75. // if (!options.html5) {
  76. // this._sound.on('load', () => {
  77. // this.emit('loaded', this._sound.duration())
  78. // })
  79. // }
  80. }
  81. init(src) {
  82. this.remove();
  83. this._canplay = true;
  84. this._sound = new Howl({
  85. src: [src],
  86. loop: this._options.loop ? true : false,
  87. html5: this._options.html5 ? true : false,
  88. //preload : this._options.html5 ? true : false,
  89. format: ["mp3", "webm"],
  90. });
  91. this._sound.on("play", () => this.emit("play"));
  92. this._sound.on("end", () => this.emit("end") && this.emit("off"));
  93. this._sound.on("pause", () => this.emit("pause") && this.emit("off"));
  94. this._sound.on("stop", () => this.emit("stop") && this.emit("off"));
  95. this._sound.on("loaderror", (err) => this.emit("error", err));
  96. this._sound.once("load", () => {
  97. this.emit("loaded", this._sound.duration());
  98. });
  99. }
  100. /**
  101. * 设置播放源
  102. * @param {String} src 音频地址
  103. * @param {Boolean} isAutoplay 是否自动播放,default:true
  104. */
  105. setSRC(src) {
  106. //this._sound.setSRC(src)
  107. //this._pause_byother = false
  108. if (src) {
  109. this.init(src);
  110. } else {
  111. this.remove();
  112. //this.emit('stop') && this.emit('off')
  113. }
  114. }
  115. /**
  116. * 设置是否循环
  117. * @param {Boolean} isLoop
  118. */
  119. setLoop(isLoop) {
  120. if (!this._canplay) {
  121. return;
  122. }
  123. this._sound.loop(isLoop);
  124. }
  125. /**
  126. * 播放
  127. */
  128. play() {
  129. setTimeout(() => {
  130. if (this._disable || !this._canplay || this._sound.playing()) {
  131. return;
  132. }
  133. this._sound.play();
  134. this._pause_byother = false;
  135. }, 10);
  136. }
  137. /**
  138. * 停止
  139. */
  140. stop() {
  141. if (!this._canplay) {
  142. return;
  143. }
  144. if (!this._sound.playing()) {
  145. return;
  146. }
  147. this._sound.stop();
  148. }
  149. /**
  150. * 暂停
  151. * @param {Boolean} isByOther 是否由其他播放源导致的暂停,default:false
  152. */
  153. pause(isByOther = false) {
  154. if (!this._canplay) {
  155. return;
  156. }
  157. if (this._sound.playing()) {
  158. this._sound.pause();
  159. this._pause_byother = isByOther;
  160. }
  161. }
  162. /**
  163. * 强制标记为其他播放源引起的暂停行为
  164. */
  165. pauseByOther() {
  166. if (this._canplay) {
  167. this._pause_byother = true;
  168. }
  169. }
  170. time(time) {
  171. if (!this._canplay) {
  172. return;
  173. }
  174. this._sound.seek(time);
  175. }
  176. /**
  177. * 设置静音
  178. */
  179. mute(muted) {
  180. if (!this._canplay) {
  181. return;
  182. }
  183. this._sound.mute(muted);
  184. }
  185. /**
  186. * 继续播放(如果pause方法中的isByOther为true,则可以继续播放,否则无效)
  187. */
  188. resume() {
  189. if (!this._canplay) {
  190. return;
  191. }
  192. if (this._pause_byother) {
  193. this.play();
  194. }
  195. }
  196. remove() {
  197. this._canplay = false;
  198. this._pause_byother = false;
  199. if (this._sound) {
  200. this._sound.stop();
  201. this._sound.unload();
  202. }
  203. }
  204. /**
  205. * 禁用
  206. */
  207. disabel() {
  208. this._disable = true;
  209. }
  210. /**
  211. * 启用
  212. */
  213. enable() {
  214. this._disable = false;
  215. }
  216. /**
  217. * 是否正在播放
  218. */
  219. get isPlaying() {
  220. if (!this._canplay) {
  221. return false;
  222. }
  223. return this._sound.playing();
  224. }
  225. }
  226. /**
  227. * 背景音乐播放器
  228. */
  229. export const backgroundMusicPlayer = new SoundPlayer({ html5: false, loop: true });
  230. /**
  231. * 自动导览录音播放器
  232. */
  233. export const guideSoundPlayer = new SoundPlayer({ html5: false });
  234. /**
  235. * 热点音频播放器
  236. */
  237. export const hotspotSoundPlayer = new SoundPlayer({ html5: true, loop: true });