浏览代码

音源切换时候times时值切换,没有音源时候的按钮逻辑和缺省页

黄琪勇 1 年之前
父节点
当前提交
1dde35c7d5

+ 11 - 4
src/helpers/formateMusic.ts

@@ -1,7 +1,6 @@
 import dayjs from "dayjs";
 import duration from "dayjs/plugin/duration";
 import state, { customData } from "/src/state";
-import { metronomeData as metronomeDataState } from "./metronome"
 import { browser } from "../utils/index";
 import {
 	isSpecialMark,
@@ -774,6 +773,8 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 	let multipleRestMeasures = 0;
 	let staveNoteIndex = 0;
 	let staveIndex = 0;
+	let xmlNoteTime = 0  // xml上面的音符时间
+	let xmlMp3BeatFixTime = 0 // xml上节拍器的时间
 
 	let preNoteEndTime = 0; // 上一个音符的结束时间
 
@@ -983,8 +984,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 					state.fixtime = fixtime;
 				}
 				// 存储mp3节拍器时间
-				metronomeDataState.xmlMp3BeatFixTime = getFixTime(beatSpeed)
-				// 
+				xmlMp3BeatFixTime = getFixTime(beatSpeed)
 				// console.log("fixtime:", fixtime, '速度:', beatSpeed, "state.isSpecialBookCategory:", state.isSpecialBookCategory, 'state.isOpenMetronome:', state.isOpenMetronome);
 			}
 			// console.log(getTimeByBeatUnit(beatUnit, measureSpeed, iterator.currentMeasure.activeTimeSignature.Denominator))
@@ -1210,7 +1210,14 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 				measureSpeed,  // 小节速度
 				maxNoteNum: note.maxNoteNum, // 当前小节音符最多的分轨的音符数量
 				repeatIdx: iterator.repeatIdx || 0, // 标记是第几遍循环,从0开始
+				xmlNoteTime: retain(xmlNoteTime), // xml上音符开始时间 唱名用
+				xmlNoteEndTime: retain(xmlNoteTime + noteLength), //xml上音符结束时间 唱名用
+				xmlMp3BeatFixTime,  //xml上节拍器的时间
+				notBeatFixtime: state.isOpenMetronome ? fixtime - xmlMp3BeatFixTime : fixtime, // 不含节拍器的fixtime值 唱名用
+				notBeatTime: state.isEvxml && evNoteStartTime ? retain(evNoteStartTime) : retain(relativeTime + (state.isOpenMetronome ? fixtime - xmlMp3BeatFixTime : fixtime)), // 不含节拍器的 音符开始时间
+				notBeatEndTime: state.isEvxml && evNoteEndTime ? retain(evNoteEndTime) : retain(relaEndtime + (state.isOpenMetronome ? fixtime - xmlMp3BeatFixTime : fixtime)) // 不含节拍器的 音符结束时间
 			};
+			xmlNoteTime += noteLength
 			// 如果是妙极客的曲子,并且第二遍循环播放需要等待时间,并且是第二遍循环的第一个小节的第一个音符
 			// if (state.isEvxml && state.secondEvXmlBeginTime && nodeDetail.i > 0 && nodeDetail.MeasureNumberXML === 1 && nodeDetail.noteId === 0) {
 			// 	nodeDetail.time = nodeDetail.time + state.secondEvXmlBeginTime;
@@ -1256,7 +1263,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 		i++;
 	}
 	// 按照时间轴排序
-	const sortArray = allNotes.sort((a, b) => a.relativeTime - b.relativeTime).map((item, index) => ({ ...item, i: index }));
+	const sortArray = allNotes.sort((a, b) => a.relativeTime - b.relativeTime).map((item, index) => Object.assign(item,{i:index}));
 	// const sortArray = allNotes.sort((a, b) => a.time - b.time).map((item, index) => ({ ...item, i: index }));
 	// const sortArray = allNotes.map((item, index) => ({ ...item, i: index }));
 	console.timeEnd("音符跑完时间");

+ 0 - 1
src/helpers/metronome.ts

@@ -42,7 +42,6 @@ export const metronomeData = reactive({
 	cursorTips: '' as string, // 光标模式提示文字
 	followAudioIndex: 1, // 当前的拍数
 	totalNumerator: 2, // 总拍数
-	xmlMp3BeatFixTime: 0   // 当前xml mp3节拍器的时间 切换演奏和演唱计算时间用
 });
 
 watch(

+ 159 - 65
src/page-instrument/header-top/index.tsx

@@ -1,4 +1,4 @@
-import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef } from "vue";
+import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef,ComputedRef } from "vue";
 import styles from "./index.module.less";
 
 import iconBack from "./image/icon-back.png";
