useAudio.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import {
  2. nextTick,
  3. ref,
  4. onUnmounted
  5. } from "vue";
  6. import {
  7. debounce
  8. } from "@/utils/common";
  9. export function useAudio() {
  10. const innerAudioContext = ref(null);
  11. const options = ref(null);
  12. function createAudio(audioUrl) {
  13. const innerAudioContext = uni.createInnerAudioContext();
  14. innerAudioContext.autoplay = false;
  15. innerAudioContext.src = audioUrl;
  16. innerAudioContext.onPlay(() => {
  17. // 播放
  18. uni.$emit('yy-audio-playing', options);
  19. });
  20. innerAudioContext.onError((res) => {
  21. uni.$emit('yy-audio-error')
  22. });
  23. innerAudioContext.onEnded(() => {
  24. // 播放结束
  25. uni.$emit('yy-audio-end', options)
  26. })
  27. return innerAudioContext;
  28. }
  29. function changeSource(url) {
  30. innerAudioContext.src = url;
  31. innerAudioContext.currentTime = 0;
  32. }
  33. const debuncePlay = debounce((myOption) => {
  34. innerAudioContext.value = createAudio(myOption.url);
  35. innerAudioContext.value.play()
  36. }, 50)
  37. function handlePlay(data) {
  38. if (innerAudioContext.value) {
  39. innerAudioContext.value.pause();
  40. innerAudioContext.value.destroy();
  41. innerAudioContext.value = null;
  42. uni.$emit('destory-stop')
  43. }
  44. options.value = data;
  45. debuncePlay(data);
  46. }
  47. function handleStop() {
  48. if (innerAudioContext.value) {
  49. innerAudioContext.value.pause();
  50. innerAudioContext.value.destroy();
  51. innerAudioContext.value = null;
  52. uni.$emit('destory-stop')
  53. }
  54. }
  55. function doBackOutpage() {
  56. handleStop();
  57. }
  58. function doRepeatPlayToStop() {
  59. handleStop();
  60. }
  61. function doSwiperChange() {
  62. handleStop();
  63. }
  64. function doQuestionJiexiClose() {
  65. handleStop();
  66. }
  67. function doUnitestSubmit() {
  68. handleStop();
  69. }
  70. // 离开当前页面 停止播放
  71. uni.$on('back-outpage', doBackOutpage)
  72. // 播放过程中点击同一个视频触发终止
  73. uni.$on('repeat-play-to-stop', doRepeatPlayToStop)
  74. // 试题切换停止播放
  75. uni.$on('swiper-change', doSwiperChange)
  76. // 解析关闭 停止播放
  77. uni.$on('question-jiexi-close', doQuestionJiexiClose)
  78. // 交卷 停止播放
  79. uni.$on('unitTest-submit', doUnitestSubmit)
  80. onUnmounted(() => {
  81. uni.$off('back-outpage', doBackOutpage)
  82. uni.$off('repeat-play-to-stop', doRepeatPlayToStop)
  83. // 试题切换停止播放
  84. uni.$off('swiper-change', doSwiperChange)
  85. // 解析关闭 停止播放
  86. uni.$off('question-jiexi-close', doQuestionJiexiClose)
  87. // 交卷 停止播放
  88. uni.$off('unitTest-submit', doUnitestSubmit)
  89. })
  90. return {
  91. options,
  92. handlePlay,
  93. handleStop,
  94. innerAudioContext
  95. }
  96. }
  97. export class UseAudio {
  98. instance = null;
  99. options = null;
  100. doPlay = debounce((data) => {
  101. if (this.options) {
  102. if(this.options.stId == data.stId && this.options.index == data.index) {
  103. // console.log('同一个音频播放应该暂停')
  104. uni.$emit('reset-playing-status', this.options)
  105. this.innerAudioContext.pause();
  106. this.destory();
  107. this.init();
  108. return;
  109. }
  110. // 切换不同音频
  111. if(this.options.stId !== data.stId || this.options.index != data.index) {
  112. // console.log('切换不同音频')
  113. uni.$emit('reset-playing-status', this.options)
  114. }
  115. }
  116. this.options = data;
  117. this.innerAudioContext.src = data.url;
  118. this.innerAudioContext.play();
  119. },50)
  120. constructor() {
  121. this.init();
  122. }
  123. init() {
  124. this.innerAudioContext = uni.createInnerAudioContext();
  125. this.innerAudioContext.autoplay = false;
  126. this.innerAudioContext.onPlay(() => {
  127. uni.$emit("yy-audio-playing", this.options);
  128. });
  129. this.innerAudioContext.onError(() => {
  130. uni.$emit("yy-audio-error", this.options);
  131. });
  132. this.innerAudioContext.onEnded(() => {
  133. uni.$emit("yy-audio-end", this.options);
  134. });
  135. }
  136. static create() {
  137. if (this.instance) {
  138. return this;
  139. }
  140. this.instance = new UseAudio()
  141. return this;
  142. }
  143. play(data) {
  144. this.doPlay(data);
  145. }
  146. pause() {
  147. this.innerAudioContext.pause();
  148. }
  149. stop() {
  150. this.innerAudioContext.stop();
  151. }
  152. destory() {
  153. this.innerAudioContext.destroy();
  154. this.innerAudioContext = null;
  155. this.options = null;
  156. }
  157. }