Browse Source

音源文件和布局

黄琪勇 8 months ago
parent
commit
d797598cf8

+ 2 - 2
src/helpers/customMusicScore.ts

@@ -82,7 +82,7 @@ export const resetGivenFormate = () => {
 	}
 	const tieList = musicList[state.cbsExamSongId as string]
 	if (tieList) {
-		const partIndex = query["part-index"] || '0'
+		const partIndex = state.partIndex + ""
 		const tie = tieList.find((item) => item.parts.includes(partIndex))
 		if (!tie) return
 		// 延音线和连线重叠
@@ -643,7 +643,7 @@ const collisionDetection = (a: SVGAElement, b: SVGAElement, distance: number = 0
 
 /** 全局曲谱配置 */
 export const setGlobalMusicSheet = () => {
-	const partIndex = query["part-index"] || '0'
+	const partIndex = state.partIndex + ""
 	/** 延音线方向问题 start */
 	const stavetieList = [
 	  {id: '12644', part_index: '25', direction: 1}

+ 19 - 3
src/helpers/metronome.ts

@@ -11,6 +11,7 @@ import { Howl } from "howler";
 import tockAndTick from "/src/constant/tockAndTick.json";
 import tickWav from "/src/assets/tick.mp3";
 import tockWav from "/src/assets/tock.mp3";
+import { audioData as audioDataState } from "../view/audio-list"
 
 type IOptions = {
 	speed: number;
@@ -180,10 +181,25 @@ class Metronome {
 	};
 	// 播放
 	playAudio = () => {
-		/* 如果是 评测模式且不为MIDI并且节拍器资源加载成功的时候  不运行节拍器播放频*/
-		if (state.audioBetaDone && state.modeType === "practise" && state.playMode !== "MIDI") {
-			return
+		/* 如果是 评测模式且不为MIDI并且节拍器资源加载成功的时候  不运行节拍器播放*/
+		if (state.modeType === "practise" && state.playMode !== "MIDI") {
+			if(state.playType === "play" && state.playSource === "music" && audioDataState.songCollection.beatSongEle){
+				return
+			}			
+			if(state.playType === "play" && state.playSource === "background" && audioDataState.songCollection.betaBackgroundEle){
+				return
+			}			
+			if(state.playType === "sing" && state.playSource === "music" && audioDataState.songCollection.betaFanSongEle){
+				return
+			}			
+			if(state.playType === "sing" && state.playSource === "background" && audioDataState.songCollection.betaBanSongEle){
+				return
+			}			
+			if(state.playType === "sing" && state.playSource === "mingSong" && audioDataState.songCollection.betaMingSongEle){
+				return
+			}			
 		}
+		console.log("播放自带的节拍器 233333")
 		if (!metronomeData.initPlayerState || state.playState === 'paused') return;
 		const beatVolume = state.setting.beatVolume / 100
 		// this.source = metronomeData.activeMetro?.index === 0 ? this.source1 : this.source2;

+ 3 - 0
src/page-instrument/component/authorName/index.module.less

@@ -1,3 +1,6 @@
+.authorName{
+    height: 2.4rem;
+}
 .title{
     width: 216px;
     margin: 0 auto;

+ 2 - 2
src/page-instrument/component/authorName/index.tsx

@@ -11,7 +11,7 @@ export default defineComponent({
          <>
             {
                !smoothAnimationState.isShow.value && 
-               <>
+               <div class={["authorName", styles.authorName]}>
                   <div class={styles.title}>
                      <NoticeBar text={state.examSongName} background="none" />
                   </div>
@@ -22,7 +22,7 @@ export default defineComponent({
                         {/* <NoticeBar text={'作词:李非 / 作曲:雅克兄弟'} background="none" /> */}
                      </div>
                   </div>
-               </>
+               </div>
             }
          </>
       )

+ 0 - 0
src/page-instrument/header-top/image/练习功能/伴奏@2x (3).png → src/page-instrument/header-top/image/background1.png


BIN
src/page-instrument/header-top/image/list.png


+ 0 - 0
src/page-instrument/header-top/image/练习功能/伴奏@2x (4).png → src/page-instrument/header-top/image/mingsong.png


+ 0 - 0
src/page-instrument/header-top/image/练习功能/伴奏@2x (2).png → src/page-instrument/header-top/image/music1.png


+ 3 - 1
src/page-instrument/header-top/index.module.less

@@ -16,10 +16,12 @@
     .img{
         width: 32px;
         height: 32px;
+        &:first-child{
+            margin-right: 10px;
+        }
     }
     .title{
         width: 216px;
-        margin-left: 10px;
         :global{
             .van-notice-bar{
                 height: 30px;

+ 78 - 20
src/page-instrument/header-top/index.tsx

@@ -2,13 +2,14 @@ import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive
 import styles from "./index.module.less";
 
 import iconBack from "./image/icon-back.png";
+import listImg from "./image/list.png";
 import iconMode from "./image/mode.png";
 import { headImg } from "./image";
 import { Badge, Circle, Popover, Popup, showConfirmDialog, showToast, NoticeBar } from "vant";
 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, resetPlaybackToStart } 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";
@@ -28,6 +29,7 @@ import useDrag from "/src/view/plugins/useDrag/index";
 import Dragbom from "/src/view/plugins/useDrag/dragbom";
 import { getGuidance, setGuidance } from "../custom-plugins/guide-page/api";
 import ModeView from "./modeView"
+import { smoothAnimationState } from "../view-detail/smoothAnimation"
 
 /** 头部数据和方法 */
 export const headTopData = reactive({
@@ -193,15 +195,48 @@ export default defineComponent({
       // 评测开始 禁用
       if (state.modeType === "evaluating") return { display: false, disabled: true };
       if (!state.isAppPlay) {
-        // 原声, 伴奏 少一个,就不能切换
-        if (!state.music || !state.accompany) return { display: true, disabled: true };
+        if(state.playType === "play"){
+            // 原声, 伴奏 少一个,就不能切换
+            if (state.music && state.accompany) return { display: true, disabled: false };
+        } else {
+          let index = 0
+          state.fanSong && index++
+          state.banSong && index++
+          state.mingSong && index++
+          if(index > 1) {
+            return { display: true, disabled: false };
+          }
+        }
       }
       return {
-        disabled: false,
+        disabled: true,
         display: true,
       };
     });
-
+    /** 播放类型按钮 */
+    const playTypeBtn = computed(() => {
+      // 选择模式,跟练模式 不显示
+      if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false };
+      // 评测开始 禁用
+      if (state.modeType === "evaluating") return { display: false, disabled: true };
+      // 音频播放中 禁用
+      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) {
+            return { display: true, disabled: false };
+          }
+        }
+      }
+      return {
+        disabled: true,
+        display: true,
+      };
+    })
     /** 模式切换按钮 */
     const toggleBtn = computed(() => {
       // 选择模式, url设置模式 不显示
@@ -413,12 +448,16 @@ export default defineComponent({
           {/* 返回和标题 */}
           <div class={styles.headTopLeftBox}>
             <img src={iconBack} class={['headTopBackBtn', styles.img, !headTopData.showBack && styles.hidenBack]} onClick={handleBack} />
-            <div class={styles.title}>
-              <NoticeBar
-                text={state.examSongName}
-                background="none"
-              />
-            </div>
+            {
+              state.modeType === "practise" && smoothAnimationState.isShow.value ? 
+                <div class={styles.title}>
+                  <NoticeBar
+                    text={state.examSongName}
+                    background="none"
+                  />
+              </div> :
+              <img src={listImg} class={[styles.img]} />
+            }
           </div>
           {/* 模式切换 */}
           <div 
@@ -468,26 +507,45 @@ export default defineComponent({
               </div>
             ) : null} */}
             <div
-              class={[styles.btn]}
+              style={{ display: playTypeBtn.value.display ? "" : "none" }}
+              class={[styles.btn, playTypeBtn.value.disabled && styles.disabled]}
               onClick={() => {
-                state.playType = state.playType === "perform" ? "sing" : "perform";
+                if(state.playType === "play"){
+                  state.playType = "sing"
+                  state.playSource = state.fanSong?"music":state.banSong?"background":"mingSong"
+                } else {
+                  state.playType = "play"
+                  state.playSource = state.music?"music":"background"
+                }
+                resetPlaybackToStart()
               }}
             >
-              <img style={{ display: state.playType === "perform" ? "" : "none" }} class={styles.iconBtn} src={headImg(`perform.png`)} />
-              <img style={{ display: state.playType === "perform" ? "none" : "" }} class={styles.iconBtn} src={headImg(`sing.png`)} />
-              <span>{state.playType === "perform" ? "演奏" : "演唱"}</span>
+              <img style={{ display: state.playType === "play" ? "" : "none" }} class={styles.iconBtn} src={headImg(`perform.png`)} />
+              <img style={{ display: state.playType === "play" ? "none" : "" }} class={styles.iconBtn} src={headImg(`sing.png`)} />
+              <span>{state.playType === "play" ? "演奏" : "演唱"}</span>
             </div>
             <div
               id={state.platform === IPlatform.PC ? "teacherTop-1" : "studnetT-1"}
               style={{ display: originBtn.value.display ? "" : "none" }}
               class={[styles.btn, originBtn.value.disabled && styles.disabled]}
               onClick={() => {
-                state.playSource = state.playSource === "music" ? "background" : "music";
+                if(state.playType === 'play'){
+                  state.playSource = state.playSource === "music" ? "background" : "music";
+                }else{
+                  if(state.playSource === "music"){
+                    state.playSource = state.banSong ? "background" :"mingSong"
+                  }else if(state.playSource === "background"){
+                    state.playSource = state.mingSong ? "mingSong" :"music"
+                  }else {
+                    state.playSource = state.fanSong ? "music" :"background"
+                  }
+                }
               }}
             >
-              <img style={{ display: state.playSource === "music" ? "" : "none" }} class={styles.iconBtn} src={headImg(`music.png`)} />
-              <img style={{ display: state.playSource === "music" ? "none" : "" }} class={styles.iconBtn} src={headImg(`background.png`)} />
-              <span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
+              <img style={{ display: state.playSource === "music" ? "" : "none" }} class={styles.iconBtn} src={state.playType === 'play'?headImg(`music.png`):headImg(`music1.png`)} />
+              <img style={{ display: state.playSource === "background" ? "" : "none" }} class={styles.iconBtn} src={state.playType === 'play'?headImg(`background.png`):headImg(`background1.png`)} />
+              <img style={{ display: state.playSource === "mingSong" ? "" : "none" }} class={styles.iconBtn} src={headImg(`mingsong.png`)} />
+              <span>{state.playSource === "music" ? (state.playType ==="play" ? "原声" : "范唱") : state.playSource === "background" ? (state.playType ==="play" ? "伴奏" : "伴唱") : "唱名"}</span>
             </div>
             <div id={state.platform === IPlatform.PC ? "teacherTop-2" : "studnetT-2"} style={{ display: selectBtn.value.display ? "" : "none" }} class={[styles.btn, selectBtn.value.disabled && styles.disabled]} onClick={() => handleChangeSection()}>
               <img style={{ display: state.section.length === 0 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section0.png`)} />

+ 2 - 2
src/page-instrument/view-detail/index.module.less

@@ -37,8 +37,8 @@
 
     .container {
         position: sticky;
-        top: 38px;
-        height: calc(100vh - 38px);
+        top: 36px;
+        height: calc(100vh - 36px);
         margin: 0 10px;
         border-radius: 10px;
         transition: height .2s;

+ 2 - 11
src/page-instrument/view-detail/index.tsx

@@ -5,7 +5,7 @@ import Metronome, { metronomeData } from "../../helpers/metronome";
 import state, { EnumMusicRenderType, evaluatCreateMusicPlayer, handleSetSpeed, IAudioState, IPlatform, isRhythmicExercises, resetPlaybackToStart, togglePlay, getMusicDetail, addNoteBBox } from "/src/state";
 import { browser, setGlobalData } from "../../utils";
 import AudioList from "../../view/audio-list";
-import MusicScore, { resetMusicScore } from "../../view/music-score";
+import MusicScore from "../../view/music-score";
 import TestCheck from "/src/view/music-score/testCheck";
 import { sysMusicScoreAccompanimentQueryPage } from "../api";
 import EvaluatModel from "../evaluat-model";
@@ -282,9 +282,6 @@ export default defineComponent({
           //   state.musicScoreBtnDirection = state.playBtnDirection
           // }
           state.musicScoreBtnDirection = state.playBtnDirection
-          nextTick(() => {
-            resetMusicScore();
-          });
         }
       }
     );
@@ -341,13 +338,7 @@ export default defineComponent({
           }
         }
       }
-    );    
-    onMounted(() => {
-      window.addEventListener("resize", resetMusicScore);
-    });
-    onBeforeUnmount(() => {
-      window.removeEventListener("resize", resetMusicScore);
-    });
+    );
     const browsInfo = browser();
     const handleOpenFignerView = () => {
       if (!query.modelType) {

+ 15 - 1
src/page-instrument/view-detail/smoothAnimation/index.less

@@ -1,9 +1,14 @@
 #musicAndSelection.singleLineMusicBox{
     .smoothAnimationBox{
-        position: relative;
+        display: flex;
+        align-items: center;
+        height: 2.4rem;
         &.smoothAnimationBoxHide{
             opacity: 0;
         }
+    }
+    .smoothAnimationCon{
+        position: relative;
         .smoothBot{
             position: absolute;
             background: url("./bird.png") no-repeat;
@@ -14,10 +19,19 @@
             top: 0;
         }
     }
+    #osmdCanvasPage1{
+        top: 0;
+    }
     #cursorImg-0 {
         display: none;
     }
     .staveBox {
         display: none !important;
     }
+    .authorName{
+        position: fixed;
+        left: 0;
+        top: 36px;
+        width: 100vw;
+    }
 }

+ 6 - 2
src/page-instrument/view-detail/smoothAnimation/index.ts

@@ -243,6 +243,9 @@ function createSmoothAnimation() {
    const smoothAnimationBoxDom = document.createElement("div")
    smoothAnimationBoxDom.className = "smoothAnimationBox"
    smoothAnimationState.smoothAnimationBoxDom = smoothAnimationBoxDom
+   // con
+   const smoothAnimationConDom = document.createElement("div")
+   smoothAnimationConDom.className = "smoothAnimationCon"
    //canvas
    const smoothCanvasDom = document.createElement("canvas")
    smoothCanvasDom.className = "smoothCanvas"
@@ -255,8 +258,9 @@ function createSmoothAnimation() {
    const smoothBotDom = document.createElement("div")
    smoothBotDom.className = "smoothBot"
    smoothAnimationState.smoothBotDom = smoothBotDom
-   smoothAnimationBoxDom.appendChild(smoothCanvasDom)
-   smoothAnimationBoxDom.appendChild(smoothBotDom)
+   smoothAnimationConDom.appendChild(smoothCanvasDom)
+   smoothAnimationConDom.appendChild(smoothBotDom)
+   smoothAnimationBoxDom.appendChild(smoothAnimationConDom)
    // 添加到 osmdCanvasPage1
    osmdCanvasPageDom?.insertBefore(smoothAnimationBoxDom, osmdCanvasPageDom.firstChild)
 }

+ 1 - 7
src/page-instrument/view-evaluat-report/index.tsx

@@ -3,7 +3,7 @@ import { defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, T
 import { formateTimes } from "../../helpers/formateMusic";
 import state, { isRhythmicExercises, getMusicDetail, EnumMusicRenderType } from "../../state";
 import { setGlobalData } from "../../utils";
-import MusicScore, { resetMusicScore } from "../../view/music-score";
+import MusicScore from "../../view/music-score";
 import styles from "./index.module.less";
 import {
 	api_cloudLoading,
@@ -400,12 +400,6 @@ export default defineComponent({
 			// setMearureColor();
 			api_cloudLoading();
 		};
-		onMounted(() => {
-			window.addEventListener("resize", resetMusicScore);
-		});
-		onBeforeUnmount(() => {
-			window.removeEventListener("resize", resetMusicScore);
-		});
 		watch(
 			() => scoreData.itemType,
 			() => {

+ 1 - 7
src/report-share/gym-share/index.tsx

@@ -3,7 +3,7 @@ import { defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, T
 import { formateTimes } from "../../helpers/formateMusic";
 import state, { isRhythmicExercises } from "../../state";
 import { browser, setGlobalData } from "../../utils";
-import MusicScore, { resetMusicScore } from "../../view/music-score";
+import MusicScore from "../../view/music-score";
 import styles from "./index.module.less";
 import { api_cloudLoading, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
 import { getQuery } from "/src/utils/queryString";
@@ -154,12 +154,6 @@ export default defineComponent({
 			setMearureColor();
 			api_cloudLoading();
 		};
-		onMounted(() => {
-			window.addEventListener("resize", resetMusicScore);
-		});
-		onBeforeUnmount(() => {
-			window.removeEventListener("resize", resetMusicScore);
-		});
 
 		return () => (
 			<div class={[styles.shareBox, styles.detail, state.setting.eyeProtection && "eyeProtection", browserInfo.android && styles.android]} style={{ paddingLeft: detailData.paddingLeft }}>

+ 1 - 7
src/report-share/orchestra-share/index.tsx

@@ -3,7 +3,7 @@ import { computed, defineComponent, onBeforeMount, onBeforeUnmount, onMounted, r
 import { formateTimes } from "../../helpers/formateMusic";
 import state, { isRhythmicExercises } from "../../state";
 import { setGlobalData } from "../../utils";
-import MusicScore, { resetMusicScore } from "../../view/music-score";
+import MusicScore from "../../view/music-score";
 import styles from "./index.module.less";
 import { api_cloudLoading, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
 import { getQuery } from "/src/utils/queryString";
@@ -158,12 +158,6 @@ export default defineComponent({
 			setMearureColor();
 			api_cloudLoading();
 		};
-		onMounted(() => {
-			window.addEventListener("resize", resetMusicScore);
-		});
-		onBeforeUnmount(() => {
-			window.removeEventListener("resize", resetMusicScore);
-		});
 
 		return () => (
 			<div class={[styles.shareBox, styles.detail, state.setting.eyeProtection && "eyeProtection"]} style={{ paddingLeft: detailData.paddingLeft }}>

+ 84 - 27
src/state.ts

@@ -16,6 +16,8 @@ import { getQuery } from "/src/utils/queryString";
 import { followData } from "/src/view/follow-practice/index"
 import { changeSongSourceByBate } from "/src/view/audio-list"
 import { moveSmoothAnimation, smoothAnimationState, moveSmoothAnimationByPlayTime} from "/src/page-instrument/view-detail/smoothAnimation"
+import { storeData } from "/src/store";
+import { downloadXmlStr } from "./view/music-score"
 
 const query: any = getQuery();
 
@@ -32,7 +34,7 @@ export enum EnumMusicRenderType {
 }
 export const musicscoresettingKey = "musicscoresetting";
 /** 有声音的是那个音源 */
-export type IPlayState = "music" | "background";
+export type IPlayState = "music" | "background" | "mingSong";
 /** 播放状态 */
 export type IAudioState = "play" | "paused";
 
@@ -293,6 +295,20 @@ const state = reactive({
   music: "",
   /** 伴奏 */
   accompany: "",
+  /** 范唱 */
+  fanSong: "",
+  /** 伴唱 */
+  banSong: "",
+  /** 唱名 */
+  mingSong: "", 
+  /** 节拍器音乐资源 */
+  beatSong: {
+    music: "",
+    accompany: "",
+    fanSong: "",
+    banSong: "",
+    mingSong: ""
+  },
   /** midiURL */
   midiUrl: "",
   /** 父分ID */
@@ -324,7 +340,7 @@ const state = reactive({
   /** 播放结束状态 */
   playEnd: false,
   /** 播放类型 演奏 演唱 */
-  playType: "perform" as "perform" | "sing",
+  playType: "play" as "play" | "sing",
   /** 播放那个: 原音,伴奏 */
   playSource: "music" as IPlayState,
   /** 播放进度 */
@@ -452,8 +468,6 @@ const state = reactive({
   midiSectionStart: 0,
   /** 音频文件是否加载完成 */
   audioDone: false,
-  /** 节拍文件是否加载成功 */
-  audioBetaDone: false,
   /** 是否为单行谱渲染模式 */
   isSingleLine: false,
   /** 是否是evxml */
@@ -651,14 +665,6 @@ export const skipNotePlay = async (itemIndex: number, isStart = false) => {
   }
 };
 
-/* 还原音频源 */
-watch(()=>state.playState,()=>{
-  // 播放之前  当为评测模式和不为MIDI时候按  是否禁用节拍器  切换音源
-  if (state.audioBetaDone && state.playState==='paused' && state.modeType === "practise" && state.playMode !== "MIDI") {
-    console.log("还原音源")
-    changeSongSourceByBate(true)
-  }
-})
 /**
  * 切换曲谱播放状态
  * @param playState 可选: 默认 undefined, 需要切换的状态 play:播放, paused: 暂停
@@ -670,7 +676,7 @@ export const togglePlay = async (playState?: "play" | "paused", sourceType?: str
     return
   }
   // 播放之前  当为评测模式和不为MIDI时候按  是否禁用节拍器  切换音源
-  if (state.audioBetaDone && (playState ? playState : state.playState === "paused" ? "play" : "paused") ==='play' && state.modeType === "practise" && state.playMode !== "MIDI") {
+  if ((playState ? playState : state.playState === "paused" ? "play" : "paused") ==='play' && state.modeType === "practise" && state.playMode !== "MIDI") {
     console.log("设置音源")
     changeSongSourceByBate(metronomeData.disable)
   }
@@ -1161,28 +1167,81 @@ export const evaluatCreateMusicPlayer = () => {
 export const getMusicDetail = async (id: string) => {
   const res = await getMusicSheetDetail(id);
   if (res?.code === 200) {
-    getMusicInfo(res)
+    await getMusicInfo(res)
   }
 };
 
 
-const getMusicInfo = (res: any) => {
-  const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0;
-  // 原音声轨
-  const musicData = res.data.musicSheetSoundList?.[index] || {};
-  // 伴奏声轨
-  const accompanyData = res.data.musicSheetAccompanimentList?.[0] || {}
+const getMusicInfo = async (res: any) => {
+  const xmlString = await fetch(res.data.xmlFileUrl).then((response) => response.text());
+  downloadXmlStr.value = xmlString //给musice-score 赋值xmlString 以免加载2次
+  const tracks = xmlToTracks(xmlString) //获取声轨列表
+  let index = query["part-index"] ? parseInt(query["part-index"]) : 0
+  const musicObj = initMusicSource(res.data, tracks[index]) //当前part-index找不到声源的时候以第一个为准
+  index = tracks.findIndex(item => {  // 筛选出当前的index
+    return item === musicObj?.track
+  })
   const musicInfo = {
     ...res.data,
-    music: musicData.audioFileUrl || '',
-    accompany: accompanyData.audioFileUrl || '',
-    musicSheetId: musicData.musicSheetId || res.data.bizId,
-    track: musicData.track || '',
+    track: musicObj?.track
   };
   console.log("🚀 ~ musicInfo:", musicInfo);
   setState(musicInfo, index);
 };
-
+//获取xml中的音轨数据
+function xmlToTracks(xmlString: string) {
+  const xmlParse = new DOMParser().parseFromString(xmlString, "text/xml");
+  const partNames = Array.from(xmlParse.getElementsByTagName('part-name'));
+	return partNames.reduce((arr:string[], item)=>{
+    const textContent = item?.textContent?.trim()
+    if(textContent !== "COMMON" && textContent){
+      arr.push(textContent)
+    }
+    return arr
+  },[]);
+}
+// 设置音源
+function initMusicSource (data: any, track?:string) {
+  const { instrumentId } = storeData.user
+  const { musicSheetType, isAllSubject, musicSheetSoundList, musicSheetAccompanimentList } = data
+  let musicObj,accompanyObj,fanSongObj,banSongObj
+  // 独奏
+  if(musicSheetType === "SINGLE") {
+    // 适用声部(instrumentId)为true 时候没有乐器只有一个原音;当前用户有乐器就匹配  不然取第一个原音
+    musicObj = musicSheetSoundList.find((item:any) => {
+      return (isAllSubject||!instrumentId)?item.audioPlayType === "PLAY":(item.audioPlayType === "PLAY"&&item.musicalInstrumentId ==instrumentId)
+    })
+    fanSongObj = musicSheetSoundList.find((item:any) => {
+      return item.audioPlayType === "SING"
+    })
+    banSongObj = musicSheetAccompanimentList.find((item:any) => {
+      return item.audioPlayType === "SING"
+    })
+  } else {
+    // 合奏  合奏根据声轨来区分原音
+    musicObj = track?musicSheetSoundList.find((item:any) => {
+      return item.track === track
+    }):musicSheetSoundList[0]
+  }
+  accompanyObj = musicSheetAccompanimentList.find((item:any) => {
+    return item.audioPlayType === "PLAY"
+  })
+  Object.assign(state, {
+    music: musicObj?.audioFileUrl,
+    accompany: accompanyObj?.audioFileUrl,
+    fanSong: fanSongObj?.audioFileUrl,
+    banSong: banSongObj?.audioFileUrl,
+    mingSong: fanSongObj?.solmizationFileUrl
+  })  
+  Object.assign(state.beatSong, {
+    music: musicObj?.audioBeatMixUrl,
+    accompany: accompanyObj?.audioBeatMixUrl,
+    fanSong: fanSongObj?.audioBeatMixUrl,
+    banSong: banSongObj?.audioBeatMixUrl,
+    mingSong: fanSongObj?.solmizationBeatUrl
+  })
+  return musicObj
+}  
 const setState = (data: any, index: number) => {
   state.appName = "COLEXIU";
   state.detailId = data.bizId;
@@ -1227,8 +1286,6 @@ const setState = (data: any, index: number) => {
   state.isShowFingering = data.isShowFingering ? true : false;
   // 设置曲谱的播放模式, APP播放(midi音频是app播放) | h5播放
   state.isAppPlay = data.playMode === 'MIDI';
-  state.music = data.music;
-  state.accompany = data.accompany;
   state.midiUrl = data.midiFileUrl;
   state.parentCategoriesId = data.musicTag;
   state.musicSheetCategoriesId = data.musicCategoryId;

+ 2 - 0
src/store.ts

@@ -21,6 +21,8 @@ type IUser = {
   vipMember?: boolean;
   phone?: string;
   schoolInfos?: any[];
+  // 当前用户 绑定 的乐器
+  instrumentId: string 
 };
 type IStatus = "init" | "login" | "logout" | "error";
 type IPlatformType = "STUDENT" | "TEACHER" | "WEB" | "";

+ 126 - 107
src/view/audio-list/index.tsx

@@ -12,21 +12,23 @@ import state, { IPlayState, onEnded, onPlay } from "/src/state";
 import { api_playProgress, api_cloudTimeUpdae, api_cloudplayed, api_remove_cloudplayed, api_remove_cloudTimeUpdae } from "/src/helpers/communication";
 import { evaluatingData } from "/src/view/evaluating";
 import { cloudToggleState } from "/src/helpers/midiPlay"
-import { metronomeData } from "../../helpers/metronome";
-import Crunker from "../../utils/crunker"
-const crunker = new Crunker()
-import tickWav from "/src/assets/tick.mp3";
-import tockWav from "/src/assets/tock.mp3";
 import Loading from "./loading"
 
 export const audioData = reactive({
-	songEle: null as unknown as HTMLAudioElement,
-	backgroundEle: null as unknown as HTMLAudioElement,
-	songCollection: {  // 音乐源合集   beatSongEle和bateBackgroundEle是带节拍的音乐源   评测模式的时候用
-		songEle: null as unknown as HTMLAudioElement,
-		backgroundEle: null as unknown as HTMLAudioElement,
-		beatSongEle: null as unknown as HTMLAudioElement,
-		bateBackgroundEle: null as unknown as HTMLAudioElement,
+	songEle: null as HTMLAudioElement | null, // 原生
+	backgroundEle: null as HTMLAudioElement | null, //伴唱
+	mingSongEle: null as HTMLAudioElement | null, //唱名
+	songCollection: {  // 音乐源合集 带节拍器和不带节拍器的
+		songEle: null as HTMLAudioElement | null,
+		backgroundEle: null as HTMLAudioElement | null,
+		fanSongEle: null as HTMLAudioElement | null,
+		banSongEle: null as HTMLAudioElement | null,
+		mingSongEle: null as HTMLAudioElement | null,
+		beatSongEle: null as HTMLAudioElement | null,
+		betaBackgroundEle: null as HTMLAudioElement | null,
+		betaFanSongEle: null as HTMLAudioElement | null,
+		betaBanSongEle: null as HTMLAudioElement | null,
+		betaMingSongEle: null as HTMLAudioElement | null
 	},
 	midiRender: false,
 	progress: 0, // midi播放进度(单位:秒)
@@ -49,9 +51,11 @@ export const audioListStart = (type: "play" | "paused") => {
 	if (type === "play") {
 		audioData.songEle?.play();
 		audioData.backgroundEle?.play();
+		audioData.mingSongEle?.play();
 	} else if (type === "paused") {
 		audioData.songEle?.pause();
 		audioData.backgroundEle?.pause();
+		audioData.mingSongEle?.pause();
 	}
 };
 /** 设置倍数播放 */
@@ -64,6 +68,7 @@ export const setAudioPlaybackRate = (rate: number) => {
 	}
 	audioData.songEle && (audioData.songEle.playbackRate = rate);
 	audioData.backgroundEle && (audioData.backgroundEle.playbackRate = rate);
+	audioData.mingSongEle && (audioData.mingSongEle.playbackRate = rate);
 };
 
 /** 获取当前播放的时间 */
@@ -76,6 +81,7 @@ export const getAudioCurrentTime = () => {
 	// console.log('返回的时间',state.playSource, audioData.songEle?.currentTime,audioData.progress)
 	if (state.playSource === "music") return audioData.songEle?.currentTime || audioData.progress;
 	if (state.playSource === "background") return audioData.backgroundEle?.currentTime || audioData.progress;
+	if (state.playSource === "mingSong") return audioData.mingSongEle?.currentTime || audioData.progress;
 	
 	return audioData.songEle?.currentTime || audioData.progress;
 };
@@ -87,7 +93,7 @@ export const getAudioDuration = () => {
 		const songEndTime = state.times[state.times.length - 1 || 0]?.endtime || 0
 		return audioData.duration || songEndTime;
 	}
-	return audioData.songEle?.duration || audioData.backgroundEle?.duration || audioData.duration;
+	return audioData.songEle?.duration || audioData.backgroundEle?.duration || audioData.mingSongEle?.duration || audioData.duration;
 };
 
 /** 设置播放的开始时间 */
@@ -100,6 +106,7 @@ export const setAudioCurrentTime = (time: number, index = 0) => {
 	}
 	audioData.songEle && (audioData.songEle.currentTime = time);
 	audioData.backgroundEle && (audioData.backgroundEle.currentTime = time);
+	audioData.mingSongEle && (audioData.mingSongEle.currentTime = time);
 	audioData.progress = time;
 };
 
@@ -113,46 +120,55 @@ export const toggleMutePlayAudio = (source: IPlayState, muted: boolean) => {
 		if (audioData.backgroundEle) {
 			audioData.backgroundEle.muted = muted;
 		}
+	} else if(source === "mingSong"){
+		if (audioData.mingSongEle) {
+			audioData.mingSongEle.muted = muted;
+		}
 	}
 };
 
-/** 检测音源数量 */
-export const detectTheNumberOfSoundSources = () => {
-	let total = 0;
-	if (audioData.songEle) total += 1;
-	if (audioData.backgroundEle) total += 1;
-	return total;
-};
-
 /** 切换节拍器音源 */
 export const changeSongSourceByBate = (isDisBate:boolean) => {
 	// isDisBate 为true 切换到不带节拍的,为false 切换到带节拍的
-	if(audioData.songCollection.songEle && audioData.songCollection.beatSongEle){
-		const songEleCurrentTime = audioData.songEle.currentTime
-		console.log("当前音乐时间:",songEleCurrentTime)
-		if(isDisBate){
+	const songEleCurrentTime = audioData.songEle?.currentTime || 0
+	const backgroundEleCurrentTime = audioData.backgroundEle?.currentTime || 0
+	const mingSongEleCurrentTime = audioData.mingSongEle?.currentTime || 0
+	if (isDisBate) {
+		if(state.playType === "play"){
 			audioData.songEle = audioData.songCollection.songEle
-			audioData.songEle.currentTime = songEleCurrentTime
-			if(audioData.songCollection.backgroundEle){
-				audioData.backgroundEle = audioData.songCollection.backgroundEle
-				audioData.backgroundEle.currentTime = songEleCurrentTime
-			}
-		}else{
-			audioData.songEle = audioData.songCollection.beatSongEle
-			audioData.songEle.currentTime = songEleCurrentTime
-			if(audioData.songCollection.bateBackgroundEle){
-				audioData.backgroundEle = audioData.songCollection.bateBackgroundEle
-				audioData.backgroundEle.currentTime = songEleCurrentTime
-			}
+			audioData.backgroundEle = audioData.songCollection.backgroundEle
+		} else {
+			audioData.songEle = audioData.songCollection.fanSongEle
+			audioData.backgroundEle = audioData.songCollection.banSongEle
+			audioData.mingSongEle = audioData.songCollection.mingSongEle
+		}
+	} else {
+		// 没有节拍器资源的时候 用 不带节拍器的资源,防止播放不了
+		if(state.playType === "play"){
+			audioData.songEle = audioData.songCollection.beatSongEle || audioData.songCollection.songEle
+			audioData.backgroundEle = audioData.songCollection.betaBackgroundEle || audioData.songCollection.backgroundEle
+		} else {
+			audioData.songEle = audioData.songCollection.betaFanSongEle || audioData.songCollection.fanSongEle
+			audioData.backgroundEle = audioData.songCollection.betaBanSongEle || audioData.songCollection.banSongEle
+			audioData.mingSongEle = audioData.songCollection.betaMingSongEle || audioData.songCollection.mingSongEle
 		}
 	}
+	audioData.songEle && (audioData.songEle.currentTime = songEleCurrentTime)
+	audioData.backgroundEle && (audioData.backgroundEle.currentTime = backgroundEleCurrentTime)
+	audioData.mingSongEle && (audioData.mingSongEle.currentTime = mingSongEleCurrentTime)
 	// 设置静音与取消静音
 	if (state.playSource === "music") {
 		audioData.songEle && (audioData.songEle.muted = false);
 		audioData.backgroundEle && (audioData.backgroundEle.muted = true);
-	} else {
+		audioData.mingSongEle && (audioData.mingSongEle.muted = true);
+	} else if (state.playSource === "background") {
 		audioData.songEle && (audioData.songEle.muted = true);
 		audioData.backgroundEle && (audioData.backgroundEle.muted = false);
+		audioData.mingSongEle && (audioData.mingSongEle.muted = true);
+	}else {
+		audioData.songEle && (audioData.songEle.muted = true);
+		audioData.backgroundEle && (audioData.backgroundEle.muted = true);
+		audioData.mingSongEle && (audioData.mingSongEle.muted = false);
 	}
 }
 export default defineComponent({
@@ -176,9 +192,15 @@ export default defineComponent({
 				if (state.playSource === "music") {
 					audioData.songEle && (audioData.songEle.muted = false);
 					audioData.backgroundEle && (audioData.backgroundEle.muted = true);
-				} else {
+					audioData.mingSongEle && (audioData.mingSongEle.muted = true);
+				} else if (state.playSource === "background") {
 					audioData.songEle && (audioData.songEle.muted = true);
 					audioData.backgroundEle && (audioData.backgroundEle.muted = false);
+					audioData.mingSongEle && (audioData.mingSongEle.muted = true);
+				}else {
+					audioData.songEle && (audioData.songEle.muted = true);
+					audioData.backgroundEle && (audioData.backgroundEle.muted = true);
+					audioData.mingSongEle && (audioData.mingSongEle.muted = false);
 				}
 			}
 		);
@@ -203,6 +225,7 @@ export default defineComponent({
 			audioData.progress = time;
 			audioData.songEle && (audioData.songEle.currentTime = time);
 			audioData.backgroundEle && (audioData.backgroundEle.currentTime = time);
+			audioData.mingSongEle && (audioData.mingSongEle.currentTime = time);
 			audioData.duration = total / 1000;
 			if (
 				res?.content?.totalDuration > 1000 &&
@@ -245,77 +268,28 @@ export default defineComponent({
 				onEnded();
 			}
 		}
-		// 合成节拍器音源
-		function loadMergeAudioBetas() {
-			console.time("音频加载时间")
-			const audioList = [state.music+'?v='+Date.now()]
-			if(state.accompany){   // 可能存在没有伴奏的音源
-				audioList.push(state.accompany+'?v='+Date.now()) 
-			}
-			return crunker.fetchAudio(tickWav, tockWav, ...audioList).then(([tickWavBuff,tockWavBuff,musicBuff,accompanyBuff])=>{
-				console.timeEnd("音频加载时间")
-				// 计算音频空白时间
-				const silenceDuration = crunker.calculateSilenceDuration(musicBuff)
-				const silenceBgDuration = accompanyBuff && crunker.calculateSilenceDuration(accompanyBuff) 
-				console.log(`音频空白时间:${silenceDuration},${silenceBgDuration}`)
-				const beats:AudioBuffer[] = []
-				const beatsTime:number[] = []
-				const beatsBgTime:number[] = []
-				metronomeData.metroMeasure.map(Measures=>{
-					Measures.map((item:any)=>{
-						beats.push(item.index===0?tickWavBuff:tockWavBuff)
-						beatsTime.push(item.time + silenceDuration) // xml 计算的时候 加上空白的时间
-						accompanyBuff && beatsBgTime.push(item.time + silenceBgDuration) // xml 计算的时候 加上空白的时间
-					})
-				})
-				//合并
-				console.time("音频合并时间")
-				const musicBuffMeg = crunker.mergeAudioBuffers([musicBuff,...beats],[0,...beatsTime])
-				const accompanyBuffMeg = accompanyBuff && crunker.mergeAudioBuffers([accompanyBuff,...beats],[0,...beatsBgTime])
-				console.timeEnd("音频合并时间")
-				return [musicBuffMeg,accompanyBuffMeg]
-			}).then(([musicBuffMeg,accompanyBuffMeg])=>{
-				console.time("音频audioDom生成时间")
-				const musicAudio = crunker.exportAudioElement(musicBuffMeg)
-				const accompanyAudio = accompanyBuffMeg && crunker.exportAudioElement(accompanyBuffMeg)
-				console.timeEnd("音频audioDom生成时间")
-				return [musicAudio,accompanyAudio]
-			})
-		}
-		// 加载普通音源
+		// 加载音源
 		function loadAudio(){
-			return Promise.all([createAudio(state.music), createAudio(state.accompany)])
+			return Promise.all([createAudio(state.music), createAudio(state.accompany), createAudio(state.fanSong), createAudio(state.banSong), createAudio(state.mingSong)])
+		}
+		// 加载节拍器音源
+		function loadBeatAudio(){
+			return Promise.all([createAudio(state.beatSong.music), createAudio(state.beatSong.accompany), createAudio(state.beatSong.fanSong), createAudio(state.beatSong.banSong), createAudio(state.beatSong.mingSong)])
 		}
 		onMounted(async () => {
 			if (state.playMode !== "MIDI") {
-				console.time("加载资源耗时")
-				// 不带节拍的音源
-				const [music, accompany] = await loadAudio()
-				try {
-					// 带节拍的音源
-					const [musicAudio,accompanyAudio] = await loadMergeAudioBetas()
-					console.log("音频合成成功66666666")
-					state.audioBetaDone = true;
-					if (musicAudio) {
-						musicAudio.addEventListener("play", onPlay);
-						musicAudio.addEventListener("ended", onEnded);
-						accompanyAudio && (accompanyAudio.muted = true);
-					} else if (accompanyAudio) {
-						accompanyAudio.addEventListener("play", onPlay);
-						accompanyAudio.addEventListener("ended", onEnded);
-					}
-					Object.assign(audioData.songCollection,{
-						songEle:music,
-						backgroundEle:accompany,
-						beatSongEle:musicAudio,
-						bateBackgroundEle:accompanyAudio
-					})
-				} catch (err) {
-					console.log("音频合成失败7777777:",err)
-				}
-				state.audioDone = true;
-				audioData.backgroundEle = accompany!;
-				audioData.songEle = music!;
+				console.time("音频加载时间")
+				// 处理音源
+				const [music, accompany, fanSong, banSong, mingSong] = await loadAudio()
+				audioData.backgroundEle = accompany;
+				audioData.songEle = music;
+				Object.assign(audioData.songCollection, {
+					songEle:music,
+					backgroundEle:accompany,
+					fanSongEle:fanSong,
+					banSongEle:banSong,
+					mingSongEle:mingSong
+				})
 				if (music) {
 					music.addEventListener("play", onPlay);
 					music.addEventListener("ended", onEnded);
@@ -324,7 +298,52 @@ export default defineComponent({
 					accompany.addEventListener("play", onPlay);
 					accompany.addEventListener("ended", onEnded);
 				}
-				console.timeEnd("加载资源耗时")
+				if(fanSong){
+					fanSong.addEventListener("play", onPlay);
+					fanSong.addEventListener("ended", onEnded);
+					banSong && (banSong.muted = true);
+					mingSong && (mingSong.muted = true);
+				}else if(banSong){
+					banSong.addEventListener("play", onPlay);
+					banSong.addEventListener("ended", onEnded);
+					mingSong && (mingSong.muted = true);
+				} else if(mingSong){
+					mingSong.addEventListener("play", onPlay);
+					mingSong.addEventListener("ended", onEnded);
+				}
+				// 处理带节拍器的音源
+				const [beatMusic, beatAccompany, beatFanSong, beatBanSong, beatMingSong] = await loadBeatAudio()
+				Object.assign(audioData.songCollection, {
+					beatSongEle:beatMusic,
+					betaBackgroundEle:beatAccompany,
+					betaFanSongEle:beatFanSong,
+					betaBanSongEle:beatBanSong,
+					betaMingSongEle:beatMingSong
+				})
+				if (beatMusic) {
+					beatMusic.addEventListener("play", onPlay);
+					beatMusic.addEventListener("ended", onEnded);
+					beatAccompany && (beatAccompany.muted = true);
+				} else if (beatAccompany) {
+					beatAccompany.addEventListener("play", onPlay);
+					beatAccompany.addEventListener("ended", onEnded);
+				}
+				if(beatFanSong){
+					beatFanSong.addEventListener("play", onPlay);
+					beatFanSong.addEventListener("ended", onEnded);
+					beatBanSong && (beatBanSong.muted = true);
+					beatMingSong && (beatMingSong.muted = true);
+				}else if(beatBanSong){
+					beatBanSong.addEventListener("play", onPlay);
+					beatBanSong.addEventListener("ended", onEnded);
+					beatMingSong && (beatMingSong.muted = true);
+				} else if(beatMingSong){
+					beatMingSong.addEventListener("play", onPlay);
+					beatMingSong.addEventListener("ended", onEnded);
+				}
+				state.audioDone = true;
+				console.timeEnd("音频加载时间")
+				console.log("音频数据:",audioData)
 				api_playProgress(progress);
 			} else {
 				state.audioDone = true;

+ 2 - 2
src/view/evaluating/index.tsx

@@ -686,7 +686,7 @@ export default defineComponent({
 			// 如果关闭伴奏,评测静音
 			if (!record_old_data.enableAccompaniment) {
 				console.log("关闭伴奏");
-				toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : "background", true);
+				toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : record_old_data.play_mode === "background" ? "background" : "mingSong", true);
 			}
 		};
 		/** 还原状态 */
@@ -697,7 +697,7 @@ export default defineComponent({
 
 			// 如果关闭伴奏, 结束评测取消静音
 			if (!record_old_data.enableAccompaniment) {
-				toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : "background", false);
+				toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : record_old_data.play_mode === "background" ? "background" : "mingSong", false);
 			}
 		};
 

+ 12 - 0
src/view/fingering/fingering-config.ts

@@ -358,6 +358,10 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
         name: "flute",
         direction: "transverse",
         height: "1.6rem",
+        scaleData: {
+          scale: "0.8",
+          offset: "3.64rem"
+        },
         hasTizhi: true,
         id: 1,
       };
@@ -383,6 +387,10 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
         name: "trumpet",
         direction: "transverse",
         height: "1.6rem",
+        scaleData: {
+          scale: "0.8",
+          offset: "3.64rem"
+        },
         hasTizhi: false,
         id: 11,
       };
@@ -399,6 +407,10 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
         name: "trombone",
         direction: "transverse",
         height: "1.6rem",
+        scaleData: {
+          scale: "0.8",
+          offset: "3.64rem"
+        },
         hasTizhi: false,
         id: 13,
       };

+ 1 - 1
src/view/music-score/index.module.less

@@ -19,7 +19,7 @@
         #osmdCanvasPage1{
             position: absolute !important;
             left: 0;
-            top: 0;
+            top: 2.4rem;
         }
     }
     .noteActive {

+ 7 - 22
src/view/music-score/index.tsx

@@ -19,26 +19,6 @@ const musicData = reactive({
 	containerWidth: 0,
 });
 
-/** 重新计算曲谱渲染比例 */
-export const resetMusicScore = () => {
-	const contaienrWidth = document.getElementById("musicAndSelection")?.offsetWidth || 625;
-	state.musicZoom = contaienrWidth / musicData.containerWidth;
-	// if (state.fingeringInfo?.name && state.fingeringInfo?.direction === 'vertical') {
-	// 	if (contaienrWidth > musicData.containerWidth) {
-	// 		setGlobalData('wrapNum', 8)
-	// 	} else {
-	// 		setGlobalData('wrapNum', 6)
-	// 	}
-	// 	musicData.showSelection = false
-	// 	osmd.zoom = state.zoom;
-	// 	osmd.render();
-	// 	setTimeout(() => {
-	// 		musicData.showSelection = true
-	// 	}, 100);
-	// }
-	
-};
-
 /** 重新渲染曲谱 */
 export const resetRenderMusicScore = (type?: string) => {
 	const search = queryString.parse(location.search);
@@ -50,6 +30,9 @@ export const resetRenderMusicScore = (type?: string) => {
 	location.search = "?" + newSearch;
 };
 
+// 下载后的xml
+export const downloadXmlStr = ref("")
+
 export default defineComponent({
 	name: "music-score",
 	emits: ["rendered"],
@@ -82,8 +65,10 @@ export default defineComponent({
 			}
 		};
 		const getXML = async () => {
-			const res = await fetch(state.xmlUrl).then((response) => response.text());
-			const xml = formatXML(res);
+			// 当有下载的xml的时候直接使用,否则需要下载
+			const xmlStr = downloadXmlStr.value || await fetch(state.xmlUrl).then((response) => response.text());
+			downloadXmlStr.value = "" // 清空内存
+			const xml = formatXML(xmlStr);
 			musicData.score = state.isCombineRender ? xml : onlyVisible(xml, state.partIndex);
 			if (state.gradualTimes) {
 				state.gradual = getGradualLengthByXml(xml);

+ 0 - 7
src/view/music-score/testCheck.tsx

@@ -19,13 +19,6 @@ const musicData = reactive({
 	containerWidth: 0,
 });
 
-/** 重新计算曲谱渲染比例 */
-export const resetMusicScore = () => {
-	const contaienrWidth = document.getElementById("musicAndSelection")?.offsetWidth || 625;
-	state.musicZoom = contaienrWidth / musicData.containerWidth;
-	
-};
-
 /** 重新渲染曲谱 */
 export const resetRenderMusicScore = (type?: string) => {
 	const search = queryString.parse(location.search);

+ 1 - 1
src/view/selection/index.tsx

@@ -223,7 +223,7 @@ export default defineComponent({
 			calcNoteData();
 			// 初始化谱面可移动的元素位置
 			try {
-			moveData.partIndex = query['part-index'] as string || '0'
+			moveData.partIndex = state.partIndex + ""
 			nextTick(() => renderForMoveData())
 			} catch (error) {}
 		});

+ 16 - 3
src/view/transfer-to-img/index.tsx

@@ -6,7 +6,8 @@ import { getQuery } from "/src/utils/queryString";
 import { closeToast, showLoadingToast } from "vant";
 import { svg2canvas } from "/src/utils/svg2canvas";
 import { moveGracePosition } from "/src/helpers/customMusicScore"
-
+import { formateTimes } from "../../helpers/formateMusic";
+import Metronome, { metronomeData } from "../../helpers/metronome";
 export default defineComponent({
 	name: "transfer-to-img",
 	setup() {
@@ -22,6 +23,7 @@ export default defineComponent({
 					name: "五线谱",
 					type: EnumMusicRenderType.staff,
 					base64: "" as any,
+					beatTime: [] as number[][]
 				},
 				{
 					state: false,
@@ -56,7 +58,7 @@ export default defineComponent({
 		});
 
 		/** 渲染完成 */
-		const handleRendered = async () => {
+		const handleRendered = async (osmd: any) => {
 			if (document.getElementById('scrollContainer')) {
 				moveGracePosition(detailData.isSpecialXml);
 			}
@@ -80,7 +82,8 @@ export default defineComponent({
 				});
 				return;
 			}
-
+			// 获取节拍器时间并赋值
+			handleBateTIme(osmd)
 			closeToast();
 			console.log(detailData.product,123456);
 			window.parent?.postMessage(
@@ -119,6 +122,16 @@ export default defineComponent({
 			});
 		};
 
+		function handleBateTIme (osmd: any){
+			const times = formateTimes(osmd)
+			const metronome = new Metronome()
+			metronome.init(times)
+			detailData.product[0].beatTime = metronomeData.metroMeasure.map(metroMeasure => {
+				return metroMeasure.map((item: any) => {
+					return item.time
+				})
+			})
+		}
 		return () => (
 			<div class={styles.detail}>
 				<div id="scrollContainer" class={[styles.container, "hideCursor"]}>

+ 3 - 3
vite.config.ts

@@ -76,9 +76,9 @@ export default defineConfig({
         // target: "https://kt.colexiu.com",
         // target: "https://test.lexiaoya.cn",
         // target: "https://kt.colexiu.com",
-        // target: "https://test.resource.colexiu.com", // 内容平台开发环境,内容平台开发,需在url链接上加上isCbs=true
-        // target: "https://dev.resource.colexiu.com",
-        target: "https://test.kt.colexiu.com",
+        //target: "https://test.resource.colexiu.com", // 内容平台开发环境,内容平台开发,需在url链接上加上isCbs=true
+        //target: "https://dev.resource.colexiu.com",
+        target: "https://dev.kt.colexiu.com",
         //target: "https://mec.colexiu.com",
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/instrument/, ""),