sound.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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. paused() {
  103. console.log('hard-paused')
  104. this.sound && this.sound.pause()
  105. this.isPlay = false
  106. }
  107. stop() {
  108. this.sound.stop()
  109. }
  110. resume() {
  111. if (this.pauseFromOther) {
  112. this.pauseFromOther = false
  113. if (!this.isPlay) {
  114. this.play()
  115. }
  116. }
  117. }
  118. source(src, options = {}) {
  119. this._init(src, options)
  120. }
  121. }
  122. class MusicPlayer extends AudioPlayer {
  123. constructor() {
  124. super('music')
  125. const store = useStore()
  126. const ready = () => {
  127. if (typeof parent.WeixinJSBridge !== 'undefined') {
  128. parent.WeixinJSBridge.invoke(
  129. 'getNetworkType',
  130. {},
  131. e => {
  132. try {
  133. if (!player.pauseFromOther) {
  134. this.play()
  135. }
  136. } catch (error) { }
  137. },
  138. false
  139. )
  140. }
  141. }
  142. this.isLock = true
  143. this.watchPlay = (autoplay = null) => {
  144. if (this.isLock) {
  145. return
  146. }
  147. this._remove()
  148. const source = computed(() => {
  149. let music = store.getters['fdkk/fdkkBGM'] || store.getters['scene/musicURL']
  150. console.log(music, 'musicmusicmusic');
  151. if (music) {
  152. return {
  153. src: music,
  154. loop: true,
  155. }
  156. }
  157. return null
  158. })
  159. if (source.value && source.value.src) {
  160. this._create(source.value.src, {
  161. loop: source.value.loop,
  162. html5: false,
  163. })
  164. .then(() => {
  165. // if (browser.detectWeixin()) {
  166. // if (typeof parent.WeixinJSBridge !== 'undefined') {
  167. // ready()
  168. // } else {
  169. // parent.document.addEventListener('WeixinJSBridgeReady', ready)
  170. // }
  171. // } else {
  172. if (autoplay) {
  173. setTimeout(() => {
  174. this.play()
  175. }, 50);
  176. }
  177. else {
  178. retryPlay(this)
  179. }
  180. // ready()
  181. // }
  182. })
  183. .catch(err => {
  184. console.error('err', err)
  185. })
  186. } else {
  187. setTimeout(() => {
  188. this._remove()
  189. }, 50)
  190. }
  191. }
  192. watchEffect(() => this.watchPlay())
  193. }
  194. }
  195. class SoundPlayer extends AudioPlayer {
  196. constructor() {
  197. super('sound')
  198. const store = useStore()
  199. const source = computed(() => {
  200. return store.getters['functions/commentary']
  201. })
  202. const ready = () => {
  203. if (typeof parent.WeixinJSBridge !== 'undefined') {
  204. parent.WeixinJSBridge.invoke(
  205. 'getNetworkType',
  206. {},
  207. e => {
  208. this.play()
  209. },
  210. false
  211. )
  212. }
  213. }
  214. this.isLock = true
  215. this.watchPlay = () => {
  216. if (this.isLock) {
  217. return
  218. }
  219. if (source.value && source.value.src) {
  220. this._create(source.value.src, {
  221. loop: source.value.loop,
  222. html5: false,
  223. })
  224. .then(() => {
  225. if (source.value.openByDefault) {
  226. this.play()
  227. }
  228. })
  229. .catch(err => {
  230. console.error('err', err)
  231. })
  232. } else {
  233. setTimeout(() => {
  234. this._remove()
  235. }, 50)
  236. }
  237. }
  238. // watchEffect(() => this.watchPlay())
  239. }
  240. }
  241. export function useMusicPlayer() {
  242. if (useMusicPlayer.player === void 0) {
  243. useMusicPlayer.player = new MusicPlayer()
  244. useApp().then(app => {
  245. useMusicPlayer.player.isLock = false
  246. useMusicPlayer.player.watchPlay()
  247. })
  248. }
  249. return useMusicPlayer.player
  250. }
  251. export function useSoundPlayer() {
  252. if (useSoundPlayer.player === void 0) {
  253. useSoundPlayer.player = new SoundPlayer()
  254. }
  255. return useSoundPlayer.player
  256. }
  257. function wxConfig() {
  258. wx.config({
  259. // 配置信息, 即使不正确也能使用 wx.ready
  260. debug: false,
  261. appId: '',
  262. timestamp: 1,
  263. nonceStr: '',
  264. signature: '',
  265. jsApiList: [],
  266. })
  267. }