Просмотр исходного кода

feat: 节拍器使用HTMLAudio播放

TIANYONG 1 год назад
Родитель
Сommit
b484766f94
2 измененных файлов с 60 добавлено и 15 удалено
  1. 51 12
      src/helpers/metronome.ts
  2. 9 3
      src/view/tick/index.tsx

+ 51 - 12
src/helpers/metronome.ts

@@ -9,12 +9,21 @@ import { browser } from "/src/utils/index";
 import state from "/src/state";
 import { Howl } from "howler";
 import tockAndTick from "/src/constant/tockAndTick.json";
+import tickWav from "/src/assets/tick.wav";
+import tockWav from "/src/assets/tock.wav";
+
 type IOptions = {
 	speed: number;
 };
 const browserInfo = browser();
 let tipsTimer: any = null; // 光标提示定时器
 
+// HTMLAudioElement 音频
+const audioData = reactive({
+	tick: null as unknown as HTMLAudioElement,
+	tock: null as unknown as HTMLAudioElement,
+});
+
 export const metronomeData = reactive({
 	disable: true,
 	initPlayerState: false,
@@ -101,14 +110,38 @@ class Metronome {
 		metronomeData.activeList = [];
 	}
 	initPlayer() {
-		if (!this.source1) {
-			this.source1 = this.loadAudio1();
-		}
-		if (!this.source2) {
-			this.source2 = this.loadAudio2();
-		}
-		metronomeData.initPlayerState = true;
+		// if (!this.source1) {
+		// 	this.source1 = this.loadAudio1();
+		// }
+		// if (!this.source2) {
+		// 	this.source2 = this.loadAudio2();
+		// }
+		// metronomeData.initPlayerState = true;
+
+		Promise.all([this.createAudio(tickWav), this.createAudio(tockWav)]).then(
+			([tick, tock]) => {
+				if (tick) {
+					audioData.tick = tick;
+				}
+				if (tock) {
+					audioData.tock = tock;
+				}
+				metronomeData.initPlayerState = true;
+			}
+		);		
 	}
+	createAudio = (src: string): Promise<HTMLAudioElement | null> => {
+		return new Promise((resolve) => {
+			const a = new Audio(src + '?v=' + Date.now());
+			a.load();
+			a.onloadedmetadata = () => {
+				resolve(a);
+			};
+			a.onerror = () => {
+				resolve(null);
+			};
+		});
+	};
 
 	// 播放
 	sound = (currentTime: number) => {
@@ -144,8 +177,11 @@ class Metronome {
 	playAudio = () => {
 		if (!metronomeData.initPlayerState) return;
 		const beatVolume = state.setting.beatVolume / 100
-		this.source = metronomeData.activeMetro?.index === 0 ? this.source1 : this.source2;
-		this.source.volume(metronomeData.disable || state.playState === 'paused' ? 0 : beatVolume);
+		// this.source = metronomeData.activeMetro?.index === 0 ? this.source1 : this.source2;
+		// this.source.volume(metronomeData.disable || state.playState === 'paused' ? 0 : beatVolume);
+		// Audio 播放音频
+		this.source = metronomeData.activeMetro?.index === 0 ? audioData.tick : audioData.tock;
+		this.source.volume = metronomeData.disable || state.playState === 'paused' ? 0 : beatVolume;
 		this.source.play();
 	};
 
@@ -153,11 +189,14 @@ class Metronome {
 	 * 跟练模式播放,跟练模式没有曲子音频播放器
 	 */
 	simulatePlayAudio = () => {
-		// console.log(333, metronomeData.followAudioIndex)
+		console.log(333, metronomeData.followAudioIndex)
 		if (!metronomeData.initPlayerState) return;
 		const beatVolume = state.setting.beatVolume / 100
-		this.source = metronomeData.followAudioIndex === 1 ? this.source1 : this.source2;
-		this.source.volume(metronomeData.disable ? 0 : beatVolume);
+		// this.source = metronomeData.followAudioIndex === 1 ? this.source1 : this.source2;
+		// Audio 播放音频
+		this.source = metronomeData.followAudioIndex === 1 ? audioData.tick : audioData.tock;
+		// this.source.volume(metronomeData.disable ? 0 : beatVolume);
+		this.source.volume = metronomeData.disable ? 0 : beatVolume
 		this.source.play();
 		metronomeData.followAudioIndex += 1;
 		metronomeData.followAudioIndex = metronomeData.followAudioIndex > metronomeData.totalNumerator ? 1 : metronomeData.followAudioIndex;

+ 9 - 3
src/view/tick/index.tsx

@@ -30,7 +30,11 @@ const handlePlay = (i: number, source: any | null) => {
 				return
 			};
 			tickData.index++;
-			if (source) source.play();
+			if (source) {
+				const beatVolume = state.setting.beatVolume / 100
+				source.volume = beatVolume;
+				source.play();
+			}
 			resolve(i);
 		}, tickData.beatLengthInMilliseconds);
 	});
@@ -86,8 +90,10 @@ export const handleStartTick = async () => {
 	for(let i = 0; i <= tickData.len; i++){
 		// 提前结束, 直接放回false
 		if (tickData.tickEnd) return false;
-		const source = i === 0 ? tickData.source1 : i === tickData.len ? null : tickData.source2;
-		// const source = i === 0 ? audioData.tick : i === tickData.len ? null : audioData.tock;
+		// Howl 插件播放音频
+		// const source = i === 0 ? tickData.source1 : i === tickData.len ? null : tickData.source2;
+		// Audio 标签播放音频
+		const source = i === 0 ? audioData.tick : i === tickData.len ? null : audioData.tock;
 		await handlePlay(i, source)
 	}
 	tickData.show = false;