sound.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. import { computed, watchEffect } from 'vue'
  2. import { useStore } from 'vuex'
  3. import { useApp } from '@/app'
  4. import browser from './browser'
  5. import QJKanKan from '@/sdk/QJKanKan'
  6. let CLICKFIRST = false
  7. // const sounds$ = document.createElement('div')
  8. // sounds$.className = 'audios'
  9. // sounds$.style.display = 'none'
  10. // sounds$.style.position = 'absolute'
  11. // sounds$.style.zIndex = -1
  12. // document.body.appendChild(sounds$)
  13. const retryPlay = player => {
  14. function onclick() {
  15. $player.removeEventListener('click', onclick)
  16. $player.removeEventListener('touchstart', onclick)
  17. //判断是否第一次进入或者是否已点击过
  18. if (player.pauseFromOther||CLICKFIRST) {
  19. return
  20. }
  21. CLICKFIRST = true
  22. player.sound.play()
  23. }
  24. const $player = document.querySelector('.ui-view-layout')
  25. $player.addEventListener('click', onclick)
  26. $player.addEventListener('touchstart', onclick)
  27. }
  28. class AudioPlayer extends QJKanKan.MITT.Emiter {
  29. constructor(name) {
  30. super()
  31. this.isPlay = false
  32. this.isPause = false
  33. this.pauseFromOther = false
  34. this._create = (src, options = {}) => {
  35. return new Promise((resolve, reject) => {
  36. this._remove()
  37. setTimeout(() => {
  38. this.sound = new Howl({
  39. preload: true,
  40. src: [src],
  41. loop: options.loop || false,
  42. html5: options.html5 || false,
  43. onloaderror(id, err) {
  44. if (!options.html5) {
  45. reject(err)
  46. }
  47. },
  48. onplayerror: function (err) {
  49. if (!options.html5) {
  50. reject(err)
  51. }
  52. },
  53. onload() {
  54. if (!options.html5) {
  55. resolve()
  56. }
  57. },
  58. onplay: () => {
  59. this.isPlay = true
  60. this.isPause = false
  61. this.emit('play')
  62. },
  63. onpause: () => {
  64. this.isPause = true
  65. this.isPlay = false
  66. this.emit('pause')
  67. },
  68. onend: () => {
  69. this.isPause = false
  70. this.isPlay = false
  71. this.emit('pause')
  72. },
  73. })
  74. if (options.html5) {
  75. resolve()
  76. }
  77. }, 50)
  78. })
  79. }
  80. this._remove = () => {
  81. if (this.sound) {
  82. if (this.isPlay) {
  83. this.sound.stop()
  84. }
  85. this.sound.unload()
  86. this.sound = null
  87. }
  88. }
  89. }
  90. play() {
  91. this.sound.play()
  92. }
  93. pause(fromOther) {
  94. if (!this.isPlay) {
  95. return
  96. }
  97. this.sound.pause()
  98. if (fromOther) {
  99. this.pauseFromOther = true
  100. }
  101. }
  102. stop() {
  103. this.sound.stop()
  104. }
  105. resume() {
  106. if (this.pauseFromOther) {
  107. this.pauseFromOther = false
  108. if (!this.isPlay) {
  109. this.play()
  110. }
  111. }
  112. }
  113. source(src, options = {}) {
  114. this._init(src, options)
  115. }
  116. }
  117. class MusicPlayer extends AudioPlayer {
  118. constructor() {
  119. super('music')
  120. const store = useStore()
  121. const ready = () => {
  122. if (typeof parent.WeixinJSBridge !== 'undefined') {
  123. parent.WeixinJSBridge.invoke(
  124. 'getNetworkType',
  125. {},
  126. e => {
  127. try {
  128. if (!player.pauseFromOther) {
  129. this.play()
  130. }
  131. } catch (error) {}
  132. },
  133. false
  134. )
  135. }
  136. }
  137. this.isLock = true
  138. this.watchPlay = (autoplay = null) => {
  139. if (this.isLock) {
  140. return
  141. }
  142. this._remove()
  143. const source = computed(() => {
  144. let music = store.getters['fdkk/fdkkBGM'] || store.getters['scene/musicURL']
  145. console.log(music, 'musicmusicmusic');
  146. if (music) {
  147. return {
  148. src: music,
  149. loop: true,
  150. }
  151. }
  152. return null
  153. })
  154. if (source.value && source.value.src) {
  155. this._create(source.value.src, {
  156. loop: source.value.loop,
  157. html5: false,
  158. })
  159. .then(() => {
  160. // if (browser.detectWeixin()) {
  161. // if (typeof parent.WeixinJSBridge !== 'undefined') {
  162. // ready()
  163. // } else {
  164. // parent.document.addEventListener('WeixinJSBridgeReady', ready)
  165. // }
  166. // } else {
  167. if (autoplay) {
  168. setTimeout(() => {
  169. this.play()
  170. }, 50);
  171. }
  172. else {
  173. retryPlay(this)
  174. }
  175. // ready()
  176. // }
  177. })
  178. .catch(err => {
  179. console.error('err', err)
  180. })
  181. } else {
  182. setTimeout(() => {
  183. this._remove()
  184. }, 50)
  185. }
  186. }
  187. watchEffect(() => this.watchPlay())
  188. }
  189. }
  190. class SoundPlayer extends AudioPlayer {
  191. constructor() {
  192. super('sound')
  193. const store = useStore()
  194. const source = computed(() => {
  195. return store.getters['functions/commentary']
  196. })
  197. const ready = () => {
  198. if (typeof parent.WeixinJSBridge !== 'undefined') {
  199. parent.WeixinJSBridge.invoke(
  200. 'getNetworkType',
  201. {},
  202. e => {
  203. this.play()
  204. },
  205. false
  206. )
  207. }
  208. }
  209. this.isLock = true
  210. this.watchPlay = () => {
  211. if (this.isLock) {
  212. return
  213. }
  214. if (source.value && source.value.src) {
  215. this._create(source.value.src, {
  216. loop: source.value.loop,
  217. html5: false,
  218. })
  219. .then(() => {
  220. if (source.value.openByDefault) {
  221. this.play()
  222. }
  223. })
  224. .catch(err => {
  225. console.error('err', err)
  226. })
  227. } else {
  228. setTimeout(() => {
  229. this._remove()
  230. }, 50)
  231. }
  232. }
  233. // watchEffect(() => this.watchPlay())
  234. }
  235. }
  236. export function useMusicPlayer() {
  237. if (useMusicPlayer.player === void 0) {
  238. useMusicPlayer.player = new MusicPlayer()
  239. useApp().then(app => {
  240. useMusicPlayer.player.isLock = false
  241. useMusicPlayer.player.watchPlay()
  242. })
  243. }
  244. return useMusicPlayer.player
  245. }
  246. export function useSoundPlayer() {
  247. if (useSoundPlayer.player === void 0) {
  248. useSoundPlayer.player = new SoundPlayer()
  249. }
  250. return useSoundPlayer.player
  251. }
  252. function wxConfig() {
  253. wx.config({
  254. // 配置信息, 即使不正确也能使用 wx.ready
  255. debug: false,
  256. appId: '',
  257. timestamp: 1,
  258. nonceStr: '',
  259. signature: '',
  260. jsApiList: [],
  261. })
  262. }