123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877 |
- import styles from "./index.module.less";
- import { Snackbar } from "@varlet/ui";
- import { closeToast, showLoadingToast, showToast, Popup } from "vant";
- import { defineComponent, 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_startRecordingCb,
- api_stopRecording,
- api_recordStartTime,
- api_remove_recordStartTime,
- api_startCapture,
- api_endCapture,
- api_getDeviceDelay,
- hideComplexButton,
- api_checkSocketStatus,
- addAccompanyError,
- removeAccompanyError,
- addSocketStatus,
- removeSocketStatus,
- api_disconnectSocket,
- api_midiMicDelay,
- api_cloudSetCurrentTime,
- api_cloudChangeSpeed,
- api_startDelayCheck,
- api_closeDelayCheck,
- api_openCamera,
- api_closeCamera,
- api_recordAudioUpload
- } from "/src/helpers/communication";
- import state, { IPlayState, clearSelection, handleStopPlay, onPlay, resetPlaybackToStart, togglePlay, initSetPlayRate, resetBaseRate, scrollViewNote } from "/src/state";
- import { IPostMessage } from "/src/utils/native-message";
- import { usePageVisibility } from "@vant/use";
- import { browser } from "/src/utils";
- import { getAudioCurrentTime, toggleMutePlayAudio, audioListStart, audioData } from "../audio-list";
- import { handleStartTick, closeTick } from "../tick";
- import AbnormalPop from "../abnormal-pop";
- import { storeData } from "../../store";
- import icon_bg from "../abnormal-pop/icon_bg.svg";
- import icon_close from "../abnormal-pop/icon_close.svg";
- import icon_btn from "../abnormal-pop/icon_btn.png";
- import icon_success from "../abnormal-pop/icon_success.png";
- import { data } from "../../page-instrument/custom-plugins/work-index";
- import { startCountdown } from "/src/page-instrument/evaluat-model/countdown";
- const browserInfo = browser();
- let socketStartTime = 0;
- export const popImgs = {
- icon_bg,
- icon_close,
- icon_btn,
- icon_success,
- };
- export const evaluatingData = reactive({
- /** 评测数据 */
- contentData: {} as any,
- /** 评测模块是否加载完成 */
- rendered: false,
- earphone: false, // 是否插入耳机
- soundEffect: false, // 是否效音
- soundEffectFrequency: 0, // 效音频率
- checkStep: 0, // 执行步骤
- checkEnd: false, // 检测结束
- earphoneMode: false, // 耳机弹窗
- earPhoneType: "" as "" | "有线耳机" | "蓝牙耳机", // 耳机类型
- soundEffectMode: false, // 效音弹窗
- websocketState: false, // websocket连接状态
- /**是否开始播放 */
- startBegin: false, // 开始
- backtime: 0, // 延迟时间
- /** 已经评测的数据 */
- evaluatings: {} as IEvaluatings,
- /** 评测结果 */
- resultData: {} as any,
- /** 评测结果弹窗 */
- resulstMode: false,
- /** 是否是完整评测 */
- isComplete: false,
- /** */
- isDisabledPlayMusic: false,
- /** socket异常状态弹窗 */
- socketErrorPop: false,
- /** 异常提示 */
- errorContents: '',
- /** socket异常状态弹窗的状态值 */
- socketErrorStatus: 0,
- /** 延迟检测,socket状态异常 */
- delayCheckSocketError: false,
- /** 异常状态,不生成评测记录,不调用保存接口 */
- isErrorState: false,
- /** accompanyError,错误类型 */
- accompanyErrorType: '',
- /** app播放结束状态,重新评测需要重置为 */
- isAudioPlayEnd: false,
- preloadJson: true, // 预加载延迟检测的资源
- jsonLoading: true, // 延迟检测的资源加载中状态
- jsonLoadDone: true, // 延迟检测的动画dom加载完成状态
- hideResultModal: false, // 评测作业,如果不是完整评测,需要隐藏评测结果弹窗
- oneselfCancleEvaluating: false, // 是否是自主取消评测,自主取消评测,不生产评测记录
- isBeginMask: false, // 倒计时和系统节拍器时候的遮罩,防止用户点击,
- recordingTime: 0, // 调用startRecording的时间
- endEvaluatingTime: 0, // 调用endEvaluating的时间
- evaluatSpeed: 0, // 评测记录的速度
- needReplayEvaluat: false, // 手动取消评测,需要自动开始评测
- needPlayTick: false, // 评测时,mp3节拍器需要等待音频开始播放后再执行播放节拍器的圆点动画
- tipErjiShow: false, // 评测提示弹窗
- onceErjiPopShow: false, // 是否已经提示过耳机弹窗,重新进入评测页面,重置该状态为false,手动关掉耳机弹窗,改变该状态为true,本次评测都不在提示耳机状态弹窗
- needCheckErjiStatus: true, // 点击评测模式进入评测模块的需要检测耳机状态,通过返回按钮进入评测模块的,不检测耳机状态
- evaluatResultLoading: false, // 评测结果处理中
- });
- const sendOffsetTime = async (offsetTime: number) => {
- const delayData = await api_getDeviceDelay();
- api_midiMicDelay({
- header: {
- commond: "audioPlayStart",
- type: "SOUND_COMPARE",
- },
- body: {
- offsetTime,
- micDelay: delayData?.content?.value,
- },
- });
- };
- /** 点击开始评测按钮 */
- export const handleStartEvaluat = async () => {
- if (state.modeType === "evaluating") {
- handleCancelEvaluat();
- // 放下面会在异步之后执行 旋律线可能在会隐藏不了
- state.modeType = "practise";
- } else {
- // 放下面会在异步之后执行 旋律线可能在会隐藏不了
- state.modeType = "evaluating";
- if (state.platform !== "PC") {
- // 评测前先检查APP端的websocket状态
- const res = await api_checkSocketStatus();
- if (res?.content?.status === "connected") {
- handleStopPlay();
- } else {
- // socket未连接
- // evaluatingData.socketErrorPop = true
- }
- } else {
- handleStopPlay();
- }
- }
- //state.modeType = state.modeType === "evaluating" ? "practise" : "evaluating";
- if (state.modeType !== "evaluating") {
- // 切换到练习模式,卸载评测模块
- evaluatingData.rendered = false;
- }
- };
- /** 开始评测 & 延迟检测开始按钮 */
- export const startCheckDelay = async () => {
- // 评测前先检查APP端的websocket状态
- const res = await api_checkSocketStatus();
- if (res?.content?.status === "connected") {
- //
- return new Promise((resolve) => {
- resolve({ checked: true });
- });
- } else {
- /**
- * socket未连接,记录此时的时间,以便于和收到socket成功链接,进行对比,对比时间小于500ms时,则连接中的状态默认显示500ms持续时间
- *
- * */
- socketStartTime = +new Date();
- evaluatingData.socketErrorPop = true;
- evaluatingData.socketErrorStatus = 1;
- return new Promise((resolve) => {
- resolve({ checked: false });
- });
- }
- };
- const check_currentTime = () => {
- let preTime = 0;
- // 选段评测模式
- if (state.isSelectMeasureMode) {
- preTime = state.section[0].time * 1000;
- }
- const currentTime = getAudioCurrentTime() * 1000 - preTime;
- // console.log('播放进度music', currentTime, 'preTime:' + preTime)
- if (currentTime >= 500) {
- sendEvaluatingOffsetTime(500);
- return;
- }
- setTimeout(() => {
- check_currentTime();
- }, 10);
- };
- /** 开始播放发送延迟时间 */
- export const sendEvaluatingOffsetTime = async (currentTime: number) => {
- // 没有开始时间点, 不处理
- if (!evaluatingData.backtime) return;
- const nowTime = Date.now();
- const delayTime = nowTime - evaluatingData.backtime - currentTime;
- console.error("真正播放延迟", delayTime, "currentTime:", currentTime);
- await api_proxyServiceMessage({
- header: {
- commond: "audioPlayStart",
- type: "SOUND_COMPARE",
- },
- body: {
- offsetTime: delayTime < 0 ? 0 : delayTime,
- micDelay: 0,
- },
- });
- };
- /** 检测耳机 */
- export 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 () => {
- // 检测完成不检测了
- if (evaluatingData.checkEnd) return;
- // 延迟检测
- if (evaluatingData.checkStep === 0) {
- evaluatingData.checkStep = 5;
- // 没有设备延迟数据 或 开启了效音 显示检测组件,并持续检测耳机状态
- if (state.setting.soundEffect) {
- evaluatingData.soundEffectMode = true;
- return;
- }
- const delayTime = await api_getDeviceDelay();
- console.log("🚀 ~ delayTime:", delayTime);
- if (!delayTime) {
- evaluatingData.soundEffectMode = true;
- return;
- }
- handlePerformDetection();
- return;
- }
- // 检测耳机
- if ((evaluatingData.checkStep = 5)) {
- evaluatingData.checkStep = 10;
- 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) {
- evaluatingData.checkEnd = true;
- }
- };
- /** 记录小节分数 */
- export const addMeasureScore = (measureScore: any, show = true) => {
- // #8720 bug修复
- for (let idx in evaluatingData.evaluatings) {
- evaluatingData.evaluatings[idx].show = false;
- }
- evaluatingData.evaluatings[measureScore.measureRenderIndex] = {
- ...measureScore,
- leve: getLeveByScoreMeasure(measureScore.score),
- show,
- };
- // console.log("🚀 ~ measureScore:", evaluatingData.evaluatings)
- };
- const handleScoreResult = async (res?: IPostMessage) => {
- console.log("返回", res, evaluatingData.oneselfCancleEvaluating);
- // 如果是手动取消评测,不生成评测记录
- // if (evaluatingData.oneselfCancleEvaluating) {
- // return;
- // }
- if (res?.content) {
- const { header, body } = res.content;
- // 效音返回
- if (header.commond === "checking") {
- evaluatingData.soundEffectFrequency = body.frequency;
- }
- // 小节评分返回
- if (header?.commond === "measureScore" && !evaluatingData.oneselfCancleEvaluating) {
- console.log("🚀 ~ 评测返回:", res);
- addMeasureScore(body);
- }
- // 评测结束返回
- if (header?.commond === "overall") {
- console.log("🚀 ~ 评测返回:", res);
- console.log("评测结束", body);
- state.isHideEvaluatReportSaveBtn = false;
- setTimeout(() => {
- // 评测作业,如果不是完整评测,不展示评测弹窗
- if (data.trainingType === "EVALUATION" && !evaluatingData.isComplete) {
- evaluatingData.hideResultModal = true;
- } else {
- evaluatingData.hideResultModal = false;
- }
- // 手动取消评测,不展示评测弹窗
- if (evaluatingData.oneselfCancleEvaluating) {
- evaluatingData.hideResultModal = true;
- }
- evaluatingData.resulstMode = evaluatingData.isErrorState ? false : true;
- evaluatingData.startBegin = false;
- evaluatingData.evaluatResultLoading = false;
- }, 200);
- evaluatingData.resultData = {
- ...body,
- ...getLeveByScore(body.score),
- };
- // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData)
- closeToast();
- state.isLoading = false
- }
- }
- };
- /** 开始评测 */
- export const handleStartBegin = async (preTimes?: number) => {
- // 滚动到当前小节所在区域
- scrollViewNote(true);
- evaluatingData.needPlayTick = false;
- if (state.isAppPlay) {
- await api_cloudSetCurrentTime({
- currentTime: 0,
- songID: state.examSongId,
- })
- }
- evaluatingData.isComplete = false;
- evaluatingData.evaluatings = {};
- evaluatingData.resultData = {};
- evaluatingData.backtime = 0;
- evaluatingData.isAudioPlayEnd = false;
- const res = await startEvaluating(evaluatingData.contentData);
- if (res?.api !== "startEvaluating") {
- Snackbar.error("请在APP端进行评测");
- evaluatingData.startBegin = false;
- return;
- }
- if (res?.content?.reson) {
- // #10984,APP端会有弹窗提示,不需要再次提示
- // showToast(res.content?.des);
- evaluatingData.startBegin = false;
- return;
- }
- resetPlaybackToStart();
- evaluatingData.startBegin = true;
- if (evaluatingData.isDisabledPlayMusic) {
- evaluatingData.isBeginMask = true
- // 先播放倒计时
- await startCountdown()
- state.playState = state.playState === "paused" ? "play" : "paused";
- // 设置为开始播放时, 如果需要节拍,先播放节拍器
- if (state.playState === "play" && (state.playType==="play"&&state.needTick)||(state.playType==="sing"&&state.needSingTick)) {
- // 如果是系统节拍器 等系统节拍器播完了再播,如果是mp3节拍器 直接播
- if((state.playType==="play" && !state.isOpenMetronome)||(state.playType==="sing" && !state.isSingOpenMetronome)){
- /**
- * #12291
- * 如果是选段评测,并且开始小节不是第一个小节,不需要播放节拍器的圆点动画
- */
- if (state.section.length && state.section[0]?.MeasureNumberXML !== state.firstMeasureNumber) {
- //
- } else {
- const tickend = await handleStartTick();
- console.log("🚀 ~ tickend:", tickend)
- // 节拍器返回false, 取消播放
- if (!tickend) {
- state.playState = "paused";
- evaluatingData.startBegin = false;
- evaluatingData.isBeginMask = false
- return;
- }
- }
- }else{
- // handleStartTick()
- // 需要等待音频返回进度后再执行节拍器圆点动画
- evaluatingData.needPlayTick = true;
- }
- }
- evaluatingData.isBeginMask = false
- onPlay();
- }
- if (evaluatingData.isErrorState) {
- state.playState = 'paused';
- evaluatingData.startBegin = false;
- return
- }
- //开始录音
- // await api_startRecording({
- // accompanimentState: state.setting.enableAccompaniment ? 1 : 0,
- // firstNoteTime: preTimes || 0,
- // });
- const rate = state.basePlayRate * state.originAudioPlayRate; // 播放倍率
- await api_startRecordingCb({
- // accompanimentState: state.setting.enableAccompaniment ? 1 : 0,
- accompanimentState: !state.accompany ? 0 : 1, // 评测没有伴奏时,静音播放
- firstNoteTime: preTimes || 0,
- speedRate: parseFloat(rate.toFixed(2)), // 播放倍率
- }, () => {
- if (state.isAppPlay) {
- setTimeout(() => {
- sendOffsetTime(0)
- }, 300);
- }
- })
- /**
- * 安卓端,快速点击开始评测和结束评测,间隔太小了时,会出现异常情况(音频没有停止播放)
- * 记录一下startRecord的开始时间
- */
- evaluatingData.recordingTime = +new Date();
- // 如果开启了摄像头, 开启录制视频
- if (state.setting.camera) {
- console.log("开始录制视频");
- await api_startCapture();
- }
- // 如果是midi音频评测,需要调用cloudPlay
- if (state.isAppPlay) {
- await api_cloudChangeSpeed({
- speed: state.originSpeed,
- originalSpeed: state.originSpeed,
- songID: state.examSongId,
- });
- audioData.progress = 0
- audioListStart(state.playState);
- }
- evaluatingData.oneselfCancleEvaluating = false;
- };
- /** 播放音乐 */
- const playMusic = async () => {
- const playState = await togglePlay("play");
- // 取消播放,停止播放
- if (!playState) {
- evaluatingData.startBegin = false;
- handleCancelEvaluat();
- return;
- }
- // 检测播放进度, 计算延迟
- check_currentTime();
- // 如果开启了摄像头, 开启录制视频
- if (state.setting.camera) {
- console.log("开始录制视频");
- api_startCapture();
- }
- };
- let _audio: HTMLAudioElement;
- /** 录音开始,记录开始时间点 */
- const recordStartTimePoint = async (res?: IPostMessage) => {
- console.error("开始录音");
- // 没有开始评测,不处理
- if (!evaluatingData.startBegin) return;
- let inteveral = res?.content?.inteveral || 0;
- if (browserInfo.ios) {
- inteveral *= 1000;
- }
- evaluatingData.backtime = inteveral || Date.now();
- console.log("🚀 ~ 开始时间点:", evaluatingData.backtime, "已经录的时间:", Date.now() - inteveral, "记录时间点:", Date.now());
- // 是否禁播
- if (evaluatingData.isDisabledPlayMusic) {
- return;
- }
- // 开始播放
- playMusic();
- };
- /**
- * 结束评测
- * @param isComplete 是否完整评测
- * @param endType 结束类型,selfCancel:是否是自己取消本次评测
- * @returns
- */
- export const handleEndEvaluat = (isComplete = false, endType?: string) => {
- // 没有开始评测 , 不是评测模式 , 不评分;evaluatResultLoading:评测结果处理中,避免重复结束
- if (!evaluatingData.startBegin || state.modeType !== "evaluating" || evaluatingData.evaluatResultLoading) return;
- // 结束录音
- // api_stopRecording();
- // 结束评测
- evaluatingData.evaluatResultLoading = true
- console.log("评测结束1");
- endEvaluating({
- musicScoreId: state.examSongId,
- });
- // 评测作业如果不是完整评测,给出提示
- if (!isComplete && data.trainingType === "EVALUATION") {
- showToast({
- message: "完整演奏结束才算作业分数!",
- });
- } else {
- if (!endType) {
- state.loadingText = "正在评分中,请稍等..."
- state.isLoading = true
- // showLoadingToast({
- // message: "评分中",
- // duration: 0,
- // overlay: true,
- // overlayClass: styles.scoreMode,
- // });
- }
- }
- setTimeout(() => {
- // evaluatingData.startBegin = false;
- if (endType === 'selfCancel') {
- // 重置播放倍率
- const item: any = (state.sectionStatus && state.section.length === 2) ? state.sectionFirst || state.section[0] : state.times[0];
- state.activeNoteIndex = item.i;
- state.activeMeasureIndex = item.MeasureNumberXML;
- resetBaseRate(item.i);
- }
- }, 500);
- evaluatingData.isComplete = isComplete;
- // 如果开启了摄像头, 结束录制视频
- if (state.setting.camera) {
- console.log("结束录制视频");
- api_endCapture();
- }
- };
- // 校验评测结束最小的时间间隔
- export const checkMinInterval = () => {
- const currentTime = +new Date();
- // 开始评测和结束评测的间隔时间小于800毫秒,则不处理
- if (currentTime - evaluatingData.recordingTime < 800) {
- return;
- }
- }
- /**
- * 结束评测(手动结束评测)
- */
- export const handleEndBegin = () => {
- handleEndEvaluat();
- handleStopPlay();
- };
- /**
- * 取消评测
- */
- export const handleCancelEvaluat = (cancelType?: string) => {
- evaluatingData.evaluatings = {};
- evaluatingData.startBegin = false;
- // 关闭提示
- closeToast();
- // 取消记录
- api_proxyServiceMessage({
- header: {
- commond: "recordCancel",
- type: "SOUND_COMPARE",
- status: 200,
- },
- });
- /**
- * 异常状态是取消评测(cancelEvaluating),正常结束时结束评测(endEvaluating)
- */
- // if (cancelType === "cancel") {
- // // 取消评测
- // cancelEvaluating();
- // } else {
- // endEvaluating({
- // musicScoreId: state.examSongId,
- // });
- // }
- cancelEvaluating();
- // 停止播放
- handleStopPlay();
- console.log("评测结束2");
- endEvaluating({
- musicScoreId: state.examSongId,
- });
- // 如果开启了摄像头, 结束录制视频
- if (state.setting.camera) {
- console.log("结束录制视频");
- api_endCapture();
- }
- };
- /** 查看报告 */
- export const handleViewReport = (key: "recordId" | "recordIdStr", type: "gym" | "colexiu" | "orchestra" | "instrument") => {
- const id = evaluatingData.resultData?.[key] || "";
- let url = "";
- switch (type) {
- case "gym":
- url = location.origin + location.pathname + "#/report/" + id;
- break;
- case "orchestra":
- url = location.origin + location.pathname + "report-share.html?id=" + id;
- break;
- case "instrument":
- url = location.origin + location.pathname + "#/evaluat-report?id=" + id + "&musicRenderType=" + state.musicRenderType + "&systemType=" + state.systemType;
- if (state.isSchool) {
- url += `&school=1`;
- }
- break;
- default:
- url = location.origin + location.pathname + "report-share.html?id=" + id;
- break;
- }
- api_openWebView({
- url,
- orientation: 0,
- isHideTitle: true, // 此处兼容安卓,意思为隐藏全部头部
- statusBarTextColor: false,
- isOpenLight: true,
- c_orientation: 0,
- showLoadingAnim: true
- });
- };
- // 隐藏存演奏按钮
- const handleComplexButton = (res?: IPostMessage) => {
- console.log("监听是否隐藏保存按钮", res);
- if (res?.content) {
- const { header, body } = res.content;
- state.isHideEvaluatReportSaveBtn = true;
- }
- };
- // 检测到APP发送的异常信息
- const handleAccompanyError = (res?: IPostMessage) => {
- console.log("异常信息返回", res);
- if (res?.content) {
- const { type, reson } = res.content;
- state.playState = 'paused'
- switch (type) {
- case "enterBackground":
- // App退到后台
- case "playError":
- // 播放异常
- case "socketError":
- // socket连接断开,评测中,则取消评测
- // 延迟检测中
- if (evaluatingData.soundEffectMode) {
- evaluatingData.socketErrorStatus = 0;
- evaluatingData.delayCheckSocketError = true;
- evaluatingData.socketErrorPop = type === "socketError" ? true : false;
- evaluatingData.accompanyErrorType = type;
- // api_checkSocketStatus()
- return;
- }
- // 评测中
- if (state.modeType === "evaluating" && evaluatingData.startBegin) {
- handleCancelEvaluat("cancel");
- }
- // 关闭节拍器
- closeTick();
- // socketerrror,才发送关闭延迟检测的消息
- if (type === "socketError") {
- api_closeDelayCheck({});
- }
- evaluatingData.socketErrorStatus = 0;
- evaluatingData.socketErrorPop = type === "socketError" ? true : false;
- evaluatingData.isErrorState = true;
- evaluatingData.accompanyErrorType = type;
- resetPlaybackToStart();
- break;
- case "recordError":
- // 录音异常
- break;
- default:
- break;
- }
- }
- };
- // 监测socket状态,是否已经成功连接
- const handleSocketStatus = (res?: IPostMessage) => {
- if (res?.content?.status === "connected") {
- const currentTime = +new Date();
- evaluatingData.delayCheckSocketError = false;
- const diffTime = currentTime - socketStartTime;
- if (diffTime < 1000) {
- const remainingTime = 1000 - diffTime;
- setTimeout(() => {
- evaluatingData.socketErrorStatus = 2;
- }, remainingTime);
- }
- }
- };
- // 评测出现异常,再试一次
- export const hanldeConfirmPop = async () => {
- api_checkSocketStatus();
- evaluatingData.socketErrorStatus = 1;
- socketStartTime = +new Date();
- };
- // 关闭异常弹窗
- export const hanldeClosePop = () => {
- evaluatingData.socketErrorPop = false;
- evaluatingData.socketErrorStatus = 0;
- };
- export default defineComponent({
- name: "evaluating",
- setup() {
- const pageVisibility = usePageVisibility();
- // 需要记录的数据
- const record_old_data = reactive({
- /** 指法 */
- finger: false,
- /** 原音伴奏 */
- play_mode: "" as IPlayState,
- /** 评测是否要伴奏 */
- enableAccompaniment: true,
- });
- /** 记录状态 */
- const hanlde_record = () => {
- // 取消指法
- // record_old_data.finger = state.setting.displayFingering;
- // state.setting.displayFingering = false;
- // 切换为伴奏
- record_old_data.play_mode = state.playSource;
- record_old_data.enableAccompaniment = state.setting.enableAccompaniment;
- // 如果关闭伴奏,评测静音
- if (!record_old_data.enableAccompaniment) {
- console.log("关闭伴奏");
- toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : record_old_data.play_mode === "background" ? "background" : "mingSong", true);
- }
- };
- /** 还原状态 */
- const handle_reduction = () => {
- // 还原指法
- // state.setting.displayFingering = record_old_data.finger;
- state.playSource = record_old_data.play_mode;
- // 如果关闭伴奏, 结束评测取消静音
- if (!record_old_data.enableAccompaniment) {
- toggleMutePlayAudio(record_old_data.play_mode === "music" ? "music" : record_old_data.play_mode === "background" ? "background" : "mingSong", false);
- }
- };
- // 打开摄像头
- const openSetCamera = async () => {
- if (state.setting.camera) {
- const res = await api_openCamera();
- // 没有授权
- if (res?.content?.reson) {
- state.setting.camera = false;
- store.set("musicscoresetting", state.setting);
- }
- }
- }
- watch(pageVisibility, (value) => {
- if (value == "hidden" && evaluatingData.startBegin) {
- // handleEndBegin();
- }
- });
- watch(
- () => evaluatingData.socketErrorStatus,
- () => {
- if (evaluatingData.socketErrorStatus === 2) {
- setTimeout(() => {
- evaluatingData.socketErrorPop = false;
- // evaluatingData.socketErrorStatus = 0
- }, 1000);
- }
- }
- );
- watch(
- () => evaluatingData.socketErrorPop,
- () => {
- if (evaluatingData.socketErrorPop && state.setting.soundEffect) {
- // 监听到socket状态异常,需要关闭延迟检测
- api_closeDelayCheck({});
- }
- }
- );
- onMounted(() => {
- openSetCamera();
- resetPlaybackToStart();
- hanlde_record();
- evaluatingData.resultData = {};
- // evaluatingData.resulstMode = true;
- // evaluatingData.resultData = {...getLeveByScore(10), score: 10, intonation: 10, cadence: 30, integrity: 40}
- // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData)
- evaluatingData.onceErjiPopShow = false;
- evaluatingData.evaluatings = {};
- evaluatingData.soundEffectFrequency = 0;
- evaluatingData.checkStep = 0;
- evaluatingData.rendered = true;
- sendResult(handleScoreResult);
- hideComplexButton(handleComplexButton, true);
- api_recordStartTime(recordStartTimePoint);
- addAccompanyError(handleAccompanyError);
- addSocketStatus(handleSocketStatus);
- // 不是选段模式评测, 就清空已选段
- if (!state.isSelectMeasureMode) {
- clearSelection();
- }
- console.log("加载评测模块成功");
- });
- onUnmounted(() => {
- evaluatingData.checkEnd = false;
- evaluatingData.rendered = false;
- resetPlaybackToStart();
- removeResult(handleScoreResult);
- hideComplexButton(() => {}, false);
- api_remove_recordStartTime(recordStartTimePoint);
- handle_reduction();
- removeAccompanyError(handleAccompanyError);
- if (evaluatingData.socketErrorPop && state.setting.soundEffect) {
- console.log('延迟检测出错')
- } else {
- removeSocketStatus(handleSocketStatus);
- }
- api_closeCamera();
- api_disconnectSocket();
- console.log("卸载评测模块成功");
- });
- return () => (
- <div>
- {/** 预加载一下断网需要用到的图片 */}
- <div class={styles.hiddenPop}>
- <img src={popImgs.icon_bg} />
- <img src={popImgs.icon_btn} />
- <img src={popImgs.icon_success} />
- <img src={popImgs.icon_close} />
- </div>
- <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale", evaluatingData.socketErrorStatus === 2 && styles.socketErrorStatus]} transition="van-scale" v-model:show={evaluatingData.socketErrorPop} overlay-style={evaluatingData.socketErrorStatus === 2?{ background: "initial" }:{}}>
- <AbnormalPop onConfirm={hanldeConfirmPop} onClose={hanldeClosePop} />
- </Popup>
- </div>
- );
- },
- });
|