@@ -9,7 +9,7 @@ import { Badge, Circle, Popover, Popup, showConfirmDialog, showToast, NoticeBar
 import Speed from "./speed";
 import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating";
 import Settting from "./settting";
-import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay } from "/src/state";
+import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay, IPlayState } from "/src/state";
 import { getAudioCurrentTime } from "/src/view/audio-list";
 import { followData, toggleFollow } from "/src/view/follow-practice";
 import { api_back } from "/src/helpers/communication";
@@ -89,6 +89,143 @@ export const headData = reactive({
   musicTypeShow: false,
 });
 
+let resetBtn:ComputedRef<{
+  display: boolean;
+  disabled: boolean;
+}>
+/**
+ * 处理模式切换
+ * @param oldPlayType   没改变之前的播放模式
+ * @param oldPlaySource  没改变之前的播放类型
+ * @param isforceReset   是否强制刷新播放状态 模式times时值改变时候也刷新
+ */
+export function handlerModeChange(oldPlayType:"play"|"sing", oldPlaySource:IPlayState,isforceReset?:boolean) {
+    const isModeChange = modeChangeHandleTimes(oldPlayType, oldPlaySource)
+    // 没有切换的时候 不处理下面的
+    if(isModeChange){
+      try {
+        metronomeData.metro.calculation(state.times);
+      } catch (error) {}
+      console.log("重新之后的times", state.times, state.fixtime)
+    }
+    if(isModeChange||isforceReset){
+      // 重置播放状态
+      handleRessetState()
+      // 隐藏重播按钮
+      resetBtn && (resetBtn.value.display = false)
+    }
+}
+// 模式切换之后重新给times赋值
+function modeChangeHandleTimes(oldPlayType:"play"|"sing", oldPlaySource:IPlayState){
+  const playType = state.playType
+  const playSource = state.playSource
+  const {notBeatFixtime, xmlMp3BeatFixTime} = state.times[0]
+  const { isOpenMetronome, isSingOpenMetronome } = state 
+  // 演奏向演唱切
+  if(oldPlayType === "play"&&playType === "sing"){
+    if(playSource === "mingSong"){
+      state.fixtime = 0
+      state.times.map(item => {
+        item.time = item.xmlNoteTime
+        item.endtime = item.xmlNoteEndTime
+        item.fixtime = 0
+      })
+      return true
+    }else{
+      //演奏开了节拍器,演唱没开节拍器
+      if(isOpenMetronome&&!isSingOpenMetronome){
+        state.fixtime = notBeatFixtime
+        state.times.map(item => {
+          item.time = item.notBeatTime
+          item.endtime = item.notBeatEndTime
+          item.fixtime = notBeatFixtime
+        })
+        return true
+      }else if(!isOpenMetronome&&isSingOpenMetronome){
+        state.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        state.times.map(item => {
+          item.time = item.notBeatTime + xmlMp3BeatFixTime
+          item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime
+          item.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        })
+        return true
+      }
+    }
+  }else if(oldPlayType === "sing"&&playType === "play"){
+    // 演唱向演奏切
+    if(oldPlaySource === "mingSong"){
+      // 有节拍器
+      if(isOpenMetronome){
+        state.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        state.times.map(item => {
+          item.time = item.notBeatTime + xmlMp3BeatFixTime
+          item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime
+          item.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        })
+        return true
+      }else{
+        state.fixtime = notBeatFixtime
+        state.times.map(item => {
+          item.time = item.notBeatTime
+          item.endtime = item.notBeatEndTime
+          item.fixtime = notBeatFixtime
+        })
+        return true
+      }
+    }
+    // 演奏开了节拍器,演唱没开节拍器
+    if(isOpenMetronome&&!isSingOpenMetronome){
+      state.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+      state.times.map(item => {
+        item.time = item.notBeatTime + xmlMp3BeatFixTime
+        item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime
+        item.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+      })
+      return true
+    }else if(!isOpenMetronome&&isSingOpenMetronome){
+      state.fixtime = notBeatFixtime
+      state.times.map(item => {
+        item.time = item.notBeatTime
+        item.endtime = item.notBeatEndTime
+        item.fixtime = notBeatFixtime
+      })
+      return true
+    }
+  }else if(oldPlayType === "sing"&&playType === "sing"){
+    // 演唱之间切换  
+    // 切到唱名时候
+    if(playSource === "mingSong"){
+      state.fixtime = 0
+      state.times.map(item => {
+        item.time = item.xmlNoteTime
+        item.endtime = item.xmlNoteEndTime
+        item.fixtime = 0
+      })
+      return true
+    }else if(oldPlaySource === "mingSong"){
+      // 有节拍器
+      if(isSingOpenMetronome){
+        state.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        state.times.map(item => {
+          item.time = item.notBeatTime + xmlMp3BeatFixTime
+          item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime
+          item.fixtime = notBeatFixtime + xmlMp3BeatFixTime
+        })
+        return true
+      }else{
+        state.fixtime = notBeatFixtime
+        state.times.map(item => {
+          item.time = item.notBeatTime
+          item.endtime = item.notBeatEndTime
+          item.fixtime = notBeatFixtime
+        })
+        return true
+      }
+    }
+  }
+  return false
+}
+
 export default defineComponent({
   name: "header-top",
   emits: ["close"],
@@ -200,6 +337,11 @@ export default defineComponent({
             // 原声, 伴奏 少一个,就不能切换
             if (state.music && state.accompany) return { display: true, disabled: false };
         } else {
+          // 播放过程中不能切换
+          if (state.playState === "play"){
+            return { display: true, disabled: true };
+          }
+          // 范唱 
           let index = 0
           state.fanSong && index++
           state.banSong && index++
@@ -223,15 +365,17 @@ export default defineComponent({
       // 音频播放中 禁用
       if (state.playState === "play") return { display: true, disabled: true };
       if (!state.isAppPlay) {
-        if(!state.isConcert){
           let index = 0
-          state.fanSong && index++
-          state.banSong && index++
-          state.mingSong && index++
-          if(index > 0) {
+          state.music && index++
+          state.accompany && index++
+          let songIndex = 0
+          state.fanSong && songIndex++
+          state.banSong && songIndex++
+          state.mingSong && songIndex++
+          // 演唱和演奏 都有数据的时间不禁用
+          if(songIndex>0&&index>0) {
             return { display: true, disabled: false };
           }
-        }
       }
       return {
         disabled: true,
@@ -266,7 +410,7 @@ export default defineComponent({
     });
 
     /** 重播按钮 */
-    const resetBtn = computed(() => {
+    resetBtn = computed(() => {
       // 选择模式 不显示
       if (headTopData.modeType !== "show") return { display: false, disabled: false };
       // 评测模式 不显示,跟练模式 不显示
@@ -428,61 +572,6 @@ export default defineComponent({
         console.log(e);
       }
     };
-
-    // 切换 演唱和演奏模式的时候处理
-    function handlerRefreshPlayType() {
-      // 妙极客的 曲子 时间是不变的,所以不做处理
-      if( !state.isEvxml ) {
-        // 重新计算state.times
-        const { isOpenMetronome, isSingOpenMetronome } = state
-        const { xmlMp3BeatFixTime } = metronomeData
-        if(state.playType === "play"){
-          if(isOpenMetronome && !isSingOpenMetronome){
-            state.fixtime = state.fixtime + xmlMp3BeatFixTime
-          } else if(!isOpenMetronome && isSingOpenMetronome){
-            state.fixtime = state.fixtime - xmlMp3BeatFixTime
-          }
-        }else{
-          if(isSingOpenMetronome && !isOpenMetronome){
-            state.fixtime = state.fixtime + xmlMp3BeatFixTime
-          } else if(!isSingOpenMetronome && isOpenMetronome){
-            state.fixtime = state.fixtime - xmlMp3BeatFixTime
-          }
-        }
-        const fixtime = state.fixtime
-        state.times.map(item => {
-          if(state.playType === "play"){
-            if(isOpenMetronome && !isSingOpenMetronome){
-              item.time = item.time + xmlMp3BeatFixTime
-              item.endtime = item.endtime + xmlMp3BeatFixTime
-              item.fixtime = fixtime
-            } else if(!isOpenMetronome && isSingOpenMetronome){
-              item.time = item.time - xmlMp3BeatFixTime
-              item.endtime = item.endtime - xmlMp3BeatFixTime
-              item.fixtime = fixtime
-            }
-          }else{
-            if(isSingOpenMetronome && !isOpenMetronome){
-              item.time = item.time + xmlMp3BeatFixTime
-              item.endtime = item.endtime + xmlMp3BeatFixTime
-              item.fixtime = fixtime
-            } else if(!isSingOpenMetronome && isOpenMetronome){
-              item.time = item.time - xmlMp3BeatFixTime
-              item.endtime = item.endtime - xmlMp3BeatFixTime
-              item.fixtime = fixtime
-            }
-          }
-        })
-        try {
-          metronomeData.metro.calculation(state.times);
-        } catch (error) {}
-        console.log("重新之后的times", state.times, fixtime)
-      }
-      // 重置播放状态
-      handleRessetState()
-      // 隐藏重播按钮
-      resetBtn.value.display = false
-    }
     return () => (
       <>
         <div
@@ -572,6 +661,8 @@ export default defineComponent({
               style={{ display: playTypeBtn.value.display ? "" : "none" }}
               class={[styles.btn, playTypeBtn.value.disabled && styles.disabled]}
               onClick={() => {
+                const oldPlayType = state.playType
+                const oldPlaySource = state.playSource
                 if(state.playType === "play"){
                   state.playType = "sing"
                   state.playSource = state.fanSong?"music":state.banSong?"background":"mingSong"
@@ -579,7 +670,7 @@ export default defineComponent({
                   state.playType = "play"
                   state.playSource = state.music?"music":"background"
                 }
-                handlerRefreshPlayType()
+                handlerModeChange(oldPlayType, oldPlaySource, true)
               }}
             >
               <img style={{ display: state.playType === "play" ? "" : "none" }} class={styles.iconBtn} src={headImg(`perform.png`)} />
@@ -591,6 +682,8 @@ export default defineComponent({
               style={{ display: originBtn.value.display ? "" : "none" }}
               class={[styles.btn, originBtn.value.disabled && styles.disabled]}
               onClick={() => {
+                const oldPlayType = state.playType
+                const oldPlaySource = state.playSource
                 if(state.playType === 'play'){
                   state.playSource = state.playSource === "music" ? "background" : "music";
                 }else{
@@ -602,6 +695,7 @@ export default defineComponent({
                     state.playSource = state.fanSong ? "music" :"background"
                   }
                 }
+                handlerModeChange(oldPlayType, oldPlaySource)
               }}
             >
               <img style={{ display: state.playSource === "music" ? "" : "none" }} class={styles.iconBtn} src={state.playType === 'play'?headImg(`music.png`):headImg(`music1.png`)} />

二进制
src/page-instrument/view-detail/emptyMusic/imgs/empty.png


+ 41 - 0
src/page-instrument/view-detail/emptyMusic/index.module.less

@@ -0,0 +1,41 @@
+.emptyMusic {
+    position: fixed;
+    z-index: 9999;
+    width: 100vw;
+    height: 100vh;
+    top: 0;
+    left: 0;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    background-color: #fff;
+    .emptyMusicBox{
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        .img{
+            width: 202px;
+            height: 179px;
+        }
+        .tit{
+            margin-top: 6px;
+            font-weight: 400;
+            font-size: 16px;
+            color: #999999;
+            line-height: 22px;
+        }
+        .backBtn{
+            margin-top: 16px;
+            width: 100px;
+            height: 36px;
+            border-radius: 18px;
+            border: 1px solid #1CACF1;
+            font-weight: 400;
+            font-size: 16px;
+            color: #1CACF1;
+            line-height: 36px;
+            text-align: center;
+            cursor: pointer;
+        }
+    }
+}

+ 46 - 0
src/page-instrument/view-detail/emptyMusic/index.tsx

@@ -0,0 +1,46 @@
+import { defineComponent, ref } from "vue"
+import styles from "./index.module.less"
+import empty from "./imgs/empty.png"
+import { browser } from "/src/utils";
+import { HANDLE_WORK_ADD } from "../../custom-plugins/work-index";
+import { storeData } from "/src/store";
+import { api_back } from "/src/helpers/communication";
+import { getQuery } from "/src/utils/queryString";
+
+export const isEmptyMusicShow = ref(false)
+export default defineComponent({
+   name: "emptyMusic",
+   setup() {
+      const query = getQuery();
+      const browInfo = browser()
+      /** 返回 */
+      const handleBack = () => {
+         HANDLE_WORK_ADD()
+         // 不在APP中,
+         if (!storeData.isApp) {
+            window.close()
+            return
+         }
+         if ((browInfo.iPhone || browInfo.ios) && query.workRecord) {
+            setTimeout(() => {
+               api_back()
+            }, 550)
+            return
+         }
+         api_back()
+      }
+      return () => (
+         <>
+            {isEmptyMusicShow.value && (
+               <div class={styles.emptyMusic}>
+                  <div class={styles.emptyMusicBox}>
+                     <img class={styles.img} src={empty} />
+                     <div class={styles.tit}>曲目已失效</div>
+                     <div class={styles.backBtn} onClick={handleBack}>返回</div>
+                  </div>
+               </div>
+            )}
+         </>
+      )
+   }
+})

+ 54 - 15
src/page-instrument/view-detail/index.tsx

@@ -9,7 +9,7 @@ import MusicScore from "../../view/music-score";
 import TestCheck from "/src/view/music-score/testCheck";
 import { sysMusicScoreAccompanimentQueryPage } from "../api";
 import EvaluatModel from "../evaluat-model";
-import HeaderTop from "../header-top";
+import HeaderTop, {handlerModeChange} from "../header-top";
 import styles from "./index.module.less";
 import { api_cloudAccompanyMessage, api_cloudLoading, api_keepScreenLongLight, api_openCamera, api_openWebView, api_setEventTracking, api_setRequestedOrientation, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
 import { getQuery } from "/src/utils/queryString";
@@ -35,6 +35,7 @@ import TheAudio from "/src/components/the-audio"
 import tickWav from "/src/assets/tick.mp3";
 import AuthorName from "../component/authorName"
 import { initSmoothAnimation } from "./smoothAnimation"
+import EmptyMusic, { isEmptyMusicShow } from "./emptyMusic"
 
 const DelayCheck = defineAsyncComponent(() =>
   import('/src/page-instrument/evaluat-model/delay-check')
@@ -144,7 +145,13 @@ export default defineComponent({
       // Promise.all([sysMusicScoreAccompanimentQueryPage(id)]).then((values) => {
       //   getMusicInfo(values[0]);
       // });
-      await getMusicDetail(id);
+      try { 
+        await getMusicDetail(id);
+      } catch (err) {
+        console.error(err)
+        isEmptyMusicShow.value = true
+        return
+      }
       detailData.isLoading = false;
       // 如果后台设置了不显示指法,关闭指法开关
       if (!state.isShowFingering) {
@@ -171,6 +178,9 @@ export default defineComponent({
       setCustomGradual();
 			setCustomNoteRealValue();
       state.times = formateTimes(osmd);
+      // state.times = resetFrequency(state.times);
+      state.times = setNoteHalfTone(state.times);
+      console.log("🚀 ~ state.times:", state.times, state.subjectId, state);
       // 一行谱
       if (state.isSingleLine) {
         // 音符添加位置信息bbox
@@ -178,9 +188,6 @@ export default defineComponent({
         // 一行谱创建 动画
         initSmoothAnimation();
       }
-      // state.times = resetFrequency(state.times);
-      state.times = setNoteHalfTone(state.times);
-      console.log("🚀 ~ state.times:", state.times, state.subjectId, state);
       // 初始化midi音频信息
       const songEndTime = state.times[state.times.length - 1 || 0]?.endtime || 0
       if (state.isAppPlay) {
@@ -196,18 +203,16 @@ export default defineComponent({
       // 需要向外面(iframe)派发计时器数据的时候触发
       if(query.isbeatTimes){
         const { isOpenMetronome, isSingOpenMetronome } = state
-        const { xmlMp3BeatFixTime } = metronomeData
+        const {xmlMp3BeatFixTime} = state.times[0] 
         const singBeatTime: number[][] = []
         const beatTime = metronomeData.metroMeasure.map(metroMeasure => {
           const singBeat:number[] = []
           const beatTimeItem = metroMeasure.map((item: any) => {
             let singTime = item.time
-            if(!state.isEvxml){
-              if(isSingOpenMetronome && !isOpenMetronome){
-                singTime += xmlMp3BeatFixTime
-              } else if(!isSingOpenMetronome && isOpenMetronome){
-                singTime -= xmlMp3BeatFixTime
-              }
+            if(isSingOpenMetronome && !isOpenMetronome){
+              singTime += xmlMp3BeatFixTime
+            } else if(!isSingOpenMetronome && isOpenMetronome){
+              singTime -= xmlMp3BeatFixTime
             }
             singBeat.push(singTime)
             return item.time
@@ -215,16 +220,48 @@ export default defineComponent({
           singBeatTime.push(singBeat)
           return beatTimeItem
         })
-        console.log("webApi_beatTimes",{beatTime,singBeatTime})
+        //改为唱名
+        state.fixtime = 0
+        state.times.map(item => {
+          item.time = item.xmlNoteTime
+          item.endtime = item.xmlNoteEndTime
+          item.fixtime = 0
+        })
+        metronomeData.metro.calculation(state.times)
+        const mingBeatTime:number[][] = metronomeData.metroMeasure.map(metroMeasure => {
+          const beatTimeItem = metroMeasure.map((item: any) => {
+            return item.time
+          })
+          return beatTimeItem
+        })
+        console.log("webApi_beatTimes",{beatTime,singBeatTime,mingBeatTime})
         window.parent.postMessage(
           {
             api: "webApi_beatTimes",
-            data: JSON.stringify({beatTime,singBeatTime})
+            data: JSON.stringify({beatTime,singBeatTime,mingBeatTime})
           },
           "*"
         );
+        throw new Error("webApi_beatTimes 完成");
+      }
+      // 根据当前文件有没有 设置当前的播放模式
+      if(!state.music){
+        if(state.accompany){
+          state.playSource = "background"
+        }else{
+          if(state.fanSong){
+            state.playType = "sing"
+            state.playSource = "music"
+          }else if(state.banSong){
+            state.playType = "sing"
+            state.playSource = "background"
+          }else if(state.mingSong){
+            state.playType = "sing"
+            state.playSource = "mingSong"
+          }
+          handlerModeChange("play", "music")
+        }
       }
-      
       /**
        * 2024.1.25
        * 设置节拍器,跟练需要播放系统节拍器,所以不需要判断needTick状态
@@ -435,6 +472,8 @@ export default defineComponent({
             </div>
           )}
         </Transition>
+        {/* 曲目加载错误的缺省 */}
+        <EmptyMusic></EmptyMusic>
         {/** 功能按钮 */}
         {
           !state.isPreView && 

+ 8 - 6
src/state.ts

@@ -1209,7 +1209,6 @@ const getMusicInfo = async (res: any) => {
   index = tracks.findIndex(item => {  // 筛选出当前的index
     return item === musicObj?.track
   })
-  index = index >= 0 ? index : 0;
   const musicInfo = {
     ...res.data,
     track: musicObj?.track
@@ -1242,6 +1241,10 @@ function initMusicSource (data: any, track?:string) {
     musicObj = musicSheetSoundList.find((item:any) => {
       return (isAllSubject||!instrumentId)?item.audioPlayType === "PLAY":(item.audioPlayType === "PLAY"&&item.musicalInstrumentId ==instrumentId)
     })
+    // 因为可能根据学生的乐器id也找不到曲目所以尝试取第一个
+    musicObj || (musicObj = musicSheetSoundList.find((item:any) => {
+      return item.audioPlayType === "PLAY"
+    }))
     fanSongObj = musicSheetSoundList.find((item:any) => {
       return item.audioPlayType === "SING"
     })
@@ -1257,6 +1260,10 @@ function initMusicSource (data: any, track?:string) {
   accompanyObj = musicSheetAccompanimentList.find((item:any) => {
     return item.audioPlayType === "PLAY"
   })
+  // 当没有任何曲目的时候报错
+  if(!musicObj?.audioFileUrl&&!accompanyObj?.audioFileUrl&&!fanSongObj?.audioFileUrl&&!banSongObj?.audioFileUrl&&!fanSongObj?.solmizationFileUrl){
+    throw new Error("该曲目无任何音源");
+  }
   Object.assign(state, {
     music: musicObj?.audioFileUrl,
     accompany: accompanyObj?.audioFileUrl,
@@ -1377,11 +1384,6 @@ const setState = (data: any, index: number) => {
     state.setting.displayFingering = false
   }
 
-  // 检测是否原音和伴奏都有
-  if (!state.music || !state.accompany) {
-    state.playSource = state.music ? "music" : "background";
-  }
-
   // 如果是PC端,放大曲谱
   state.platform = query.platform?.toLocaleUpperCase() || "";
   if (state.platform === IPlatform.PC) {