|
@@ -12,21 +12,23 @@ import state, { IPlayState, onEnded, onPlay } from "/src/state";
|
|
|
import { api_playProgress, api_cloudTimeUpdae, api_cloudplayed, api_remove_cloudplayed, api_remove_cloudTimeUpdae } from "/src/helpers/communication";
|
|
|
import { evaluatingData } from "/src/view/evaluating";
|
|
|
import { cloudToggleState } from "/src/helpers/midiPlay"
|
|
|
-import { metronomeData } from "../../helpers/metronome";
|
|
|
-import Crunker from "../../utils/crunker"
|
|
|
-const crunker = new Crunker()
|
|
|
-import tickWav from "/src/assets/tick.mp3";
|
|
|
-import tockWav from "/src/assets/tock.mp3";
|
|
|
import Loading from "./loading"
|
|
|
|
|
|
export const audioData = reactive({
|
|
|
- songEle: null as unknown as HTMLAudioElement,
|
|
|
- backgroundEle: null as unknown as HTMLAudioElement,
|
|
|
- songCollection: { // 音乐源合集 beatSongEle和bateBackgroundEle是带节拍的音乐源 评测模式的时候用
|
|
|
- songEle: null as unknown as HTMLAudioElement,
|
|
|
- backgroundEle: null as unknown as HTMLAudioElement,
|
|
|
- beatSongEle: null as unknown as HTMLAudioElement,
|
|
|
- bateBackgroundEle: null as unknown as HTMLAudioElement,
|
|
|
+ songEle: null as HTMLAudioElement | null, // 原生
|
|
|
+ backgroundEle: null as HTMLAudioElement | null, //伴唱
|
|
|
+ mingSongEle: null as HTMLAudioElement | null, //唱名
|
|
|
+ songCollection: { // 音乐源合集 带节拍器和不带节拍器的
|
|
|
+ songEle: null as HTMLAudioElement | null,
|
|
|
+ backgroundEle: null as HTMLAudioElement | null,
|
|
|
+ fanSongEle: null as HTMLAudioElement | null,
|
|
|
+ banSongEle: null as HTMLAudioElement | null,
|
|
|
+ mingSongEle: null as HTMLAudioElement | null,
|
|
|
+ beatSongEle: null as HTMLAudioElement | null,
|
|
|
+ betaBackgroundEle: null as HTMLAudioElement | null,
|
|
|
+ betaFanSongEle: null as HTMLAudioElement | null,
|
|
|
+ betaBanSongEle: null as HTMLAudioElement | null,
|
|
|
+ betaMingSongEle: null as HTMLAudioElement | null
|
|
|
},
|
|
|
midiRender: false,
|
|
|
progress: 0, // midi播放进度(单位:秒)
|
|
@@ -49,9 +51,11 @@ export const audioListStart = (type: "play" | "paused") => {
|
|
|
if (type === "play") {
|
|
|
audioData.songEle?.play();
|
|
|
audioData.backgroundEle?.play();
|
|
|
+ audioData.mingSongEle?.play();
|
|
|
} else if (type === "paused") {
|
|
|
audioData.songEle?.pause();
|
|
|
audioData.backgroundEle?.pause();
|
|
|
+ audioData.mingSongEle?.pause();
|
|
|
}
|
|
|
};
|
|
|
/** 设置倍数播放 */
|
|
@@ -64,6 +68,7 @@ export const setAudioPlaybackRate = (rate: number) => {
|
|
|
}
|
|
|
audioData.songEle && (audioData.songEle.playbackRate = rate);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.playbackRate = rate);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.playbackRate = rate);
|
|
|
};
|
|
|
|
|
|
/** 获取当前播放的时间 */
|
|
@@ -76,6 +81,7 @@ export const getAudioCurrentTime = () => {
|
|
|
// console.log('返回的时间',state.playSource, audioData.songEle?.currentTime,audioData.progress)
|
|
|
if (state.playSource === "music") return audioData.songEle?.currentTime || audioData.progress;
|
|
|
if (state.playSource === "background") return audioData.backgroundEle?.currentTime || audioData.progress;
|
|
|
+ if (state.playSource === "mingSong") return audioData.mingSongEle?.currentTime || audioData.progress;
|
|
|
|
|
|
return audioData.songEle?.currentTime || audioData.progress;
|
|
|
};
|
|
@@ -87,7 +93,7 @@ export const getAudioDuration = () => {
|
|
|
const songEndTime = state.times[state.times.length - 1 || 0]?.endtime || 0
|
|
|
return audioData.duration || songEndTime;
|
|
|
}
|
|
|
- return audioData.songEle?.duration || audioData.backgroundEle?.duration || audioData.duration;
|
|
|
+ return audioData.songEle?.duration || audioData.backgroundEle?.duration || audioData.mingSongEle?.duration || audioData.duration;
|
|
|
};
|
|
|
|
|
|
/** 设置播放的开始时间 */
|
|
@@ -100,6 +106,7 @@ export const setAudioCurrentTime = (time: number, index = 0) => {
|
|
|
}
|
|
|
audioData.songEle && (audioData.songEle.currentTime = time);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.currentTime = time);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.currentTime = time);
|
|
|
audioData.progress = time;
|
|
|
};
|
|
|
|
|
@@ -113,46 +120,55 @@ export const toggleMutePlayAudio = (source: IPlayState, muted: boolean) => {
|
|
|
if (audioData.backgroundEle) {
|
|
|
audioData.backgroundEle.muted = muted;
|
|
|
}
|
|
|
+ } else if(source === "mingSong"){
|
|
|
+ if (audioData.mingSongEle) {
|
|
|
+ audioData.mingSongEle.muted = muted;
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-/** 检测音源数量 */
|
|
|
-export const detectTheNumberOfSoundSources = () => {
|
|
|
- let total = 0;
|
|
|
- if (audioData.songEle) total += 1;
|
|
|
- if (audioData.backgroundEle) total += 1;
|
|
|
- return total;
|
|
|
-};
|
|
|
-
|
|
|
/** 切换节拍器音源 */
|
|
|
export const changeSongSourceByBate = (isDisBate:boolean) => {
|
|
|
// isDisBate 为true 切换到不带节拍的,为false 切换到带节拍的
|
|
|
- if(audioData.songCollection.songEle && audioData.songCollection.beatSongEle){
|
|
|
- const songEleCurrentTime = audioData.songEle.currentTime
|
|
|
- console.log("当前音乐时间:",songEleCurrentTime)
|
|
|
- if(isDisBate){
|
|
|
+ const songEleCurrentTime = audioData.songEle?.currentTime || 0
|
|
|
+ const backgroundEleCurrentTime = audioData.backgroundEle?.currentTime || 0
|
|
|
+ const mingSongEleCurrentTime = audioData.mingSongEle?.currentTime || 0
|
|
|
+ if (isDisBate) {
|
|
|
+ if(state.playType === "play"){
|
|
|
audioData.songEle = audioData.songCollection.songEle
|
|
|
- audioData.songEle.currentTime = songEleCurrentTime
|
|
|
- if(audioData.songCollection.backgroundEle){
|
|
|
- audioData.backgroundEle = audioData.songCollection.backgroundEle
|
|
|
- audioData.backgroundEle.currentTime = songEleCurrentTime
|
|
|
- }
|
|
|
- }else{
|
|
|
- audioData.songEle = audioData.songCollection.beatSongEle
|
|
|
- audioData.songEle.currentTime = songEleCurrentTime
|
|
|
- if(audioData.songCollection.bateBackgroundEle){
|
|
|
- audioData.backgroundEle = audioData.songCollection.bateBackgroundEle
|
|
|
- audioData.backgroundEle.currentTime = songEleCurrentTime
|
|
|
- }
|
|
|
+ audioData.backgroundEle = audioData.songCollection.backgroundEle
|
|
|
+ } else {
|
|
|
+ audioData.songEle = audioData.songCollection.fanSongEle
|
|
|
+ audioData.backgroundEle = audioData.songCollection.banSongEle
|
|
|
+ audioData.mingSongEle = audioData.songCollection.mingSongEle
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 没有节拍器资源的时候 用 不带节拍器的资源,防止播放不了
|
|
|
+ if(state.playType === "play"){
|
|
|
+ audioData.songEle = audioData.songCollection.beatSongEle || audioData.songCollection.songEle
|
|
|
+ audioData.backgroundEle = audioData.songCollection.betaBackgroundEle || audioData.songCollection.backgroundEle
|
|
|
+ } else {
|
|
|
+ audioData.songEle = audioData.songCollection.betaFanSongEle || audioData.songCollection.fanSongEle
|
|
|
+ audioData.backgroundEle = audioData.songCollection.betaBanSongEle || audioData.songCollection.banSongEle
|
|
|
+ audioData.mingSongEle = audioData.songCollection.betaMingSongEle || audioData.songCollection.mingSongEle
|
|
|
}
|
|
|
}
|
|
|
+ audioData.songEle && (audioData.songEle.currentTime = songEleCurrentTime)
|
|
|
+ audioData.backgroundEle && (audioData.backgroundEle.currentTime = backgroundEleCurrentTime)
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.currentTime = mingSongEleCurrentTime)
|
|
|
// 设置静音与取消静音
|
|
|
if (state.playSource === "music") {
|
|
|
audioData.songEle && (audioData.songEle.muted = false);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.muted = true);
|
|
|
- } else {
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = true);
|
|
|
+ } else if (state.playSource === "background") {
|
|
|
audioData.songEle && (audioData.songEle.muted = true);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.muted = false);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = true);
|
|
|
+ }else {
|
|
|
+ audioData.songEle && (audioData.songEle.muted = true);
|
|
|
+ audioData.backgroundEle && (audioData.backgroundEle.muted = true);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = false);
|
|
|
}
|
|
|
}
|
|
|
export default defineComponent({
|
|
@@ -176,9 +192,15 @@ export default defineComponent({
|
|
|
if (state.playSource === "music") {
|
|
|
audioData.songEle && (audioData.songEle.muted = false);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.muted = true);
|
|
|
- } else {
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = true);
|
|
|
+ } else if (state.playSource === "background") {
|
|
|
audioData.songEle && (audioData.songEle.muted = true);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.muted = false);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = true);
|
|
|
+ }else {
|
|
|
+ audioData.songEle && (audioData.songEle.muted = true);
|
|
|
+ audioData.backgroundEle && (audioData.backgroundEle.muted = true);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.muted = false);
|
|
|
}
|
|
|
}
|
|
|
);
|
|
@@ -203,6 +225,7 @@ export default defineComponent({
|
|
|
audioData.progress = time;
|
|
|
audioData.songEle && (audioData.songEle.currentTime = time);
|
|
|
audioData.backgroundEle && (audioData.backgroundEle.currentTime = time);
|
|
|
+ audioData.mingSongEle && (audioData.mingSongEle.currentTime = time);
|
|
|
audioData.duration = total / 1000;
|
|
|
if (
|
|
|
res?.content?.totalDuration > 1000 &&
|
|
@@ -245,77 +268,28 @@ export default defineComponent({
|
|
|
onEnded();
|
|
|
}
|
|
|
}
|
|
|
- // 合成节拍器音源
|
|
|
- function loadMergeAudioBetas() {
|
|
|
- console.time("音频加载时间")
|
|
|
- const audioList = [state.music+'?v='+Date.now()]
|
|
|
- if(state.accompany){ // 可能存在没有伴奏的音源
|
|
|
- audioList.push(state.accompany+'?v='+Date.now())
|
|
|
- }
|
|
|
- return crunker.fetchAudio(tickWav, tockWav, ...audioList).then(([tickWavBuff,tockWavBuff,musicBuff,accompanyBuff])=>{
|
|
|
- console.timeEnd("音频加载时间")
|
|
|
- // 计算音频空白时间
|
|
|
- const silenceDuration = crunker.calculateSilenceDuration(musicBuff)
|
|
|
- const silenceBgDuration = accompanyBuff && crunker.calculateSilenceDuration(accompanyBuff)
|
|
|
- console.log(`音频空白时间:${silenceDuration},${silenceBgDuration}`)
|
|
|
- const beats:AudioBuffer[] = []
|
|
|
- const beatsTime:number[] = []
|
|
|
- const beatsBgTime:number[] = []
|
|
|
- metronomeData.metroMeasure.map(Measures=>{
|
|
|
- Measures.map((item:any)=>{
|
|
|
- beats.push(item.index===0?tickWavBuff:tockWavBuff)
|
|
|
- beatsTime.push(item.time + silenceDuration) // xml 计算的时候 加上空白的时间
|
|
|
- accompanyBuff && beatsBgTime.push(item.time + silenceBgDuration) // xml 计算的时候 加上空白的时间
|
|
|
- })
|
|
|
- })
|
|
|
- //合并
|
|
|
- console.time("音频合并时间")
|
|
|
- const musicBuffMeg = crunker.mergeAudioBuffers([musicBuff,...beats],[0,...beatsTime])
|
|
|
- const accompanyBuffMeg = accompanyBuff && crunker.mergeAudioBuffers([accompanyBuff,...beats],[0,...beatsBgTime])
|
|
|
- console.timeEnd("音频合并时间")
|
|
|
- return [musicBuffMeg,accompanyBuffMeg]
|
|
|
- }).then(([musicBuffMeg,accompanyBuffMeg])=>{
|
|
|
- console.time("音频audioDom生成时间")
|
|
|
- const musicAudio = crunker.exportAudioElement(musicBuffMeg)
|
|
|
- const accompanyAudio = accompanyBuffMeg && crunker.exportAudioElement(accompanyBuffMeg)
|
|
|
- console.timeEnd("音频audioDom生成时间")
|
|
|
- return [musicAudio,accompanyAudio]
|
|
|
- })
|
|
|
- }
|
|
|
- // 加载普通音源
|
|
|
+ // 加载音源
|
|
|
function loadAudio(){
|
|
|
- return Promise.all([createAudio(state.music), createAudio(state.accompany)])
|
|
|
+ return Promise.all([createAudio(state.music), createAudio(state.accompany), createAudio(state.fanSong), createAudio(state.banSong), createAudio(state.mingSong)])
|
|
|
+ }
|
|
|
+ // 加载节拍器音源
|
|
|
+ function loadBeatAudio(){
|
|
|
+ return Promise.all([createAudio(state.beatSong.music), createAudio(state.beatSong.accompany), createAudio(state.beatSong.fanSong), createAudio(state.beatSong.banSong), createAudio(state.beatSong.mingSong)])
|
|
|
}
|
|
|
onMounted(async () => {
|
|
|
if (state.playMode !== "MIDI") {
|
|
|
- console.time("加载资源耗时")
|
|
|
- // 不带节拍的音源
|
|
|
- const [music, accompany] = await loadAudio()
|
|
|
- try {
|
|
|
- // 带节拍的音源
|
|
|
- const [musicAudio,accompanyAudio] = await loadMergeAudioBetas()
|
|
|
- console.log("音频合成成功66666666")
|
|
|
- state.audioBetaDone = true;
|
|
|
- if (musicAudio) {
|
|
|
- musicAudio.addEventListener("play", onPlay);
|
|
|
- musicAudio.addEventListener("ended", onEnded);
|
|
|
- accompanyAudio && (accompanyAudio.muted = true);
|
|
|
- } else if (accompanyAudio) {
|
|
|
- accompanyAudio.addEventListener("play", onPlay);
|
|
|
- accompanyAudio.addEventListener("ended", onEnded);
|
|
|
- }
|
|
|
- Object.assign(audioData.songCollection,{
|
|
|
- songEle:music,
|
|
|
- backgroundEle:accompany,
|
|
|
- beatSongEle:musicAudio,
|
|
|
- bateBackgroundEle:accompanyAudio
|
|
|
- })
|
|
|
- } catch (err) {
|
|
|
- console.log("音频合成失败7777777:",err)
|
|
|
- }
|
|
|
- state.audioDone = true;
|
|
|
- audioData.backgroundEle = accompany!;
|
|
|
- audioData.songEle = music!;
|
|
|
+ console.time("音频加载时间")
|
|
|
+ // 处理音源
|
|
|
+ const [music, accompany, fanSong, banSong, mingSong] = await loadAudio()
|
|
|
+ audioData.backgroundEle = accompany;
|
|
|
+ audioData.songEle = music;
|
|
|
+ Object.assign(audioData.songCollection, {
|
|
|
+ songEle:music,
|
|
|
+ backgroundEle:accompany,
|
|
|
+ fanSongEle:fanSong,
|
|
|
+ banSongEle:banSong,
|
|
|
+ mingSongEle:mingSong
|
|
|
+ })
|
|
|
if (music) {
|
|
|
music.addEventListener("play", onPlay);
|
|
|
music.addEventListener("ended", onEnded);
|
|
@@ -324,7 +298,52 @@ export default defineComponent({
|
|
|
accompany.addEventListener("play", onPlay);
|
|
|
accompany.addEventListener("ended", onEnded);
|
|
|
}
|
|
|
- console.timeEnd("加载资源耗时")
|
|
|
+ if(fanSong){
|
|
|
+ fanSong.addEventListener("play", onPlay);
|
|
|
+ fanSong.addEventListener("ended", onEnded);
|
|
|
+ banSong && (banSong.muted = true);
|
|
|
+ mingSong && (mingSong.muted = true);
|
|
|
+ }else if(banSong){
|
|
|
+ banSong.addEventListener("play", onPlay);
|
|
|
+ banSong.addEventListener("ended", onEnded);
|
|
|
+ mingSong && (mingSong.muted = true);
|
|
|
+ } else if(mingSong){
|
|
|
+ mingSong.addEventListener("play", onPlay);
|
|
|
+ mingSong.addEventListener("ended", onEnded);
|
|
|
+ }
|
|
|
+ // 处理带节拍器的音源
|
|
|
+ const [beatMusic, beatAccompany, beatFanSong, beatBanSong, beatMingSong] = await loadBeatAudio()
|
|
|
+ Object.assign(audioData.songCollection, {
|
|
|
+ beatSongEle:beatMusic,
|
|
|
+ betaBackgroundEle:beatAccompany,
|
|
|
+ betaFanSongEle:beatFanSong,
|
|
|
+ betaBanSongEle:beatBanSong,
|
|
|
+ betaMingSongEle:beatMingSong
|
|
|
+ })
|
|
|
+ if (beatMusic) {
|
|
|
+ beatMusic.addEventListener("play", onPlay);
|
|
|
+ beatMusic.addEventListener("ended", onEnded);
|
|
|
+ beatAccompany && (beatAccompany.muted = true);
|
|
|
+ } else if (beatAccompany) {
|
|
|
+ beatAccompany.addEventListener("play", onPlay);
|
|
|
+ beatAccompany.addEventListener("ended", onEnded);
|
|
|
+ }
|
|
|
+ if(beatFanSong){
|
|
|
+ beatFanSong.addEventListener("play", onPlay);
|
|
|
+ beatFanSong.addEventListener("ended", onEnded);
|
|
|
+ beatBanSong && (beatBanSong.muted = true);
|
|
|
+ beatMingSong && (beatMingSong.muted = true);
|
|
|
+ }else if(beatBanSong){
|
|
|
+ beatBanSong.addEventListener("play", onPlay);
|
|
|
+ beatBanSong.addEventListener("ended", onEnded);
|
|
|
+ beatMingSong && (beatMingSong.muted = true);
|
|
|
+ } else if(beatMingSong){
|
|
|
+ beatMingSong.addEventListener("play", onPlay);
|
|
|
+ beatMingSong.addEventListener("ended", onEnded);
|
|
|
+ }
|
|
|
+ state.audioDone = true;
|
|
|
+ console.timeEnd("音频加载时间")
|
|
|
+ console.log("音频数据:",audioData)
|
|
|
api_playProgress(progress);
|
|
|
} else {
|
|
|
state.audioDone = true;
|