Pārlūkot izejas kodu

设备延迟检测

liushengqiang 2 gadi atpakaļ
vecāks
revīzija
897474b7df

+ 32 - 0
src/helpers/communication.ts

@@ -217,3 +217,35 @@ export const api_endCapture = () => {
 		api: "endCapture",
 	});
 };
+
+/** 获取设备延迟检测 */
+export const api_getDeviceDelay = () => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "getDeviceDelay" });
+};
+
+/** 延迟检测触发 */
+export const api_toggleTune = (state: "start" | "stop" | "finishTune", count?: number) => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	if (state === "start") {
+		// 开始效音
+		return promisefiyPostMessage({
+			api: "startTune",
+			content: {
+				count: count + "",
+			},
+		});
+	} else if (state === "stop") {
+		// 结束效音,触发时机: 1.监听后台效音返回 2.点击跳过效音或关闭效音
+		return promisefiyPostMessage({ api: "endTune" });
+	} else if (state === "finishTune") {
+		// 效音完成
+		return promisefiyPostMessage({ api: "finishTune" });
+	}
+};
+
+/** 初始化曲谱音频 和效音音频 */
+export const api_createMusicPlayer = (content: any) => {
+	if (!storeData.isApp) return Promise.resolve({} as any);
+	return promisefiyPostMessage({ api: "createMusicPlayer", content });
+};

+ 0 - 0
src/page-instrument/evaluat-model/delay-check/index.module.less


+ 56 - 0
src/page-instrument/evaluat-model/delay-check/index.tsx

@@ -0,0 +1,56 @@
+import { Button, Popup } from "vant";
+import { defineComponent, onMounted, onUnmounted, reactive } from "vue";
+import { api_toggleTune, removeResult, sendResult } from "/src/helpers/communication";
+
+export default defineComponent({
+	name: "delay-check",
+	setup() {
+		const data = reactive({
+			show: false,
+			/** 检测状态 */
+			checkStatus: "init" as "init" | "ing" | "error",
+			count: 0,
+		});
+		const listenerResult = () => {
+			if (data.checkStatus !== "ing") return;
+			data.count++;
+			if (data.count >= 2) {
+				toggleTune("finishTune");
+				return;
+			}
+			setTimeout(() => {
+				toggleTune("start");
+			}, 100);
+		};
+		onMounted(() => {
+			data.show = true;
+			sendResult(listenerResult);
+		});
+		onUnmounted(() => {
+			removeResult(listenerResult);
+		});
+
+		const toggleTune = async (state: "start" | "stop" | "finishTune") => {
+			await api_toggleTune(state, data.count);
+		};
+		return () => (
+			<Popup
+				teleport="body"
+				closeOnClickOverlay={false}
+				class={["popup-custom"]}
+				transition="van-fade"
+				v-model:show={data.show}
+			>
+				<Button
+					disabled={data.checkStatus !== "init"}
+					onClick={() => {
+						data.checkStatus = "ing";
+						toggleTune("start");
+					}}
+				>
+					开始检测
+				</Button>
+			</Popup>
+		);
+	},
+});

+ 5 - 2
src/page-instrument/evaluat-model/index.tsx

@@ -27,6 +27,7 @@ import startingData from "./data/starting.json";
 import iconTastBg from "./icons/task-bg.svg";
 import iconEvaluat from "./icons/evaluating.json";
 import { api_musicPracticeRecordVideoUpload } from "../api";
+import DelayCheck from "./delay-check";
 
 // frequency 频率, amplitude 振幅, decibels 分贝
 type TCriteria = "frequency" | "amplitude" | "decibels";
