Browse Source

feat: 评测选段、评测调速1.0

TIANYONG 11 tháng trước cách đây
mục cha
commit
19413b0cba

+ 23 - 7
src/helpers/formateMusic.ts

@@ -623,7 +623,30 @@ export const formatXML = (xml: string, xmlUrl?: string): string => {
 	if (!xml) return "";
 	
 	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+
 	const measures = Array.from(xmlParse.getElementsByTagName("measure"));
+	const minutes: any = xmlParse.getElementsByTagName("per-minute");
+	let speeds: any = []
+	for (const minute of minutes) {
+		if (minute.textContent && !!Number(minute.textContent)) {
+			speeds.push(Number(minute.textContent))
+		}
+	}
+	speeds = [...new Set(speeds)]
+	const hasVaryingSpeed = speeds.length > 1 ? true : false
+  // 如果后台没有设置速度,默认取xml速度,如果xml也没有速度,默认赋值100
+	if (state.originSpeed === 0) {
+		state.originSpeed = speeds[0] ? speeds[0] : 100;
+		state.speed = state.originSpeed;
+	}
+	// 如果谱面和小节都没有打速度,osmd设置的小节速度默认取后台设置的速度
+	if (speeds.length === 0) {
+		;(window as any).baseMeasureSpeed = state.originSpeed
+	} else {
+		state.originAudioPlayRate = speeds[0] / state.originSpeed
+	}
+	console.log('是否是变速的曲子:',hasVaryingSpeed,speeds)
+
 	const repeats: any = Array.from(xmlParse.querySelectorAll('repeat'));
 	compatibleXmlPitchVoice(xmlParse);
 	// 获取作词、作曲家
@@ -705,13 +728,6 @@ export const formatXML = (xml: string, xmlUrl?: string): string => {
         </note>`;
 		}
 	}
-	// 如果曲谱详情接口没有返回速度,则取xml第一小节的速度,如果取不到,则取默认速度:100
-	if (!speed || speed == -1) {
-		speed = 100
-	}
-	if (!state.originSpeed) {
-		state.originSpeed = state.speed = speed || 100
-	}
 	return new XMLSerializer().serializeToString(xmlParse);
 };
 

+ 1 - 1
src/helpers/metronome.ts

@@ -199,7 +199,7 @@ class Metronome {
 				return
 			}			
 		}
-		console.log("播放自带的节拍器 233333")
+		// 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;

+ 2 - 2
src/page-instrument/header-top/index.tsx

@@ -78,7 +78,7 @@ export const headTopData = reactive({
       state.playIngSpeed = state.originSpeed;
       handleStartEvaluat();
       // 开发模式,把此处打开
-      state.modeType = "evaluating"
+      // state.modeType = "evaluating"
       // evaluatingData.rendered = true;
       // evaluatingData.soundEffectMode = true;
     } else if (value === "follow") {
@@ -328,7 +328,7 @@ export default defineComponent({
     /** 选段按钮 */
     const selectBtn = computed(() => {
       // 选择模式 不显示
-      if (headTopData.modeType !== "show" || ["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
+      if (headTopData.modeType !== "show" || ["follow"].includes(state.modeType)) return { display: false, disabled: true };
       // 音频播放中 禁用
       if (state.playState === "play") return { display: true, disabled: true };
 

+ 8 - 0
src/page-instrument/header-top/speed/index.tsx

@@ -24,6 +24,14 @@ export default defineComponent({
 				handleSetSpeed(speed.value);
 			}
 		);
+		watch(
+			() => state.speed,
+			() => {
+				if (speed.value !== state.speed) {
+					speed.value = state.speed;
+				}
+			}
+		);
 		const metronomeDisable = computed({
 			get(){
 				return !metronomeData.disable

+ 5 - 5
src/page-instrument/view-detail/index.tsx

@@ -171,11 +171,11 @@ export default defineComponent({
       if (state.originSpeed === 0) {
         state.originSpeed = state.speed = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM || 100;
       }
-      const saveSpeed = (store.get("speeds") || {})[state.examSongId] || state.speed || (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
-      // 加载本地缓存的速度
-      if (saveSpeed) {
-        handleSetSpeed(saveSpeed);
-      }
+      // const saveSpeed = (store.get("speeds") || {})[state.examSongId] || state.speed || (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
+      // // 加载本地缓存的速度
+      // if (saveSpeed) {
+      //   handleSetSpeed(saveSpeed);
+      // }
       setCustomGradual();
 			setCustomNoteRealValue();
       state.times = formateTimes(osmd);

+ 41 - 11
src/state.ts

@@ -504,6 +504,10 @@ const state = reactive({
   loadingText: '音频资源加载中,请稍后…',
   /** 是否是简单的单行谱模式页面 */
   isSimplePage: false, 
+  /** xml的速度和后台设置的速度,计算出的基础音频播放倍率 */
+  originAudioPlayRate: 1,  
+  /** 开始播放时,记录的mp3播放倍率,用户当前设置的速度/当前小节的速度 */
+  basePlayRate: 1,
 });
 const browserInfo = browser();
 let offset_duration = 0;
@@ -579,6 +583,35 @@ export const onEnded = () => {
   autoResetPlay();
 };
 
+// 根据当前小节动态设置,右上角展示的速度
+const dynamicShowPlaySpeed = (index: number) => {
+  const item: any = state.times[index];
+  if (item && item.measureSpeed ) {
+    state.playIngSpeed = Math.floor(state.basePlayRate * item.measureSpeed)
+    state.speed = state.playIngSpeed
+  }
+}
+
+// 开始播放时,计算mp3的播放倍率
+export const initSetPlayRate = () => {
+  const item: any = (state.sectionStatus && state.section.length === 2) ? state.sectionFirst || state.section[0] : state.times[state.activeNoteIndex];
+  if (item && item.measureSpeed) {
+    const ratio = state.speed / item.measureSpeed
+    // state.audiosInstance?.setSpeed(ratio)
+    state.basePlayRate = ratio || 1;
+    console.log('播放倍率',state.basePlayRate)
+  }
+}
+
+// 重置播放倍率
+export const resetBaseRate = () => {
+  const currentItem: any = state.times[0];
+  const currentSpeed = currentItem?.measureSpeed ? currentItem.measureSpeed : state.originSpeed;
+  state.speed = currentSpeed
+  //state.activeNoteIndex = 0
+  state.basePlayRate = 1;
+}
+
 /**
  * 播放一直触发的事件
  */
@@ -587,17 +620,8 @@ const handlePlaying = () => {
   const duration = getAudioDuration();
   state.playProgress = (currentTime / duration) * 100;
   let item = getNote(currentTime);
-  // console.log(11111,currentTime,duration,state.playSource, item)
-  // console.log(item?.i,item?.noteId,item?.measureSpeed,'播放')
-  // 练习模式下,实时刷新小节速度
-  if (item && state.modeType === "practise" && state.playState === "play" && item.measureSpeed && item.measureSpeed !== state.playIngSpeed) {
-    const ratio = state.speed / state.originSpeed
-    state.playIngSpeed = Math.ceil(ratio * item.measureSpeed) || state.speed
-  } else if (state.modeType === "practise" && state.playState === "play" && item && !item.measureSpeed) {
-    state.playIngSpeed = state.speed
-  }
-  state.playIngSpeed = state.playIngSpeed || state.speed;
   if (item) {
+    dynamicShowPlaySpeed(item.i);
     // 选段状态下
     if (state.sectionStatus && state.section.length === 2) {
       // 如果开启了预备拍
@@ -669,6 +693,10 @@ export const skipNotePlay = async (itemIndex: number, isStart = false) => {
     itemTime = 0;
   }
   if (item) {
+    // 非选段模式,点击音符,动态设置右下角的速度
+    if (item.measureSpeed && state.section.length < 2) {
+      state.speed = Math.floor(state.basePlayRate * item.measureSpeed)
+    }
     setAudioCurrentTime(itemTime, itemIndex);
     // 一行谱,点击音符,或者播放完成,需要跳转音符位置
     gotoNext(item, true);
@@ -752,6 +780,7 @@ export const togglePlay = async (playState?: "play" | "paused", sourceType?: str
       clearSelection();
     }
   }
+  initSetPlayRate();
   audioListStart(state.playState);
   return true;
 };
@@ -994,13 +1023,14 @@ export const handleResetPlay = () => {
   if (state.isAppPlay) {
     audioData.progress = 0
   }
+  resetBaseRate();
   resetPlaybackToStart();
   // 如果是暂停, 直接播放
   togglePlay("play");
 };
 /** 设置速度 */
 export const handleSetSpeed = (speed: number) => {
-  setStorageSpeed(state.examSongId, speed);
+  // setStorageSpeed(state.examSongId, speed);
   state.speed = speed;
 };
 /** 清除选段状态 */

+ 1 - 0
src/utils/index.ts

@@ -97,6 +97,7 @@ export const setStorageSpeed = (id: any, speed: number) => {
 /** 获取曲谱速度 */
 export const getStorageSpeed = (id: any) => {
 	const speeds = store.get(SPEEDKEY) || {}
+	console.log('初始速度', speeds)
 	return speeds[id] || 0
 }
 

+ 3 - 1
src/view/audio-list/index.tsx

@@ -39,7 +39,9 @@ const midiRef = ref();
 export const audioListStart = (type: "play" | "paused") => {
 	// 开始播放之前, 先设置倍数
 	if (type === "play" && state.originSpeed !== 0) {
-		setAudioPlaybackRate(state.speed / state.originSpeed);
+		const actualRate = state.originAudioPlayRate * state.basePlayRate;
+		// console.log('音频播放倍率',actualRate)
+		setAudioPlaybackRate(actualRate);
 	}
 	// console.log('api','midi状态1',type,state.isAppPlay)
 	// 如果是midi播放

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

@@ -30,7 +30,7 @@
         }
         transform-box: fill-box;
         transform-origin: center;
-        animation: noteAnimate 0.3s linear;
+        // animation: noteAnimate 0.3s linear;
         // transform: scale(2);
         // transition: all 0.3s;
     }