Skip to content

Commit

Permalink
Cache Audio, Add Server Error Handling
Browse files Browse the repository at this point in the history
  • Loading branch information
graphemecluster committed Jun 13, 2024
1 parent 256cf66 commit d7d3b9e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
43 changes: 35 additions & 8 deletions src/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useReducer, useRef, useState } from "react";

import { NO_AUTO_FILL } from "./consts";

import type { Language } from "./types";
import type { Language, ServerError } from "./types";
import type { SyntheticEvent } from "react";

const audioCache: Record<Language, Map<string, string>> = { waitau: new Map(), hakka: new Map() };

export default function AudioPlayer({ syllables, language }: { syllables: string[]; language: Language }) {
const [isReady, setIsReady] = useState(false);
const [serverError, setServerError] = useState<ServerError | undefined>();
const [retryCounter, retry] = useReducer((n: number) => n + 1, 0);
const [isPlaying, setIsPlaying] = useState<boolean | null>(false);
const [progress, setProgress] = useState(0);
const animationId = useRef(0);
Expand All @@ -27,12 +31,22 @@ export default function AudioPlayer({ syllables, language }: { syllables: string
setProgress(0);
}, [pauseAudio]);

const text = syllables.join("+");
useEffect(() => {
const _isPlaying = isPlaying;
async function fetchAudio() {
const response = await fetch(`https://Chaak2.pythonanywhere.com/TTS/${language}/${encodeURIComponent(syllables.join("+"))}`);
if (response.ok) {
audio.current.src = URL.createObjectURL(await response.blob());
let url = audioCache[language].get(text);
if (!url) {
const response = await fetch(`https://Chaak2.pythonanywhere.com/TTS/${language}/${text}`);
if (response.ok) {
audioCache[language].set(text, url = URL.createObjectURL(await response.blob()));
}
else {
setServerError(await response.json() as ServerError);
}
}
if (url) {
audio.current.src = url;
await audio.current.play();
audio.current.pause();
audio.current.currentTime = progress * audio.current.duration;
Expand All @@ -42,10 +56,11 @@ export default function AudioPlayer({ syllables, language }: { syllables: string
}
}
audio.current.pause();
setServerError(undefined);
setIsReady(false);
void fetchAudio();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [language, syllables, pauseAudio]);
}, [language, text, retryCounter]);

useEffect(() => {
if (!isReady || !isPlaying) return;
Expand Down Expand Up @@ -112,8 +127,20 @@ export default function AudioPlayer({ syllables, language }: { syllables: string
tabIndex={isReady ? 0 : -1}>
⏹︎
</button>
{!isReady && <div className="absolute inset-0 flex items-center justify-center bg-base-content bg-opacity-10 rounded-lg">
<span className="loading loading-spinner loading-lg" />
{!isReady && <div className="absolute inset-0 flex items-center justify-center bg-base-content bg-opacity-10 rounded-lg text-xl">
{serverError
? <div>
<span className="font-semibold">錯誤:</span>
{serverError.error}
{serverError.message && <>
{": "}
<code>{serverError.message}</code>
</>}
<button type="button" className="btn btn-info btn-sm text-lg text-neutral-content ml-2 gap-1" onClick={retry}>
<span className="font-symbol rotate-90"></span>重試
</button>
</div>
: <span className="loading loading-spinner loading-lg" />}
</div>}
</div>;
}
2 changes: 1 addition & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@font-face {
font-family: "Noto Sans Symbols 2";
font-display: swap;
src: url("https://fonts.gstatic.com/l/font?kit=I_uyMoGduATTei9eI8daxVHDyfisHr71ypbyaZR7WOGXo6nZf1WIKD_AmxM&skey=5cf84917987cc637&v=v23") format("woff2");
src: url("https://fonts.gstatic.com/l/font?kit=I_uyMoGduATTei9eI8daxVHDyfisHr71ypbyapR7WOGXo6nZf1WIKC3yrmtU6gc&skey=5cf84917987cc637&v=v23") format("woff2");
descent-override: 25%;
}
:root {
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ export interface Sentence {
genre: Genre;
sentence: [string, PronNoteArray][];
}

export interface ServerError {
error: string;
message?: string;
}

0 comments on commit d7d3b9e

Please sign in to comment.