index.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { defineComponent, onMounted, onUnmounted, reactive } from "vue";
  2. import state, { getMusicDetail, handleSetSpeed, addNoteBBox, getNote, gotoNext } from "/src/state";
  3. import MusicScore from "../../view/music-score";
  4. import styles from "./index.module.less";
  5. import { getQuery } from "/src/utils/queryString";
  6. import { closeToast, showLoadingToast } from "vant";
  7. import store from "store";
  8. import { formateTimes } from "../../helpers/formateMusic";
  9. import { setCustomGradual, setCustomNoteRealValue } from "/src/helpers/customMusicScore"
  10. import { initSmoothAnimation, smoothAnimationState, destroySmoothAnimation, moveSmoothAnimationByPlayTime } from "../view-detail/smoothAnimation";
  11. import { api_playProgress } from "/src/helpers/communication";
  12. export default defineComponent({
  13. name: "simple-detail",
  14. setup() {
  15. const query: any = getQuery();
  16. const detailData = reactive({
  17. isLoading: true,
  18. currentTime: 0, // 当前播放的时间
  19. totalTime: 60000, // 音视频总时长
  20. });
  21. const communicateCb = (res: any) => {
  22. // 播放进度
  23. if (res?.data?.api === "playProgress") {
  24. if (res?.data.data) {
  25. state.playState = 'play';
  26. console.log(res.data)
  27. }
  28. }
  29. };
  30. // 监听评测曲谱音频播放进度,返回
  31. const progress = (res: any) => {
  32. detailData.currentTime = res?.currentTime || res?.content?.currentTime;
  33. detailData.totalTime = res?.totalDuration || res?.content?.totalDuration;
  34. const time = detailData.currentTime / 1000;
  35. if (res?.content?.totalDuration > 1000 && detailData.currentTime >= detailData.totalTime) {
  36. // 播放结束
  37. }
  38. };
  39. onMounted(async () => {
  40. const id = query.id || '';
  41. await getMusicDetail(id);
  42. detailData.isLoading = false;
  43. state.isSingleLine = true;
  44. state.isSimplePage = true;
  45. api_playProgress(progress);
  46. window.addEventListener("message", communicateCb);
  47. });
  48. onUnmounted(() => {
  49. state.isSimplePage = false;
  50. window.removeEventListener("message", communicateCb);
  51. });
  52. /** 渲染完成 */
  53. const handleRendered = async (osmd: any) => {
  54. console.log('渲染完成')
  55. state.osmd = osmd;
  56. // 没有设置速度使用读取的速度
  57. if (state.originSpeed === 0) {
  58. state.originSpeed = state.speed = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM || 100;
  59. }
  60. const saveSpeed = (store.get("speeds") || {})[state.examSongId] || state.speed || (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
  61. // 加载本地缓存的速度
  62. if (saveSpeed) {
  63. handleSetSpeed(saveSpeed);
  64. }
  65. setCustomGradual();
  66. setCustomNoteRealValue();
  67. state.times = formateTimes(osmd);
  68. console.log("🚀 ~ state.times:", state.times, state.subjectId, state);
  69. // 音符添加位置信息bbox
  70. addNoteBBox(state.times);
  71. // 一行谱创建 动画
  72. initSmoothAnimation();
  73. //destroySmoothAnimation();
  74. smoothAnimationState.isShow.value = false;
  75. state.playState = 'play';
  76. setStep();
  77. };
  78. /**
  79. * 播放一直触发的事件
  80. */
  81. const handlePlaying = () => {
  82. detailData.currentTime += 0.03;
  83. const currentTime = detailData.currentTime;
  84. const duration = detailData.totalTime;
  85. state.playProgress = (currentTime / duration) * 100;
  86. // console.log('👀~播放进度',currentTime)
  87. let item = getNote(currentTime);
  88. if (item) {
  89. gotoNext(item);
  90. }
  91. // 一行谱,需要滚动小节
  92. if (state.isSingleLine) {
  93. moveSmoothAnimationByPlayTime(currentTime)
  94. }
  95. };
  96. /** 在渲染前后计算光标应该走到的音符 */
  97. const setStep = () => {
  98. // console.log('播放状态',state.playState)
  99. if (state.playState !== "play") {
  100. console.log("暂停播放");
  101. return;
  102. }
  103. let startTime = Date.now();
  104. requestAnimationFrame(() => {
  105. const endTime = Date.now();
  106. // 渲染时间大于16.6,就会让页面卡顿, 如果渲染时间大与16.6就下一个渲染帧去计算
  107. if (endTime - startTime < 16.7) {
  108. handlePlaying();
  109. setStep();
  110. } else {
  111. setTimeout(() => {
  112. handlePlaying();
  113. setStep();
  114. }, 16.7);
  115. }
  116. });
  117. };
  118. return () => (
  119. <div class={styles.detail}>
  120. <div id="scrollContainer" class={[styles.container, "hideCursor"]}>
  121. {/* 曲谱渲染 */}
  122. {!detailData.isLoading &&
  123. <MusicScore
  124. onRendered={handleRendered}
  125. musicColor={'#FFFFFF'}
  126. />}
  127. </div>
  128. </div>
  129. );
  130. },
  131. });