Buckets:
| import { Audio, type AudioErrorContext, type AudioPlayOptions, type AudioSound, type AudioVoice } from "@opentui/core" | |
| import { readFile } from "node:fs/promises" | |
| let audio: Audio | null | undefined | |
| const sounds = new Map<string, Promise<AudioSound | null>>() | |
| function getAudio() { | |
| if (audio !== undefined) return audio | |
| try { | |
| const next = Audio.create({ autoStart: false }) | |
| next.on("error", (error: Error, context: AudioErrorContext) => { | |
| console.debug("tui audio error", { error, context }) | |
| }) | |
| audio = next | |
| return next | |
| } catch (error) { | |
| console.debug("failed to create tui audio", { error }) | |
| audio = null | |
| return null | |
| } | |
| } | |
| export function loadSoundFile(file: string) { | |
| const current = getAudio() | |
| if (!current) return Promise.resolve(null) | |
| const cached = sounds.get(file) | |
| if (cached) return cached | |
| const task = readFile(file) | |
| .then((bytes) => current.loadSound(bytes)) | |
| .catch((error) => { | |
| console.debug("failed to load tui sound", { file, error }) | |
| return null | |
| }) | |
| sounds.set(file, task) | |
| return task | |
| } | |
| export function play(sound: AudioSound, options?: AudioPlayOptions) { | |
| const current = getAudio() | |
| if (!current) return null | |
| if (!current.isStarted() && !current.start()) return null | |
| return current.play(sound, options) | |
| } | |
| export function stopVoice(voice: AudioVoice) { | |
| return audio?.stopVoice(voice) ?? false | |
| } | |
| export function dispose() { | |
| audio?.dispose() | |
| audio = undefined | |
| sounds.clear() | |
| } | |
Xet Storage Details
- Size:
- 1.49 kB
- Xet hash:
- 65de8457ee87227892e97e6565b7f70edda6e984d69cc0a891942b1a60631c18
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.