fix(audio): remove speed from TTS/cache/MinIO keys; fix presigned URL host rewrite

- Speed is no longer part of Kokoro generation, in-memory cache keys, or
  MinIO object keys — audio is always generated at 1.0 and playback speed
  is applied client-side via audioEl.playbackRate
- presignAudio() now calls rewriteHost() so chapter audio URLs use the
  public MinIO endpoint (same as presignVoiceSample already did)
- docker-compose.yml: rename MINIO_PUBLIC_ENDPOINT → PUBLIC_MINIO_PUBLIC_URL
  for the ui service so SvelteKit's $env/dynamic/public picks it up
This commit is contained in:
Admin
2026-03-04 19:30:46 +05:00
parent c8e0cf2813
commit acbfafb8cd
9 changed files with 45 additions and 72 deletions

View File

@@ -314,14 +314,12 @@
async function tryPresign(
targetSlug: string,
targetChapter: number,
targetVoice: string,
targetSpeed: number
targetVoice: string
): Promise<string | null> {
const params = new URLSearchParams({
slug: targetSlug,
n: String(targetChapter),
voice: targetVoice,
speed: String(targetSpeed)
voice: targetVoice
});
const res = await fetch(`/api/presign/audio?${params}`);
if (res.status === 404) return null;
@@ -337,7 +335,6 @@
if (audioStore.nextStatus !== 'none') return; // already running or done
const voice = audioStore.voice;
const speed = audioStore.speed;
audioStore.nextStatus = 'prefetching';
audioStore.nextChapterPrefetched = nextChapter;
@@ -345,7 +342,7 @@
try {
// Fast path: already generated
const url = await tryPresign(slug, nextChapter, voice, speed);
const url = await tryPresign(slug, nextChapter, voice);
if (url) {
stopNextProgress();
audioStore.nextProgress = 100;
@@ -358,14 +355,14 @@
const res = await fetch(`/api/audio/${slug}/${nextChapter}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ voice, speed })
body: JSON.stringify({ voice })
});
if (!res.ok) throw new Error(`Prefetch generation failed: HTTP ${res.status}`);
stopNextProgress();
audioStore.nextProgress = 100;
const url2 = await tryPresign(slug, nextChapter, voice, speed);
const url2 = await tryPresign(slug, nextChapter, voice);
if (!url2) throw new Error('Prefetch: audio generated but presign returned 404');
audioStore.nextAudioUrl = url2;
@@ -402,7 +399,6 @@
async function startPlayback() {
const voice = audioStore.voice;
const speed = audioStore.speed;
// Populate store metadata so layout + mini-bar have track info.
audioStore.slug = slug;
@@ -435,7 +431,7 @@
}
// Fast path B: audio already in MinIO (presign check).
const url = await tryPresign(slug, chapter, voice, speed);
const url = await tryPresign(slug, chapter, voice);
if (url) {
audioStore.audioUrl = url;
audioStore.status = 'ready';
@@ -453,13 +449,13 @@
const res = await fetch(`/api/audio/${slug}/${chapter}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ voice, speed })
body: JSON.stringify({ voice })
});
if (!res.ok) throw new Error(`Generation failed: HTTP ${res.status}`);
await finishProgress();
const url2 = await tryPresign(slug, chapter, voice, speed);
const url2 = await tryPresign(slug, chapter, voice);
if (!url2) throw new Error('Audio generated but presign returned 404');
audioStore.audioUrl = url2;
audioStore.status = 'ready';