@@ -258,6 +259,8 @@ export default defineComponent({
 					<Vue3Lottie class={styles.dialogueIcon} animationData={startingData}></Vue3Lottie>
 				</div>
 
+				{evaluatingData.soundEffectMode && <DelayCheck />}
+
 				<Popup
 					teleport="body"
 					closeOnClickOverlay={false}
@@ -272,7 +275,7 @@ export default defineComponent({
 						}}
 					/>
 				</Popup>
-				<Popup
+				{/* <Popup
 					teleport="body"
 					closeOnClickOverlay={false}
 					class={["popup-custom", "van-scale"]}
@@ -289,7 +292,7 @@ export default defineComponent({
 							handlePerformDetection();
 						}}
 					/>
-				</Popup>
+				</Popup> */}
 
 				<Popup
 					teleport="body"

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

@@ -15,6 +15,7 @@ import { formateTimes } from "../../helpers/formateMusic";
 import Metronome, { metronomeData } from "../../helpers/metronome";
 import state, {
 	EnumMusicRenderType,
+	evaluatCreateMusicPlayer,
 	handleSetSpeed,
 	IAudioState,
 	IPlatform,
@@ -223,6 +224,8 @@ export default defineComponent({
 			api_cloudLoading();
 
 			state.musicRendered = true;
+
+			evaluatCreateMusicPlayer();
 		};
 		/** 指法配置 */
 		const fingerConfig = computed<any>(() => {

+ 35 - 21
src/state.ts

@@ -6,9 +6,16 @@ import { GradualNote, GradualTimes, GradualVersion } from "./type";
 import { handleEndEvaluat, handleStartEvaluat } from "./view/evaluating";
 import { IFingering } from "src/view/fingering/fingering-config";
 import { handleStartTick } from "./view/tick";
-import { audioListStart, getAudioCurrentTime, getAudioDuration, setAudioCurrentTime, setAudioPlaybackRate } from "./view/audio-list";
+import {
+	audioListStart,
+	getAudioCurrentTime,
+	getAudioDuration,
+	setAudioCurrentTime,
+	setAudioPlaybackRate,
+} from "./view/audio-list";
 import { toggleFollow } from "./view/follow-practice";
 import { browser, setStorageSpeed } from "./utils";
+import { api_createMusicPlayer } from "./helpers/communication";
 
 /** 入门 | 进阶 | 大师 */
 export type IDifficulty = "BEGINNER" | "ADVANCED" | "PERFORMER";
@@ -19,23 +26,23 @@ export enum EnumMusicRenderType {
 	/** 简谱 */
 	firstTone = "firstTone",
 	/** 固定音高 */
-	fixedTone = "fixedTone"
+	fixedTone = "fixedTone",
 }
 export const musicscoresettingKey = "musicscoresetting";
 /** 有声音的是那个音源 */
-export type IPlayState = "music" | "background"
+export type IPlayState = "music" | "background";
 /** 播放状态 */
-export type IAudioState = "play" | "paused"
+export type IAudioState = "play" | "paused";
 
 /** 来源 */
 export enum IPlatform {
 	APP = "APP",
-	PC = "PC"
+	PC = "PC",
 }
 
 const state = reactive({
 	/** 来源 : PC , app */
-	platform: '' as IPlatform,
+	platform: "" as IPlatform,
 	appName: "" as "GYM" | "COLEXIU",
 	musicRenderType: EnumMusicRenderType.staff as EnumMusicRenderType,
 	/**曲谱是否渲染完成 */
@@ -172,17 +179,17 @@ const state = reactive({
 	/** 练习,评测是否是选段模式 */
 	isSelectMeasureMode: false,
 	/** 是否是评分显示 */
-	isReport: false
+	isReport: false,
 });
-const browserInfo = browser()
-let offset_duration = 0
+const browserInfo = browser();
+let offset_duration = 0;
 /** 自定义数据 */
 export const customData = reactive({
 	/** 自定义音符时值 */
 	customNoteRealValue: [] as any,
 	/** 自定义音符按读取到的时值 */
-	customNoteCurrentTime: false
-})
+	customNoteCurrentTime: false,
+});
 /** 在渲染前后计算光标应该走到的音符 */
 const setStep = () => {
 	if (state.playState !== "play") {
@@ -200,16 +207,15 @@ const setStep = () => {
 			setTimeout(() => {
 				handlePlaying();
 				setStep();
-			}, 16.7)
+			}, 16.7);
 		}
-		
 	});
 };
 /** 开始播放 */
 export const onPlay = () => {
 	console.log("开始播放");
 	state.playEnd = false;
-	offset_duration = browserInfo.xiaomi ? 0.2 : 0.08
+	offset_duration = browserInfo.xiaomi ? 0.2 : 0.08;
 	setStep();
 };
 
@@ -254,7 +260,7 @@ const handlePlaying = () => {
 			// 如果开启了预备拍
 			const selectStartItem = state.sectionFirst ? state.sectionFirst : state.section[0];
 			const selectEndItem = state.section[1];
-				
+
 			if (Math.abs(selectEndItem.endtime - currentTime) < offset_duration) {
 				console.log("选段播放结束");
 				// 如果为选段评测模式
@@ -388,11 +394,11 @@ export const getNote = (currentTime: number) => {
 export const handleResetPlay = () => {
 	resetPlaybackToStart();
 	// 如果是暂停, 直接播放
-	togglePlay('play')
+	togglePlay("play");
 };
 /** 设置速度 */
 export const handleSetSpeed = (speed: number) => {
-	setStorageSpeed(state.examSongId, speed)
+	setStorageSpeed(state.examSongId, speed);
 	state.speed = speed;
 };
 /** 清除选段状态 */
@@ -406,7 +412,7 @@ export const clearSelection = () => {
 export const handleChangeSection = () => {
 	// 如果开启了选段,再次点击取消选段
 	if (state.sectionStatus) {
-		togglePlay('paused')
+		togglePlay("paused");
 		skipNotePlay(0, true);
 		clearSelection();
 		return;
@@ -421,7 +427,7 @@ export const handleChangeSection = () => {
 		duration: 0,
 		position: "top",
 		className: "selectionToast",
-	})
+	});
 };
 
 /** 效验并格式化选段小节 */
@@ -466,7 +472,7 @@ export const handleSelection = (item: any) => {
 			duration: 0,
 			position: "top",
 			className: "selectionToast",
-		})
+		});
 	}
 };
 
