import { Snackbar } from "@varlet/ui"; import { closeToast, showLoadingToast } from "vant"; import { defineComponent, onBeforeUnmount, onMounted, onUnmounted, reactive, ref, watch } from "vue"; import { getLeveByScore, getLeveByScoreMeasure, IEvaluatings } from "./evaluatResult"; import { cancelEvaluating, endEvaluating, endSoundCheck, getEarphone, api_proxyServiceMessage, removeResult, sendResult, startEvaluating, startSoundCheck, api_openWebView, api_startRecording, api_stopRecording, } from "/src/helpers/communication"; import state, { clearSelection, handleStopPlay, resetPlaybackToStart, togglePlay } from "/src/state"; import { IPostMessage } from "/src/utils/native-message"; import { usePageVisibility } from "@vant/use"; export const evaluatingData = reactive({ contentData: {} as any, /** 评测模块是否加载完成 */ rendered: false, earphone: false, // 是否插入耳机 soundEffect: false, // 是否效音 soundEffectFrequency: 0, // 效音频率 checkStep: 0, // 执行步骤 checkEnd: false, // 检测结束 earphoneMode: false, // 耳机弹窗 soundEffectMode: false, // 效音弹窗 websocketState: false, // websocket连接状态 startBegin: false, // 开始 backtime: 0, // 延迟时间 /** 已经评测的数据 */ evaluatings: {} as IEvaluatings, /** 评测结果 */ resultData: {} as any, /** 评测结果弹窗 */ resulstMode: false, }); /** 点击开始评测按钮 */ export const handleStartEvaluat = () => { if (state.modeType === "evaluating") { handleCancelEvaluat(); } else { handleStopPlay(); } state.modeType = state.modeType === "evaluating" ? "practise" : "evaluating"; if (state.modeType !== "evaluating") { // 切换到练习模式,卸载评测模块 evaluatingData.rendered = false; } }; /** 开始播放发送延迟时间 */ export const sendEvaluatingOffsetTime = (currentTime: number) => { const nowTime = Date.now(); // console.log("第一次播放时间", evaluatingData.backtime); // console.log("已播放时长: ", currentTime, currentTime * 1000); // console.log("不减掉已播放时间: ", nowTime - evaluatingData.backtime , currentTime); const delayTime = (nowTime - evaluatingData.backtime - currentTime * 1000) / 1000; console.log("真正播放延迟", delayTime / 1000); // 蓝牙耳机延迟一点发送消息确保在录音后面 setTimeout(async () => { await api_proxyServiceMessage({ header: { commond: "audioPlayStart", type: "SOUND_COMPARE", }, body: { offsetTime: delayTime < 0 ? 0 : delayTime, }, }); evaluatingData.backtime = 0; }, 220); }; /** 检测耳机 */ const checkUseEarphone = async () => { const res = await getEarphone(); return res?.content?.checkIsWired || false; }; /** * 开始录音 */ const handleStartSoundCheck = () => { startSoundCheck(); }; /** 结束录音 */ export const handleEndSoundCheck = () => { endSoundCheck(); }; /** 连接websocket */ export const connectWebsocket = async (content: any) => { evaluatingData.contentData = content; evaluatingData.websocketState = true; }; /** * 执行检测 */ export const handlePerformDetection = async () => { evaluatingData.checkEnd = false; if (evaluatingData.checkStep === 0) { // 检测耳机 const erji = await checkUseEarphone(); evaluatingData.checkStep = 1; if (erji) { handlePerformDetection(); } else { evaluatingData.earphoneMode = true; } return; } if (evaluatingData.checkStep === 1) { // 效音 // 是否需要开启效音 evaluatingData.checkStep = 10; if (state.setting.soundEffect) { evaluatingData.soundEffectMode = true; handleStartSoundCheck(); } else { handlePerformDetection(); } return; } if (evaluatingData.checkStep === 10) { // 连接websocket evaluatingData.checkEnd = true; evaluatingData.checkStep = 0; } }; /** 记录小节分数 */ const addMeasureScore = (measureScore: any) => { evaluatingData.evaluatings[measureScore.measureRenderIndex] = { ...measureScore, leve: getLeveByScoreMeasure(measureScore.score), show: true, }; // console.log("🚀 ~ measureScore:", evaluatingData.evaluatings[measureScore.measureRenderIndex]) }; const handleScoreResult = (res?: IPostMessage) => { if (res?.content) { console.log("🚀 ~ 评测返回:", res); const { header, body } = res.content; // 效音返回 if (header.commond === "checking") { evaluatingData.soundEffectFrequency = body.frequency; } // 小节评分返回 if (header?.commond === "measureScore") { addMeasureScore(body); } // 评测结束返回 if (header?.commond === "overall") { // console.log("评测结束", body); evaluatingData.resulstMode = true; evaluatingData.resultData = { ...body, ...getLeveByScore(body.score), }; // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData) closeToast(); } } }; /** 开始评测 */ export const handleStartBegin = async () => { evaluatingData.startBegin = true; evaluatingData.evaluatings = {}; evaluatingData.resultData = {}; evaluatingData.backtime = Date.now(); resetPlaybackToStart(); try { console.log("🚀 ~ content:", evaluatingData.contentData, JSON.stringify(evaluatingData.contentData)); } catch (error) {} const res = await startEvaluating(evaluatingData.contentData); if (res?.api !== "startEvaluating") { Snackbar.error("请在APP端进行评测"); evaluatingData.startBegin = false; return; } // 开始录音 api_startRecording(); const playState = await togglePlay("play"); // 取消播放 if (!playState) { evaluatingData.startBegin = false; handleCancelEvaluat(); return; } }; /** * 结束评测 */ export const handleEndEvaluat = () => { console.log("触发结束"); // 没有开始评测 , 不是评测模式 , 不评分 if (!evaluatingData.startBegin || state.modeType !== "evaluating") return; evaluatingData.startBegin = false; // 结束录音 api_stopRecording(); // 结束评测 endEvaluating({ musicScoreId: state.examSongId, }); showLoadingToast({ message: "评分中", duration: 0, forbidClick: true, }); }; /** * 结束评测 * @param isEnd 是否是自动播放停止, 默认: false */ export const handleEndBegin = () => { handleEndEvaluat(); handleStopPlay(); }; /** * 取消评测 */ export const handleCancelEvaluat = () => { evaluatingData.evaluatings = {}; // 关闭提示 closeToast(); // 取消记录 api_proxyServiceMessage({ header: { commond: "recordCancel", type: "SOUND_COMPARE", status: 200, }, }); // 取消评测 cancelEvaluating(); // 停止播放 handleStopPlay(); }; /** 查看报告 */ export const handleViewReport = () => { api_openWebView({ url: location.origin + "/accompany/#/report/" + evaluatingData.resultData?.recordId || "", orientation: 0, isHideTitle: true, // 此处兼容安卓,意思为隐藏全部头部 statusBarTextColor: false, isOpenLight: true, }); }; export default defineComponent({ name: "evaluating", setup() { const pageVisibility = usePageVisibility(); watch(pageVisibility, (value) => { if (value == "hidden" && evaluatingData.startBegin) { handleEndBegin(); } }); onMounted(() => { evaluatingData.resultData = {}; // evaluatingData.resultData = {...getLeveByScore(90), score: 30, intonation: 10, cadence: 30, integrity: 40} // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData) evaluatingData.evaluatings = {}; evaluatingData.soundEffectFrequency = 0; evaluatingData.checkStep = 0; evaluatingData.rendered = true; sendResult(handleScoreResult); if (!state.isSelectMeasureMode) { clearSelection(); } }); onUnmounted(() => { removeResult(handleScoreResult); }); return () =>
; }, });