fix(frontend): 同じ音源は短時間で重複して流れないように (MisskeyIO#556)

This commit is contained in:
まっちゃとーにゅ 2024-03-21 12:41:42 +09:00 committed by GitHub
parent eb884721bb
commit 9a65c8ca61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -6,10 +6,10 @@
import type { SoundStore } from '@/store.js'; import type { SoundStore } from '@/store.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import { $i } from '@/account.js'; import { $i } from '@/account.js';
import { RateLimiter } from '@/scripts/rate-limiter.js';
let ctx: AudioContext; let ctx: AudioContext;
const cache = new Map<string, AudioBuffer>(); const cache = new Map<string, AudioBuffer>();
let canPlay = true;
export const soundsTypes = [ export const soundsTypes = [
// 音声なし // 音声なし
@ -188,17 +188,13 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
*/ */
export function playMisskeySfx(operationType: OperationType) { export function playMisskeySfx(operationType: OperationType) {
const sound = defaultStore.state[`sound_${operationType}`]; const sound = defaultStore.state[`sound_${operationType}`];
if (sound.type == null || !canPlay || ('userActivation' in navigator && !navigator.userActivation.hasBeenActive)) return; if (sound.type == null || ('userActivation' in navigator && !navigator.userActivation.hasBeenActive)) return;
canPlay = false; playMisskeySfxFile(sound);
playMisskeySfxFile(sound).finally(() => {
// ごく短時間に音が重複しないように
setTimeout(() => {
canPlay = true;
}, 25);
});
} }
const rateLimiter = new RateLimiter<string>({ duration: 50, max: 1 });
/** /**
* *
* @param soundStore * @param soundStore
@ -213,7 +209,7 @@ export async function playMisskeySfxFile(soundStore: SoundStore) {
} }
const url = soundStore.type === '_driveFile_' ? soundStore.fileUrl : `/client-assets/sounds/${soundStore.type}.mp3`; const url = soundStore.type === '_driveFile_' ? soundStore.fileUrl : `/client-assets/sounds/${soundStore.type}.mp3`;
const buffer = await loadAudio(url); const buffer = await loadAudio(url);
if (!buffer) return; if (!buffer || !rateLimiter.hit(url)) return;
const volume = soundStore.volume * masterVolume; const volume = soundStore.volume * masterVolume;
createSourceNode(buffer, { volume }).soundSource.start(); createSourceNode(buffer, { volume }).soundSource.start();
} }