@@ -489,7 +495,7 @@ export const scrollViewNote = () => {
 	offsetTop = cursorElement.offsetTop;
 	if (offsetTop > 50) {
 		musicAndSelection.scrollTo({
-			top: (offsetTop - 50) * state.musicZoom ,
+			top: (offsetTop - 50) * state.musicZoom,
 			behavior: "smooth",
 		});
 	} else {
@@ -516,3 +522,11 @@ export const handleRessetState = () => {
 	}
 };
 export default state;
+
+/** 初始化评测音频 */
+export const evaluatCreateMusicPlayer = () => {
+	return api_createMusicPlayer({
+		musicSrc: state.accompany || state.music, // 曲谱音频url
+		tuneSrc: "https://cloud-coach.ks3-cn-beijing.ksyuncs.com/1686725501654check_music1_(1).mp3", //效音音频url
+	});
+};

+ 58 - 23
src/view/evaluating/index.tsx

@@ -20,8 +20,15 @@ import {
 	api_remove_recordStartTime,
 	api_startCapture,
 	api_endCapture,
+	api_getDeviceDelay,
 } from "/src/helpers/communication";
-import state, { IPlayState, clearSelection, handleStopPlay, resetPlaybackToStart, togglePlay } from "/src/state";
+import state, {
+	IPlayState,
+	clearSelection,
+	handleStopPlay,
+	resetPlaybackToStart,
+	togglePlay,
+} from "/src/state";
 import { IPostMessage } from "/src/utils/native-message";
 import { usePageVisibility } from "@vant/use";
 import { browser } from "/src/utils";
@@ -136,31 +143,48 @@ export const connectWebsocket = async (content: any) => {
 export const handlePerformDetection = async () => {
 	// 检测完成不检测了
 	if (evaluatingData.checkEnd) return;
+	// 延迟检测
 	if (evaluatingData.checkStep === 0) {
-		// 检测耳机
-		const erji = await checkUseEarphone();
-		evaluatingData.checkStep = 1;
-		if (erji) {
-			handlePerformDetection();
-		} else {
-			evaluatingData.earphoneMode = true;
+		evaluatingData.checkStep = 5;
+		// 没有设备延迟数据 或 开启了效音 显示检测组件,并持续检测耳机状态
+		if (state.setting.soundEffect){
+			evaluatingData.soundEffectMode = true
+			return
 		}
-		return;
+		const delayTime = await api_getDeviceDelay()
+		console.log("🚀 ~ delayTime:", delayTime)
+		if (!delayTime){
+			evaluatingData.soundEffectMode = true
+			return
+		}
+		handlePerformDetection();
+		return
 	}
-	if (evaluatingData.checkStep === 1) {
-		// 效音
-		// 是否需要开启效音
+	// 检测耳机
+	if ((evaluatingData.checkStep = 5)) {
 		evaluatingData.checkStep = 10;
-		if (state.setting.soundEffect && !state.isPercussion) {
-			evaluatingData.soundEffectMode = true;
-			handleStartSoundCheck();
-		} else {
-			handlePerformDetection();
+		const erji = await checkUseEarphone();
+		if (!erji){
+			evaluatingData.earphoneMode = true;
+			return
 		}
+		handlePerformDetection();
 		return;
 	}
+	// 效音
+	// if (evaluatingData.checkStep === 7) {
+	// 	// 是否需要开启效音
+	// 	evaluatingData.checkStep = 10;
+	// 	if (state.setting.soundEffect && !state.isPercussion) {
+	// 		evaluatingData.soundEffectMode = true;
+	// 		handleStartSoundCheck();
+	// 		return
+	// 	}
+	// 	handlePerformDetection();
+	// 	return;
+	// }
+	// 效验完成
 	if (evaluatingData.checkStep === 10) {
-		// 连接websocket
 		evaluatingData.checkEnd = true;
 	}
 };
@@ -176,7 +200,6 @@ export const addMeasureScore = (measureScore: any, show = true) => {
 };
 
 const handleScoreResult = (res?: IPostMessage) => {
-	console.log("🚀 ~ 评测返回:", res);
 	if (res?.content) {
 		const { header, body } = res.content;
 		// 效音返回
@@ -185,10 +208,12 @@ const handleScoreResult = (res?: IPostMessage) => {
 		}
 		// 小节评分返回
 		if (header?.commond === "measureScore") {
+			console.log("🚀 ~ 评测返回:", res);
 			addMeasureScore(body);
 		}
 		// 评测结束返回
 		if (header?.commond === "overall") {
+			console.log("🚀 ~ 评测返回:", res);
 			// console.log("评测结束", body);
 			evaluatingData.resulstMode = true;
 			evaluatingData.resultData = {
@@ -214,10 +239,10 @@ export const handleStartBegin = async () => {
 		evaluatingData.startBegin = false;
 		return;
 	}
-	if (res?.content?.reson){
+	if (res?.content?.reson) {
 		showToast(res.content.reson);
 		evaluatingData.startBegin = false;
-		return
+		return;
 	}
 	evaluatingData.startBegin = true;
 	//开始录音
@@ -253,7 +278,14 @@ const recordStartTimePoint = async (res?: IPostMessage) => {
 		inteveral *= 1000;
 	}
 	evaluatingData.backtime = inteveral || Date.now();
-	console.log("🚀 ~ 开始时间点:", evaluatingData.backtime, "已经录的时间:", Date.now() - inteveral, "记录时间点:", Date.now());
+	console.log(
+		"🚀 ~ 开始时间点:",
+		evaluatingData.backtime,
+		"已经录的时间:",
+		Date.now() - inteveral,
+		"记录时间点:",
+		Date.now()
+	);
 	// 开始播放
 	playMusic();
 
@@ -358,7 +390,10 @@ export const handleCancelEvaluat = () => {
 };
 
 /** 查看报告 */
-export const handleViewReport = (key: "recordId" | "recordIdStr", type: "gym" | "colexiu" | "orchestra" | 'instrument') => {
+export const handleViewReport = (
+	key: "recordId" | "recordIdStr",
+	type: "gym" | "colexiu" | "orchestra" | "instrument"
+) => {
 	const id = evaluatingData.resultData?.[key] || "";
 	let url = "";
 	switch (type) {