瀏覽代碼

Merge branch 'feature-tianyong-newVersion' into ktyq-online-new

TIANYONG 7 月之前
父節點
當前提交
278faff161

+ 1 - 1
osmd-extended

@@ -1 +1 @@
-Subproject commit a9aa056f79fb3aa710a6586b2064241a6636bc1c
+Subproject commit 4a585d167cdf26911b7aa5358e97e8a3e19ff195

+ 12 - 3
src/helpers/formateMusic.ts

@@ -1390,7 +1390,9 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 			// 	usetime = usetime + state.secondEvXmlBeginTime;
 			// 	relativeTime = relativeTime + state.secondEvXmlBeginTime;
 			// }
-			if (state.isEvxml && nodeDetail.repeatIdx && nodeDetail.i > 0 && nodeDetail.MeasureNumberXML === 1 && nodeDetail.noteId === 0) {
+			// if (state.isEvxml && nodeDetail.repeatIdx && nodeDetail.i > 0 && nodeDetail.MeasureNumberXML === 1 && nodeDetail.noteId === 0) {
+			const firstRepeatNodeId = allNotes.find((item: any) => item.MeasureNumberXML === state.timegapRepeatMeasureIndex)?.noteId || 0;
+			if (state.isEvxml && nodeDetail.repeatIdx && nodeDetail.i > 0 && nodeDetail.MeasureNumberXML === state.timegapRepeatMeasureIndex && nodeDetail.noteId === firstRepeatNodeId) {
 				const currentWaitTime = state.evXmlBeginArr[nodeDetail.repeatIdx] || 0;
 				nodeDetail.time = nodeDetail.time + currentWaitTime;
 				nodeDetail.endtime = nodeDetail.endtime + currentWaitTime;
@@ -1654,8 +1656,15 @@ const analyzeEvxml = (xmlParse: any, xmlUrl?: string) => {
 		const hasTimes = xmlParse.getElementsByTagName("times").length > 0;
 		if (timeGaps && timeGaps.length && !firstNoteBeginTime) {
 			// 有timegap的曲子,需要找到是从哪一小节开始循环的,默认是从第一节开始循环
-			// const startRepeat = Array.from(xmlParse.getElementsByTagName("repeat") || []).filter((item: any) => item?.getAttribute('direction') === 'forward')
-			// state.timegapRepeatMeasureIndex = startRepeat ? 2 : 1;
+			const startRepeat = Array.from(xmlParse.getElementsByTagName("repeat") || []).filter((item: any) => item?.getAttribute('direction') === 'forward')
+			const firstRepeat: any = startRepeat?.length ? startRepeat[0] : null;
+			if (firstRepeat) {
+				let parentElement = firstRepeat?.parentNode
+				while (parentElement && parentElement.tagName !== 'measure') {
+					parentElement = parentElement.parentNode
+				}
+				state.timegapRepeatMeasureIndex = parentElement?.getAttribute('number') ? Number(parentElement?.getAttribute('number')) : 1;
+			}
 			for (const timeGap of timeGaps) {
 				const num: any = timeGap?.getAttribute('num'), den: any = timeGap?.getAttribute('den');
 				const startTime = num ? 60 / state.originSpeed * num * 4/den : 0;

+ 2 - 2
src/page-instrument/header-top/speed/index.module.less

@@ -168,7 +168,6 @@
             .speedSel{
                 margin-top: 20px;
                 padding-bottom: 18px;
-                border-bottom: 1px solid #D5E0ED;
                 display: flex;
                 justify-content: space-between;
                 & > div{
@@ -191,7 +190,8 @@
                 pointer-events: none;
             }
             .metronome{
-                margin-top: 18px;
+                padding-top: 18px;
+                border-top: 1px solid #D5E0ED;
                 display: flex;
                 justify-content: space-between;
                 align-items: center;

+ 12 - 9
src/page-instrument/header-top/speed/index.tsx

@@ -136,15 +136,18 @@ export default defineComponent({
 							<div onClick={()=>{ speed.value = 100 }}>100</div>
 							<div onClick={()=>{ speed.value = 110 }}>110</div>
 						</div>
-						<div class={styles.metronome}>
-							<div class={styles.tit}>节拍器</div>
-							<Switch 
-								class={switchLoading.value ? styles.switchLoading : ''}
-								v-model:modelValue={metronomeDisable.value} 
-								loading={switchLoading.value}
-								onChange={toggleSwitch}			
-							></Switch>
-						</div>
+						{
+							state.isMixBeat && 
+							<div class={styles.metronome}>
+								<div class={styles.tit}>节拍器</div>
+								<Switch 
+									class={switchLoading.value ? styles.switchLoading : ''}
+									v-model:modelValue={metronomeDisable.value} 
+									loading={switchLoading.value}
+									onChange={toggleSwitch}			
+								></Switch>
+							</div>
+						}
 					</div>
 				</div>
 			</div>

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

@@ -299,7 +299,7 @@ export default defineComponent({
        * 设置节拍器,跟练需要播放系统节拍器,所以不需要判断needTick状态
        */
       // if (state.needTick) {
-      handleInitTick(osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4);
+      handleInitTick(osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4, osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.denominator);
       // }
       // api_cloudLoading();
       // state.playBtnDirection = query.imagePos === 'left' ? 'left' : 'right';

+ 26 - 16
src/state.ts

@@ -370,6 +370,8 @@ const state = reactive({
   needTick: false,
   /** 演唱模式是否需要节拍器 */
   needSingTick: false,
+  /** 是否能使用节拍器  */
+  isMixBeat: true,
   /** 曲谱实例 */
   osmd: null as unknown as OpenSheetMusicDisplay,
   /**是否是特殊乐谱类型, 主要针对管乐迷  */
@@ -649,7 +651,7 @@ export const onEnded = () => {
 // 根据当前小节动态设置,右上角展示的速度
 const dynamicShowPlaySpeed = (index: number) => {
   if (!headerColumnHide.value) {
-    console.log('动态计算速度')
+    // console.log('动态计算速度')
     const item: any = state.times[index];
     if (item && item.measureSpeed ) {
       // console.log('速度1',item.measureSpeed)
@@ -1108,9 +1110,12 @@ export const handleResetPlay = () => {
     audioData.progress = 0
   }
   // 如果是作业模式,不还原速度
-  if (!query.workRecord) {
-    resetBaseRate();
-  }
+  /**
+   * #TODO:2024.09.14,业务需求变更,重播不还原用户设置的速度
+   */
+  // if (!query.workRecord) {
+  //   resetBaseRate();
+  // }
   resetPlaybackToStart();
   // 如果是暂停, 直接播放
   togglePlay("play");
@@ -1356,6 +1361,8 @@ const getMusicInfo = async (res: any) => {
   state.isScoreRender = res.data?.isScoreRender
   // 是否默认显示总谱
   state.defaultScoreRender = res.data?.defaultScoreRender
+  // 是否显示节拍器
+  state.isMixBeat = res.data?.isMixBeat
   let partIndex = query["part-index"] ? parseInt(query["part-index"]) : -1 // -1为partIndex没有值的时候
   // 如果是评测报告,会有默认的分轨index
   if (state.isEvaluatReport) {
@@ -1506,18 +1513,21 @@ function initMusicSource(data: any, tracks: string[], partIndex: number, workRec
     state.mingSong = fanSongObj?.solmizationFileUrl
     state.mingSongGirl = fanSongObj?.femaleSolmizationFileUrl
   }
-  Object.assign(state.beatSong, {
-    music: musicObj?.audioBeatMixUrl,
-    accompany: accompanyObj?.audioBeatMixUrl,
-    fanSong: fanSongObj?.audioBeatMixUrl,
-    banSong: banSongObj?.audioBeatMixUrl
-  })
-  // 如果没有男唱名
-  if(!fanSongObj?.solmizationBeatUrl){
-    state.beatSong.mingSong = fanSongObj?.femaleSolmizationBeatUrl
-  }else{
-    state.beatSong.mingSong = fanSongObj?.solmizationBeatUrl
-    state.beatSong.mingSongGirl = fanSongObj?.femaleSolmizationBeatUrl
+  // 当使用节拍器的时候才加载节拍器音频
+  if(state.isMixBeat) {
+    Object.assign(state.beatSong, {
+      music: musicObj?.audioBeatMixUrl,
+      accompany: accompanyObj?.audioBeatMixUrl,
+      fanSong: fanSongObj?.audioBeatMixUrl,
+      banSong: banSongObj?.audioBeatMixUrl
+    })
+    // 如果没有男唱名
+    if(!fanSongObj?.solmizationBeatUrl){
+      state.beatSong.mingSong = fanSongObj?.femaleSolmizationBeatUrl
+    }else{
+      state.beatSong.mingSong = fanSongObj?.solmizationBeatUrl
+      state.beatSong.mingSongGirl = fanSongObj?.femaleSolmizationBeatUrl
+    }
   }
   return {
     index,

+ 5 - 3
src/view/tick/index.tsx

@@ -10,6 +10,7 @@ import tockWav from "/src/assets/tock.mp3";
 
 const tickData = reactive({
 	len: 0,
+	denominator: undefined as undefined | number,
 	reduceLen: 0,
 	tickEnd: false,
 	/** 节拍器时间 */
@@ -95,9 +96,11 @@ const createAudio = (src: string): Promise<HTMLAudioElement | null> => {
 
 /** 设置节拍器
  * @param beat 节拍数
+ * @param denominator 节拍器分母
  */
-export const handleInitTick = (beat: number) => {
+export const handleInitTick = (beat: number, denominator?: number) => {
 	tickData.len = beat;
+	tickData.denominator = denominator;
 	// 节拍器的个数除以2 直到小于等于4为止 
 	while (beat > 4 && beat % 2 === 0) {
         beat = beat / 2;
@@ -111,8 +114,7 @@ export const handleStartTick = async () => {
 	tickData.show = true;
 	tickData.tickEnd = false;
 	tickData.index = 0;
-	// tickData.beatLengthInMilliseconds = (60 / state.speed) * 1000;
-	tickData.beatLengthInMilliseconds = (state.times[0].xmlMp3BeatFixTime * 1000) / tickData.len || (60 / state.speed) * 1000;
+	tickData.beatLengthInMilliseconds = tickData.denominator ? 4 / tickData.denominator * (60 / state.speed) * 1000 : (60 / state.speed) * 1000;
 	for(let i = 0; i <= useLen.value; i++){
 		// 提前结束, 直接放回false
 		if (tickData.tickEnd) return false;