import { defineComponent, onMounted, onUnmounted, reactive, nextTick } from "vue"; import state, { getMusicDetail, handleSetSpeed, addNoteBBox, getNote, gotoNext, fillWordColor } from "/src/state"; import MusicScore from "../../view/music-score"; import styles from "./index.module.less"; import { getQuery } from "/src/utils/queryString"; import { closeToast, showLoadingToast } from "vant"; import store from "store"; import { formateTimes } from "../../helpers/formateMusic"; import { setCustomGradual, setCustomNoteRealValue } from "/src/helpers/customMusicScore" import { initSmoothAnimation, smoothAnimationState, destroySmoothAnimation, moveSmoothAnimationByPlayTime } from "../view-detail/smoothAnimation"; import { api_cloudLoading, simple_musicPage } from "/src/helpers/communication"; export default defineComponent({ name: "simple-detail", setup() { const query: any = getQuery(); const detailData = reactive({ isLoading: true, currentTime: 0, // 当前播放的时间 totalTime: 0, // 音视频总时长 }); const communicateCb = (res: any) => { let resInfo: any = {}; try { resInfo = typeof res?.data === 'string' ? JSON.parse(res.data) : res.data; // console.log('Received data:', resInfo); } catch (error) { console.error('parse_error: Invalid JSON data received'); } // 开始播放 if (resInfo?.api === "api_play") { console.log('h5开始播放') state.playState = 'play'; setStep(); } // 暂停播放 if (resInfo?.api === "api_paused") { console.log('暂停播放') state.playState = 'paused'; } // 暂停状态下,拖动进度 if (resInfo?.api === "api_updateProgress") { console.log('拖动的进度') if (state.playState === 'paused') { detailData.currentTime = resInfo?.content?.currentTime ? resInfo?.content?.currentTime : detailData.currentTime; handlePlaying(true); } } // 播放进度 if (resInfo?.api === "api_playProgress") { // console.log('播放进度',resInfo) if (resInfo?.content?.currentTime) { if (resInfo?.content?.currentTime < detailData.currentTime) { state.activeNoteIndex = 0 } detailData.currentTime = resInfo?.content?.currentTime } } }; // 监听评测曲谱音频播放进度,返回 const progress = (res: any) => { console.log('app播放进度',res) const currentTime = res?.currentTime || res?.content?.currentTime; if (currentTime) { if (currentTime < detailData.currentTime) { state.activeNoteIndex = 0 } detailData.currentTime = currentTime } }; onMounted(async () => { const id = query.id || ''; state.isSimplePage = true; await getMusicDetail(id, 'open'); detailData.isLoading = false; state.isSingleLine = true; window.addEventListener("message", communicateCb); }); onUnmounted(() => { state.isSimplePage = false; window.removeEventListener("message", communicateCb); }); /** 渲染完成 */ const handleRendered = async (osmd: any) => { const svgHeight = document.getElementById('scrollContainer')?.getBoundingClientRect().height; state.osmd = osmd; // 没有设置速度使用读取的速度 if (state.originSpeed === 0) { state.originSpeed = state.speed = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM || 100; } const saveSpeed = (store.get("speeds") || {})[state.examSongId] || state.speed || (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM; // 加载本地缓存的速度 if (saveSpeed) { handleSetSpeed(saveSpeed); } setCustomGradual(); setCustomNoteRealValue(); state.times = formateTimes(osmd); console.log("🚀 ~ state.times:", state.times, state); nextTick(() => { state.activeMeasureIndex = state.times[0].MeasureNumberXML; fillWordColor(); }) // 音符添加位置信息bbox addNoteBBox(state.times); // 一行谱创建 动画 initSmoothAnimation(); //destroySmoothAnimation(); //smoothAnimationState.isShow.value = false; api_cloudLoading(); console.log('渲染完成',svgHeight) window.parent.postMessage( { api: "api_musicPage", height: svgHeight }, "*" ); simple_musicPage({ height: svgHeight }) // state.playState = 'play'; // setStep(); }; /** * 播放一直触发的事件 */ const handlePlaying = (skipNote?: boolean) => { //detailData.currentTime += 0.03 const currentTime = detailData.currentTime; // console.log('👀~播放进度',currentTime) let item = getNote(currentTime); if (item) { gotoNext(item, skipNote); } state.activeNoteIndex = item?.i || 0 // 一行谱,需要滚动小节 if (state.isSingleLine) { moveSmoothAnimationByPlayTime(currentTime) } }; /** 在渲染前后计算光标应该走到的音符 */ const setStep = () => { // console.log('播放状态',state.playState) if (state.playState !== "play") { console.log("暂停播放"); return; } let startTime = Date.now(); requestAnimationFrame(() => { const endTime = Date.now(); // 渲染时间大于16.6,就会让页面卡顿, 如果渲染时间大与16.6就下一个渲染帧去计算 if (endTime - startTime < 16.7) { handlePlaying(); setStep(); } else { setTimeout(() => { handlePlaying(); setStep(); }, 16.7); } }); }; return () => (