|
@@ -1,5 +1,5 @@
|
|
-import { Button, Toast } from 'vant'
|
|
|
|
-import { defineComponent, onBeforeUnmount, onMounted, Ref, ref, Teleport, Transition } from 'vue'
|
|
|
|
|
|
+import { Button, Toast, Popup } from 'vant'
|
|
|
|
+import { defineComponent, onBeforeUnmount, onMounted, Ref, ref, Teleport, Transition, reactive } from 'vue'
|
|
import '@dotlottie/player-component'
|
|
import '@dotlottie/player-component'
|
|
import detailState, { isRhythmicExercises } from '/src/pages/detail/state'
|
|
import detailState, { isRhythmicExercises } from '/src/pages/detail/state'
|
|
import SettingState from '/src/pages/detail/setting-state'
|
|
import SettingState from '/src/pages/detail/setting-state'
|
|
@@ -21,10 +21,41 @@ import Evaluating, { evaluatingShow } from '../popups/evaluating'
|
|
// @ts-ignore
|
|
// @ts-ignore
|
|
import styles from './index.module.less'
|
|
import styles from './index.module.less'
|
|
import { Vue3Lottie } from 'vue3-lottie'
|
|
import { Vue3Lottie } from 'vue3-lottie'
|
|
-import startData from './data/start.json'
|
|
|
|
-import startingData from './data/starting.json'
|
|
|
|
|
|
+import startData from './data/start_new.json'
|
|
|
|
+import startingData from './data/starting_new.json'
|
|
import { unitTestData } from '../unitTest'
|
|
import { unitTestData } from '../unitTest'
|
|
import iconEvaluatingStart from './icons/icon-evaluatingStart.png'
|
|
import iconEvaluatingStart from './icons/icon-evaluatingStart.png'
|
|
|
|
+import qs from 'query-string'
|
|
|
|
+import CheckDelayPopup from "/src/pages/detail/CheckDelayPopup";
|
|
|
|
+import Headphone, { HeadphoneData } from "/src/pages/detail/Headphone";
|
|
|
|
+import { modelType } from './index'
|
|
|
|
+
|
|
|
|
+/** 初始化评测音频 */
|
|
|
|
+export const evaluatCreateMusicPlayer = () => {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ // 初始化曲谱音频 和效音音频
|
|
|
|
+ postMessage(
|
|
|
|
+ {
|
|
|
|
+ api: "createMusicPlayer",
|
|
|
|
+ content: {
|
|
|
|
+ musicSrc: runtime.songs.background || runtime.songs.music, // 曲谱音频url
|
|
|
|
+ tuneSrc: "https://oss.dayaedu.com/cloud-coach/1686725501654check_music1_(1).mp3", //效音音频url
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ () => {
|
|
|
|
+ if (browserInfo.ios) {
|
|
|
|
+ resolve(true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ // 安卓不需要
|
|
|
|
+ if(!browserInfo.ios){
|
|
|
|
+ resolve(true)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const searchParams: any = qs.parse(location.search)
|
|
|
|
|
|
/**
|
|
/**
|
|
* 节拍器时长
|
|
* 节拍器时长
|
|
@@ -44,6 +75,200 @@ const playUrl: Ref<string> = ref('')
|
|
const endResult = ref(null)
|
|
const endResult = ref(null)
|
|
const browserInfo = browser()
|
|
const browserInfo = browser()
|
|
const scoreList: any[] = []
|
|
const scoreList: any[] = []
|
|
|
|
+let calculateInfo: any = {}
|
|
|
|
+/** 延迟数据 */
|
|
|
|
+const delayData = reactive({
|
|
|
|
+ /** 是否强制检测 */
|
|
|
|
+ isForce: true,
|
|
|
|
+ /** 弹窗 */
|
|
|
|
+ open: false,
|
|
|
|
+ /** 延迟次数 */
|
|
|
|
+ count: 0,
|
|
|
|
+ /** 延迟时间 */
|
|
|
|
+ time: 0,
|
|
|
|
+ /** 耳机状态 */
|
|
|
|
+ erji: false,
|
|
|
|
+ /** 检测状态 */
|
|
|
|
+ checkStatus: 'init' as 'init' | 'ing' | 'error',
|
|
|
|
+ step: 1,
|
|
|
|
+ earPhoneType: "" as "" | "有线耳机" | "蓝牙耳机",
|
|
|
|
+})
|
|
|
|
+ /** 获取耳机状态 */
|
|
|
|
+ const getWiredStatus = (): Promise<boolean> => {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ const timer = setTimeout(() => {
|
|
|
|
+ resolve(false);
|
|
|
|
+ }, 1000)
|
|
|
|
+ postMessage({
|
|
|
|
+ api: "isWiredHeadsetOn",
|
|
|
|
+ }, (res) => {
|
|
|
|
+ delayData.earPhoneType = res?.content?.type || "";
|
|
|
|
+ const checkIsWired = res?.content?.checkIsWired ? true : false;
|
|
|
|
+ if (checkIsWired) {
|
|
|
|
+ if (delayData.step <= 5) {
|
|
|
|
+ delayData.step = 3
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (delayData.step === 2) {
|
|
|
|
+ delayData.step = 4
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
+ resolve(checkIsWired);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const closeErji = () => {
|
|
|
|
+ //
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /** 获取设备延迟 */
|
|
|
|
+ const getDeviceDelay = (): Promise<number> => {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ const timer = setTimeout(() => {
|
|
|
|
+ resolve(0);
|
|
|
|
+ }, 1000)
|
|
|
|
+ postMessage({
|
|
|
|
+ api: "getDeviceDelay",
|
|
|
|
+ }, (res) => {
|
|
|
|
+ const delay = res?.content?.value > 0 ? res?.content?.value : 0;
|
|
|
|
+ clearTimeout(timer)
|
|
|
|
+ resolve(delay);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ /** 设备延迟检测结束 */
|
|
|
|
+ const handleCheckDelayEnd = () => {
|
|
|
|
+ if (delayData.erji) {
|
|
|
|
+ closeErji();
|
|
|
|
+ } else {
|
|
|
|
+ // this.erjiShow = true;
|
|
|
|
+ HeadphoneData.toggle();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /** 评测效验 */
|
|
|
|
+ const checkEvaluating = async () => {
|
|
|
|
+ delayData.erji = await getWiredStatus();
|
|
|
|
+ delayData.time = await getDeviceDelay();
|
|
|
|
+ // 没有设备延迟数据,显示检测组件,并持续检测耳机状态
|
|
|
|
+ if (!delayData.time || delayData.isForce) {
|
|
|
|
+ delayData.open = (runtime.delayCheckFirst && searchParams.evaluatingRecord || !SettingState.sett.tuning) ? false : true
|
|
|
|
+ delayData.count = 0;
|
|
|
|
+ checkWiredStatus();
|
|
|
|
+ if (runtime.delayCheckFirst && searchParams.evaluatingRecord) {
|
|
|
|
+ // closeErji()
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ handleCheckDelayEnd()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /** 持续检测耳机状态 */
|
|
|
|
+ const checkWiredStatus = () => {
|
|
|
|
+ console.log('耳机状态',delayData.checkStatus, delayData.step)
|
|
|
|
+ // 设备检测结束,停止获取耳机状态
|
|
|
|
+ // if (delayData.checkStatus !== 'ing' || delayData.open === false) {
|
|
|
|
+ // return
|
|
|
|
+ // }
|
|
|
|
+ if (delayData.open === false) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ setTimeout(async () => {
|
|
|
|
+ delayData.erji = await getWiredStatus();
|
|
|
|
+ if (delayData.erji) {
|
|
|
|
+ delayData.count = 0;
|
|
|
|
+ delayData.time = 0;
|
|
|
|
+ // delayData.checkStatus = 'error'
|
|
|
|
+ } else {
|
|
|
|
+ if (delayData.step === 3) {
|
|
|
|
+ delayData.step = 1
|
|
|
|
+ delayData.checkStatus = 'init'
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ checkWiredStatus();
|
|
|
|
+ }, 1000)
|
|
|
|
+ }
|
|
|
|
+ /** 切换效音 */
|
|
|
|
+ const handleToggleTune = (state: 'start' | 'stop' | 'finishTune') => {
|
|
|
|
+ if (state === 'start') {
|
|
|
|
+ delayData.step = 5
|
|
|
|
+ // 开始效音
|
|
|
|
+ postMessage({
|
|
|
|
+ api: "startTune",
|
|
|
|
+ content: {
|
|
|
|
+ count: delayData.count + '',
|
|
|
|
+ }
|
|
|
|
+ }, (res) => {
|
|
|
|
+ // 用户没有授权,需要重置状态
|
|
|
|
+ if (res?.content?.reson) {
|
|
|
|
+ delayData.step = 1
|
|
|
|
+ delayData.checkStatus = 'init'
|
|
|
|
+ } else {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ handleToggleTune('stop')
|
|
|
|
+ }, 1500)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ } else if (state === 'stop') {
|
|
|
|
+ // 结束效音,触发时机: 1.监听后台效音返回 2.点击跳过效音或关闭效音
|
|
|
|
+ postMessage({
|
|
|
|
+ api: "endTune"
|
|
|
|
+ })
|
|
|
|
+ } else if (state === 'finishTune') {
|
|
|
|
+ delayData.step = 6
|
|
|
|
+ // 效音完成
|
|
|
|
+ postMessage({
|
|
|
|
+ api: "finishTune",
|
|
|
|
+ }, (res) => {
|
|
|
|
+ const result = res?.content?.result //1成功 0失败
|
|
|
|
+ // Toast('检测延迟完成')
|
|
|
|
+ // setTimeout(() => {
|
|
|
|
+ // delayData.open = false
|
|
|
|
+ // }, 500)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ /** 开始效音 */
|
|
|
|
+ const startTune = () => {
|
|
|
|
+ // 带了耳机,停止播放效音
|
|
|
|
+ if (delayData.erji) return;
|
|
|
|
+ handleToggleTune('start')
|
|
|
|
+ }
|
|
|
|
+ /** 停止设备延迟检测 */
|
|
|
|
+ const handleStopCheckDelay = () => {
|
|
|
|
+ runtime.delayCheckFirst = true
|
|
|
|
+ delayData.open = false
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ delayData.checkStatus = 'init'
|
|
|
|
+ delayData.step = 1
|
|
|
|
+ }, 500);
|
|
|
|
+ handleToggleTune('stop')
|
|
|
|
+ // this.close();
|
|
|
|
+ }
|
|
|
|
+ const handleDelayBack = () => {
|
|
|
|
+ modelType.value = 'init'
|
|
|
|
+ delayData.open = false
|
|
|
|
+ delayData.checkStatus = 'init'
|
|
|
|
+ delayData.step = 1
|
|
|
|
+ handleToggleTune('stop')
|
|
|
|
+ }
|
|
|
|
+ /** 开始检测设备延迟 */
|
|
|
|
+ const handleStartCheckDelay = async () => {
|
|
|
|
+ if (delayData.checkStatus === 'ing') return;
|
|
|
|
+ delayData.step = 2
|
|
|
|
+ delayData.erji = await getWiredStatus();
|
|
|
|
+ if (delayData.erji) {
|
|
|
|
+ delayData.checkStatus = 'error'
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ delayData.checkStatus = 'ing';
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ startTune()
|
|
|
|
+ }, 2000)
|
|
|
|
+ }
|
|
|
|
|
|
// frequency 频率, amplitude 振幅, decibels 分贝
|
|
// frequency 频率, amplitude 振幅, decibels 分贝
|
|
type TCriteria = "frequency" | "amplitude" | "decibels";
|
|
type TCriteria = "frequency" | "amplitude" | "decibels";
|
|
@@ -87,6 +312,8 @@ const formatTimes = () => {
|
|
// 阶段评测前一个节拍的标示
|
|
// 阶段评测前一个节拍的标示
|
|
let preLyricsContent = ''
|
|
let preLyricsContent = ''
|
|
let preTimes = []
|
|
let preTimes = []
|
|
|
|
+ let unitTestIdx = 0
|
|
|
|
+ let preTime = 0
|
|
if (unitTestData.isSelectMeasureMode) {
|
|
if (unitTestData.isSelectMeasureMode) {
|
|
const startIndex = detailState.times.findIndex(
|
|
const startIndex = detailState.times.findIndex(
|
|
(n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[0].NoteToGraphicalNoteObjectId
|
|
(n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[0].NoteToGraphicalNoteObjectId
|
|
@@ -94,6 +321,9 @@ const formatTimes = () => {
|
|
const endIndex = detailState.times.findIndex(
|
|
const endIndex = detailState.times.findIndex(
|
|
(n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[1].NoteToGraphicalNoteObjectId
|
|
(n: any) => n.NoteToGraphicalNoteObjectId == detailState.section[1].NoteToGraphicalNoteObjectId
|
|
)
|
|
)
|
|
|
|
+ if (startIndex > 1) {
|
|
|
|
+ preTime = detailState.times[startIndex-1].time * 1000
|
|
|
|
+ }
|
|
times = detailState.times.filter((n: any, index: number) => {
|
|
times = detailState.times.filter((n: any, index: number) => {
|
|
return index >= startIndex && index <= endIndex
|
|
return index >= startIndex && index <= endIndex
|
|
})
|
|
})
|
|
@@ -103,6 +333,7 @@ const formatTimes = () => {
|
|
starTime = times[0].sourceRelativeTime || times[0].relativeTime
|
|
starTime = times[0].sourceRelativeTime || times[0].relativeTime
|
|
actualBeatLength = startIndex == 0 && !detailState.needTick ? actualBeatLength : 0
|
|
actualBeatLength = startIndex == 0 && !detailState.needTick ? actualBeatLength : 0
|
|
// console.log("🚀 ~ times", times, '开始小节', startIndex, actualBeatLength)
|
|
// console.log("🚀 ~ times", times, '开始小节', startIndex, actualBeatLength)
|
|
|
|
+ unitTestIdx = startIndex
|
|
}
|
|
}
|
|
// 找到阶段评测,开始小节前面最近的是play或者listen的小节
|
|
// 找到阶段评测,开始小节前面最近的是play或者listen的小节
|
|
if (preTimes.length) {
|
|
if (preTimes.length) {
|
|
@@ -122,6 +353,7 @@ const formatTimes = () => {
|
|
}
|
|
}
|
|
let measureIndex = -1
|
|
let measureIndex = -1
|
|
let recordMeasure = -1
|
|
let recordMeasure = -1
|
|
|
|
+ let firstNoteTime = unitTestIdx > 1 ? preTime : 0
|
|
for (let index = 0; index < times.length; index++) {
|
|
for (let index = 0; index < times.length; index++) {
|
|
const item = times[index]
|
|
const item = times[index]
|
|
const note = getNoteByMeasuresSlursStart(item)
|
|
const note = getNoteByMeasuresSlursStart(item)
|
|
@@ -174,18 +406,23 @@ const formatTimes = () => {
|
|
denominator: note.noteElement?.Length.denominator,
|
|
denominator: note.noteElement?.Length.denominator,
|
|
isOrnament: !!note?.voiceEntry?.ornamentContainer,
|
|
isOrnament: !!note?.voiceEntry?.ornamentContainer,
|
|
}
|
|
}
|
|
|
|
+ // console.log('时间1111', data)
|
|
datas.push(data)
|
|
datas.push(data)
|
|
}
|
|
}
|
|
- return datas
|
|
|
|
|
|
+ return {
|
|
|
|
+ datas,
|
|
|
|
+ firstNoteTime
|
|
|
|
+ }
|
|
}
|
|
}
|
|
const connect = async () => {
|
|
const connect = async () => {
|
|
const search = useOriginSearch()
|
|
const search = useOriginSearch()
|
|
connentLoading.value = true
|
|
connentLoading.value = true
|
|
const behaviorId = sessionStorage.getItem('behaviorId') || search.behaviorId || initBehaviorId
|
|
const behaviorId = sessionStorage.getItem('behaviorId') || search.behaviorId || initBehaviorId
|
|
const rate = runtime.speed / detailState.baseSpeed //1
|
|
const rate = runtime.speed / detailState.baseSpeed //1
|
|
-
|
|
|
|
|
|
+ calculateInfo = formatTimes()
|
|
const content = {
|
|
const content = {
|
|
- musicXmlInfos: formatTimes(),
|
|
|
|
|
|
+ musicXmlInfos: calculateInfo.datas,
|
|
|
|
+ firstNoteTime: calculateInfo.firstNoteTime,
|
|
subjectId: detailState.subjectId ? detailState.subjectId : detailState.isPercussion ? 1 : detailState.subjectId,
|
|
subjectId: detailState.subjectId ? detailState.subjectId : detailState.isPercussion ? 1 : detailState.subjectId,
|
|
detailId: detailState.activeDetail?.id,
|
|
detailId: detailState.activeDetail?.id,
|
|
examSongId: search.id,
|
|
examSongId: search.id,
|
|
@@ -196,7 +433,7 @@ const connect = async () => {
|
|
clientId: 'STUDENT',
|
|
clientId: 'STUDENT',
|
|
hertz: SettingState.sett.hertz,
|
|
hertz: SettingState.sett.hertz,
|
|
feature: 'EVALUATION',
|
|
feature: 'EVALUATION',
|
|
- practiceSource: search.unitId ? 'UNIT_TEST' : 'PRACTICE',
|
|
|
|
|
|
+ practiceSource: (search.resourceType && search.resourceType === 'practice') ? 'UNIT_TEST_PRACTICE' : search.unitId ? 'UNIT_TEST' : 'PRACTICE',
|
|
// 这里定义的是数字但是因为是通过input输入所以强制转化一次
|
|
// 这里定义的是数字但是因为是通过input输入所以强制转化一次
|
|
reactionTimeMs: parseFloat('' + SettingState.eva.reactionTimeMs) || 0,
|
|
reactionTimeMs: parseFloat('' + SettingState.eva.reactionTimeMs) || 0,
|
|
speed: runtime.speed,
|
|
speed: runtime.speed,
|
|
@@ -264,27 +501,28 @@ const cancelTheEvaluation = () => {
|
|
RuntimeUtils.clearIntervalTimeline()
|
|
RuntimeUtils.clearIntervalTimeline()
|
|
RuntimeUtils.setCurrentTime(0)
|
|
RuntimeUtils.setCurrentTime(0)
|
|
Toast.clear()
|
|
Toast.clear()
|
|
- }, 200);
|
|
|
|
|
|
+ }, 500);
|
|
}
|
|
}
|
|
|
|
|
|
const stopPlay = () => {
|
|
const stopPlay = () => {
|
|
console.log('调用stopPlay')
|
|
console.log('调用stopPlay')
|
|
- if (!connentLoading.value) {
|
|
|
|
|
|
+ if (!connentLoading.value && evaluating.value) {
|
|
cancelTheEvaluation()
|
|
cancelTheEvaluation()
|
|
}
|
|
}
|
|
startButtonShow.value = true
|
|
startButtonShow.value = true
|
|
connentLoading.value = false
|
|
connentLoading.value = false
|
|
evaluating.value = false
|
|
evaluating.value = false
|
|
|
|
+ modelType.value = 'init'
|
|
}
|
|
}
|
|
export const evaluatStopPlay = stopPlay
|
|
export const evaluatStopPlay = stopPlay
|
|
|
|
|
|
const startPlay = () => {
|
|
const startPlay = () => {
|
|
console.log('连接服务成功,开始播放', new Date().getTime() - runtime.clickTime)
|
|
console.log('连接服务成功,开始播放', new Date().getTime() - runtime.clickTime)
|
|
- if (!SettingState.eva.mute) {
|
|
|
|
- RuntimeUtils.changeAllMode()
|
|
|
|
- } else {
|
|
|
|
- RuntimeUtils.changeMode('background')
|
|
|
|
- }
|
|
|
|
|
|
+ // if (!SettingState.eva.mute) {
|
|
|
|
+ // RuntimeUtils.changeAllMode()
|
|
|
|
+ // } else {
|
|
|
|
+ // RuntimeUtils.changeMode('background')
|
|
|
|
+ // }
|
|
startButtonShow.value = false
|
|
startButtonShow.value = false
|
|
RuntimeUtils.setPlayState()
|
|
RuntimeUtils.setPlayState()
|
|
}
|
|
}
|
|
@@ -307,9 +545,10 @@ const setPlayer = async () => {
|
|
})
|
|
})
|
|
try {
|
|
try {
|
|
await connect()
|
|
await connect()
|
|
- startPlay()
|
|
|
|
|
|
+ //startPlay()
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
console.log('关闭弹窗')
|
|
console.log('关闭弹窗')
|
|
|
|
+ startButtonShow.value = false
|
|
Toast.clear()
|
|
Toast.clear()
|
|
hint.close()
|
|
hint.close()
|
|
}, 100)
|
|
}, 100)
|
|
@@ -317,6 +556,7 @@ const setPlayer = async () => {
|
|
runtime.evaluatingStatus = false
|
|
runtime.evaluatingStatus = false
|
|
Toast.clear()
|
|
Toast.clear()
|
|
}
|
|
}
|
|
|
|
+ evaluatStart()
|
|
}
|
|
}
|
|
|
|
|
|
const togglePlay = () => {
|
|
const togglePlay = () => {
|
|
@@ -391,7 +631,7 @@ const playerStop = () => {
|
|
}
|
|
}
|
|
)
|
|
)
|
|
RuntimeUtils.endCapture()
|
|
RuntimeUtils.endCapture()
|
|
- },200)
|
|
|
|
|
|
+ }, 500);
|
|
}
|
|
}
|
|
export const evaluatPlayerStop = playerStop
|
|
export const evaluatPlayerStop = playerStop
|
|
|
|
|
|
@@ -435,11 +675,16 @@ const evaluatStart = () => {
|
|
postMessage(
|
|
postMessage(
|
|
{
|
|
{
|
|
api: 'startRecording',
|
|
api: 'startRecording',
|
|
|
|
+ content: {
|
|
|
|
+ accompanimentState: SettingState.eva.mute ? 1 : 0,
|
|
|
|
+ firstNoteTime: calculateInfo.firstNoteTime || 0,
|
|
|
|
+ }
|
|
},
|
|
},
|
|
() => {
|
|
() => {
|
|
// console.log('开始录音app回调时间', Date.now())
|
|
// console.log('开始录音app回调时间', Date.now())
|
|
backtime = Date.now()
|
|
backtime = Date.now()
|
|
evaluating.value = true
|
|
evaluating.value = true
|
|
|
|
+ runtime.playState = "play";
|
|
if (detailState.activeDetail?.midiUrl) {
|
|
if (detailState.activeDetail?.midiUrl) {
|
|
console.log('midiUrl', detailState.activeDetail?.midiUrl)
|
|
console.log('midiUrl', detailState.activeDetail?.midiUrl)
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
@@ -451,6 +696,11 @@ const evaluatStart = () => {
|
|
RuntimeUtils.startCapture()
|
|
RuntimeUtils.startCapture()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /** 音频播放完结束评测 */
|
|
|
|
+ const playEnd_endEvalute = () => {
|
|
|
|
+ playerStop()
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 酷乐秀活动接口,Url中有设置并且仅在学生端提评分交数据
|
|
* 酷乐秀活动接口,Url中有设置并且仅在学生端提评分交数据
|
|
* 管乐团单元测验, url中有单元测验ID仅在学生端提评分交数据
|
|
* 管乐团单元测验, url中有单元测验ID仅在学生端提评分交数据
|
|
@@ -500,6 +750,16 @@ const sendResult = (evt?: IPostMessage) => {
|
|
// 此处已经在校音中单独监听不做处理
|
|
// 此处已经在校音中单独监听不做处理
|
|
} else if (evt?.content.header.commond === 'checking') {
|
|
} else if (evt?.content.header.commond === 'checking') {
|
|
// 此处已经在校音中单独监听不做处理
|
|
// 此处已经在校音中单独监听不做处理
|
|
|
|
+ } else if (evt?.content.header.commond === "recordEnd") {
|
|
|
|
+ if (delayData.checkStatus !== 'ing') return
|
|
|
|
+ delayData.count++;
|
|
|
|
+ if (delayData.count >= 2) {
|
|
|
|
+ handleToggleTune('finishTune');
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ startTune()
|
|
|
|
+ }, 100)
|
|
} else {
|
|
} else {
|
|
const getBeforeNote = (index: number) => {
|
|
const getBeforeNote = (index: number) => {
|
|
while (index >= 0) {
|
|
while (index >= 0) {
|
|
@@ -602,22 +862,44 @@ export const submitMaxScore = () => {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+/**
|
|
|
|
+ * 木管(长笛 萨克斯 单簧管)乐器一级的2、3、6测评要放原音音频
|
|
|
|
+ * 铜管乐器一级的1a,1b,5,6测评要放原音音频
|
|
|
|
+ */
|
|
|
|
+const getMusicMode = (): RuntimeUtils.IMode => {
|
|
|
|
+ const muguan = [2, 4, 5, 6];
|
|
|
|
+ const tongguan = [12, 13, 14, 15, 17];
|
|
|
|
+ if (muguan.includes(detailState.subjectId) && (detailState.activeDetail?.examSongName || "").search(/[^\u0000-\u00FF](1-2|1-3|1-6)/gi) > -1) {
|
|
|
|
+ return "music";
|
|
|
|
+ }
|
|
|
|
+ if (tongguan.includes(detailState.subjectId) && (detailState.activeDetail?.examSongName || "").search(/[^\u0000-\u00FF](1-1-1|1-1-2|1-5|1-6)/gi) > -1) {
|
|
|
|
+ return "music";
|
|
|
|
+ }
|
|
|
|
+ if ([23, 113, 121].includes(detailState.subjectId)) {
|
|
|
|
+ return "music";
|
|
|
|
+ }
|
|
|
|
+ return "background";
|
|
|
|
+};
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'ColexiuButtonEvaluating',
|
|
name: 'ColexiuButtonEvaluating',
|
|
setup(props, { expose }) {
|
|
setup(props, { expose }) {
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
console.log('进入评测模块')
|
|
console.log('进入评测模块')
|
|
|
|
+ if (!SettingState.eva.mute) {
|
|
|
|
+ RuntimeUtils.changeAllMode();
|
|
|
|
+ } else {
|
|
|
|
+ RuntimeUtils.changeMode('background', 'all')
|
|
|
|
+ }
|
|
handleCheckEvaluatStatus()
|
|
handleCheckEvaluatStatus()
|
|
// 如果为单元测验和课后训练,不清楚选段数据
|
|
// 如果为单元测验和课后训练,不清楚选段数据
|
|
if (!unitTestData.isSelectMeasureMode) {
|
|
if (!unitTestData.isSelectMeasureMode) {
|
|
detailState.section = []
|
|
detailState.section = []
|
|
detailState.sectionStatus = false
|
|
detailState.sectionStatus = false
|
|
}
|
|
}
|
|
- RuntimeUtils.changeAllMode()
|
|
|
|
playUrl.value = runtime.songs.background || (runtime.songs.music as string)
|
|
playUrl.value = runtime.songs.background || (runtime.songs.music as string)
|
|
- runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('play', timeupdate)
|
|
|
|
- runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('timeupdate', onProgress)
|
|
|
|
|
|
+ // runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('play', timeupdate)
|
|
|
|
+ // runtime.audiosInstance?.audios[playUrl.value]?.addEventListener('timeupdate', onProgress)
|
|
// RuntimeUtils.event.on('next-click', playerStop)
|
|
// RuntimeUtils.event.on('next-click', playerStop)
|
|
RuntimeUtils.event.on('ended', endevent)
|
|
RuntimeUtils.event.on('ended', endevent)
|
|
listenerMessage('sendResult', sendResult)
|
|
listenerMessage('sendResult', sendResult)
|
|
@@ -625,12 +907,15 @@ export default defineComponent({
|
|
listenerMessage('cloudTimeUpdae', onProgress)
|
|
listenerMessage('cloudTimeUpdae', onProgress)
|
|
RuntimeUtils.event.on('tickDestroy', cloudMetronome)
|
|
RuntimeUtils.event.on('tickDestroy', cloudMetronome)
|
|
RuntimeUtils.event.on('tickEnd', evaluatStart)
|
|
RuntimeUtils.event.on('tickEnd', evaluatStart)
|
|
|
|
+ runtime.playEndCallback.endEvaluat = playEnd_endEvalute
|
|
hideComplexButton(handleComplexButton, true);
|
|
hideComplexButton(handleComplexButton, true);
|
|
|
|
+ // 开始效验
|
|
|
|
+ checkEvaluating()
|
|
})
|
|
})
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
onBeforeUnmount(() => {
|
|
- runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('play', timeupdate)
|
|
|
|
- runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('timeupdate', onProgress)
|
|
|
|
|
|
+ // runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('play', timeupdate)
|
|
|
|
+ // runtime.audiosInstance?.audios[playUrl.value]?.removeEventListener('timeupdate', onProgress)
|
|
// RuntimeUtils.event.off('next-click', playerStop)
|
|
// RuntimeUtils.event.off('next-click', playerStop)
|
|
RuntimeUtils.event.off('ended', endevent)
|
|
RuntimeUtils.event.off('ended', endevent)
|
|
RuntimeUtils.event.off('tickDestroy', cloudMetronome)
|
|
RuntimeUtils.event.off('tickDestroy', cloudMetronome)
|
|
@@ -690,6 +975,23 @@ export default defineComponent({
|
|
<Vue3Lottie class={styles.inRadioIcon} animationData={startingData}></Vue3Lottie>
|
|
<Vue3Lottie class={styles.inRadioIcon} animationData={startingData}></Vue3Lottie>
|
|
</div>
|
|
</div>
|
|
)}
|
|
)}
|
|
|
|
+
|
|
|
|
+ {/* 延迟检测窗口 */}
|
|
|
|
+ <Popup
|
|
|
|
+ teleport="body"
|
|
|
|
+ class="popup-scale"
|
|
|
|
+ transition="van-scale"
|
|
|
|
+ overlay={false}
|
|
|
|
+ show={delayData.open}
|
|
|
|
+ onClose={() => handleCheckDelayEnd()}
|
|
|
|
+ >
|
|
|
|
+ <CheckDelayPopup
|
|
|
|
+ delayData={delayData}
|
|
|
|
+ onStartCheckDelay={() => handleStartCheckDelay()}
|
|
|
|
+ onClose={() => handleStopCheckDelay()}
|
|
|
|
+ onBack={() => handleDelayBack()}
|
|
|
|
+ />
|
|
|
|
+ </Popup>
|
|
</Teleport>
|
|
</Teleport>
|
|
)
|
|
)
|
|
}
|
|
}
|