import { Skeleton } from "vant"; import { computed, defineComponent, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, Transition, watch, watchEffect } from "vue"; import { useRoute } from "vue-router"; import { formateTimes } from "../../helpers/formateMusic"; import Metronome, { metronomeData } from "../../helpers/metronome"; import state, { isRhythmicExercises } from "../../state"; import { storeData } from "../../store"; import { setGlobalData } from "../../utils"; import AudioList from "../../view/audio-list"; import MusicScore, { resetMusicScore } from "../../view/music-score"; import { sysMusicScoreAccompanimentQueryPage } from "../api"; import EvaluatModel from "../evaluat-model"; import HeaderTop from "../header-top"; import styles from "./index.module.less"; import { api_cloudLoading, api_openCamera, api_setEventTracking, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication"; import { getQuery } from "/src/utils/queryString"; import Evaluating, { evaluatingData } from "/src/view/evaluating"; import MeasureSpeed from "/src/view/plugins/measure-speed"; import { mappingVoicePart, subjectFingering } from "/src/view/fingering/fingering-config"; import Fingering from "/src/view/fingering"; import store from "store"; import Tick, { handleInitTick } from "/src/view/tick"; import FollowPractice from "/src/view/follow-practice"; import FollowModel from "../follow-model"; import RecordingTime from "../custom-plugins/recording-time"; export default defineComponent({ name: "music-list", setup() { const query: any = getQuery(); const detailData = reactive({ isLoading: true, paddingLeft: "", headerHide: false, }); const getAPPData = async () => { const screenData = await isSpecialShapedScreen(); if (screenData?.content) { // console.log("🚀 ~ screenData:", screenData.content); const { isSpecialShapedScreen, notchHeight } = screenData.content; if (isSpecialShapedScreen) { detailData.paddingLeft = 25 + "px"; } } }; onBeforeMount(() => { getAPPData(); api_setStatusBarVisibility(); const settting = store.get("musicscoresetting"); if (settting) { state.setting = settting; if (state.setting.camera) { api_openCamera(); } // console.log("🚀 ~ settting:", settting) } }); // console.log(route.params, query) /** 获取曲谱数据 */ const getMusicInfo = (res: any) => { const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0; const musicInfo = { ...res.data, accompany: res.data.audioFileUrl, ...res.data.background[index], }; // console.log("🚀 ~ musicInfo:", musicInfo); setState(musicInfo, index); setCustom(); detailData.isLoading = false; }; const setState = (data: any, index: number) => { state.appName = "COLEXIU"; state.detailId = data.id; state.xmlUrl = data.xmlFileUrl; state.partIndex = index; state.subjectId = data.musicSubject; state.categoriesId = data.categoriesId; state.categoriesName = data.musicTagNames; state.enableEvaluation = data.canEvaluate ? true : false; state.examSongId = data.id + ""; state.examSongName = data.musicSheetName; // 解析扩展字段 if (data.extConfigJson) { try { state.extConfigJson = JSON.parse(data.extConfigJson as string); } catch (error) { console.error("解析扩展字段错误:", error); } } state.isOpenMetronome = data.mp3Type === "MP3_METRONOME" ? true : false; state.needTick = true; // data.isOpenMetronome; state.isShowFingering = data.showFingering ? true : false; state.music = data.audioFileUrl; state.accompany = data.accompany; state.midiUrl = data.midiUrl; state.parentCategoriesId = data.musicTag; state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI"; // state.originSpeed = state.speed = parseFloat(data.playSpeed) || 0; state.originSpeed = state.speed = data.playSpeed; state.track = data.track; state.enableNotation = data.notation ? true : false; // 映射声部ID state.subjectId = mappingVoicePart(state.track as any, "COLEXIU"); // 是否打击乐 state.isPercussion = state.subjectId == 23 || state.subjectId == 113 || state.subjectId == 121 || isRhythmicExercises(); // 设置指法 state.fingeringInfo = subjectFingering(state.subjectId); // console.log("🚀 ~ state.fingeringInfo:", state.fingeringInfo, state.subjectId, state.track) // 检测是否原音和伴奏都有 if (!state.music || !state.accompany) { state.playSource = state.music ? "music" : "background"; } }; const setCustom = () => { if (state.extConfigJson.multitrack) { setGlobalData("multitrack", state.extConfigJson.multitrack); } }; onMounted(() => { (window as any).appName = "colexiu"; Promise.all([sysMusicScoreAccompanimentQueryPage(query.id)]).then((values) => { getMusicInfo(values[0]); }); api_setEventTracking(); }); /** 渲染完成 */ const handleRendered = (osmd: any) => { state.musicRendered = true; state.osmd = osmd; const saveSpeed = (store.get("speeds") || {})[state.examSongId]; const bpm = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM; state.originSpeed = state.speed = saveSpeed || bpm || 100; state.times = formateTimes(osmd); console.log("🚀 ~ state.times:", state.times); try { metronomeData.metro = new Metronome(); metronomeData.metro.init(state.times); } catch (error) {} // 设置节拍器 if (state.needTick) { const beatLengthInMilliseconds = osmd?.Sheet?.SheetPlaybackSetting?.beatLengthInMilliseconds || (60 / bpm) * 1000; handleInitTick(beatLengthInMilliseconds, osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4); } api_cloudLoading(); }; /** 指法配置 */ const fingerConfig = computed(() => { if (state.setting.displayFingering && state.fingeringInfo?.name) { if (state.fingeringInfo.direction === "transverse") { return { container: { paddingBottom: state.fingeringInfo.height, }, fingerBox: { height: state.fingeringInfo.height, }, }; } else { return { container: { paddingRight: state.fingeringInfo.width, }, fingerBox: { position: "absolute", width: state.fingeringInfo.width, height: "100%", right: 0, top: 0, }, }; } } return { container: {}, fingerBox: {}, }; }); // 监听指法显示 watch( () => state.setting.displayFingering, () => { if (state.fingeringInfo.direction === "vertical") { nextTick(() => { resetMusicScore(); }); } } ); // 监听播放状态 watch( () => state.playState, () => { detailData.headerHide = state.playState === "play" ? true : false; } ); onMounted(() => { window.addEventListener("resize", resetMusicScore); }); onBeforeUnmount(() => { window.removeEventListener("resize", resetMusicScore); }); return () => (
{!state.musicRendered && (
)}
{state.musicRendered && }
{ if (state.playState === "play") { detailData.headerHide = !detailData.headerHide; } }} > {/* 曲谱渲染 */} {!detailData.isLoading && } {/* 播放 */} {!detailData.isLoading && } {/* 评测 */} {state.modeType === "evaluating" && ( <> {evaluatingData.rendered && } )} {/* 指法 */} {state.setting.displayFingering && state.fingeringInfo?.name && (
)}
{/* 公用的插件 */}
{state.musicRendered && ( <> {/* 统计训练时长 */} )}
{/* 节拍器 */} {state.needTick && } {/* 跟练模式 */} {state.modeType === "follow" && ( <> )}
); }, });