sound.js 8.3 KB

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