feat: shared player with 6s cap, progress bar, stop button
Deploy / build-and-deploy (push) Successful in 1m43s

This commit is contained in:
2026-06-15 02:17:46 +03:00
parent 2dd604192f
commit 0c35693598
5 changed files with 167 additions and 48 deletions
+14 -43
View File
@@ -1,4 +1,4 @@
import { Howl } from "howler";
import { playUrl, stopCurrent } from "@/lib/player";
let audioCtx: AudioContext | null = null;
@@ -109,57 +109,28 @@ export function playChaosRiser() {
});
}
// ─── Howl-based URL playback ──────────────────────────────────────
const howlCache = new Map<string, Howl>();
// ─── URL playback via shared player ──────────────────────────────
/**
* Play a sound file URL (MP3/OGG) using howler.js.
* Howler handles autoplay policy, cross-browser codec support,
* and AudioContext resume better than raw new Audio().
* Play a sound file URL (MP3/OGG). Goes through the shared player,
* which caps at 6s with fadeout and shows playback UI.
*/
export function playSoundUrl(url: string) {
let h = howlCache.get(url);
if (!h) {
const newH = new Howl({
src: [url],
format: url.endsWith(".mp3") ? ["mp3"] : url.endsWith(".ogg") ? ["ogg"] : ["mp3", "ogg"],
volume: 0.4,
onloaderror: (_id: number, err: unknown) => {
console.error("[BaraBingo] Howl load error:", url, err);
},
onplayerror: (_id: number, err: unknown) => {
console.error("[BaraBingo] Howl play error:", url, err);
newH.once("unlock", () => newH.play());
},
});
howlCache.set(url, newH);
h = newH;
}
h.play();
export function playSoundUrl(url: string, name?: string) {
playUrl(url, name);
}
/**
* One-shot play of a sound URL. Same as playSoundUrl but always creates a fresh instance.
* Useful for preview/editor buttons where you want it to play every click.
* One-shot play with a display name. Same underlying player.
*/
export function playSoundOnce(url: string) {
const h = new Howl({
src: [url],
format: url.endsWith(".mp3") ? ["mp3"] : url.endsWith(".ogg") ? ["ogg"] : ["mp3", "ogg"],
volume: 0.4,
onloaderror: (_id: number, err: unknown) => {
console.error("[BaraBingo] Howl load error:", url, err);
},
onplayerror: (_id: number, err: unknown) => {
console.error("[BaraBingo] Howl play error:", url, err);
// On play error (e.g. AudioContext suspended), unlock and retry
h.once("unlock", () => h.play());
},
});
h.play();
export function playSoundOnce(url: string, name?: string) {
playUrl(url, name);
}
/**
* Stop current playback immediately.
*/
export { stopCurrent, getPlaybackState, subscribe } from "@/lib/player";
export function playSound(category: string, soundUrl?: string | null) {
if (soundUrl) {
playSoundUrl(soundUrl);