UNPKG

@lobehub/tts

Version:

A high-quality & reliable TTS React Hooks library

68 lines (66 loc) 2.03 kB
import { useStreamAudioPlayer } from "../hooks/useStreamAudioPlayer.mjs"; import { splitTextIntoSegments } from "../../core/utils/splitTextIntoSegments.mjs"; import { useCallback, useEffect, useState } from "react"; import useSWR from "swr"; //#region src/react/useTTS/index.ts const useTTS = (key, text, fetchTTS, { onError, onSuccess, onFinish, onStart, onStop, ...restSWRConfig } = {}) => { const [shouldFetch, setShouldFetch] = useState(false); const [isGlobalLoading, setIsGlobalLoading] = useState(false); const [index, setIndex] = useState(0); const [textArray, setTextArray] = useState([]); const { load, reset, ...restAudio } = useStreamAudioPlayer(); const handleReset = useCallback((newText = []) => { setShouldFetch(false); setIsGlobalLoading(false); reset(); setIndex(0); setTextArray(newText); }, []); const handleStop = useCallback(() => { onStop?.(); handleReset([]); }, [handleReset]); const { isLoading, error, mutate } = useSWR(shouldFetch && textArray?.length > 0 ? [key, textArray?.[index]].join("-") : null, async () => await fetchTTS(textArray[index]), { onError: (err, ...rest) => { onError?.(err, ...rest); console.error("Error useTTS:", err); handleReset(); }, onSuccess: (data, ...rest) => { onSuccess?.(data, ...rest); load(data); if (index < textArray.length - 1) setIndex(index + 1); else { onFinish?.([...restAudio.arrayBuffers, data].filter(Boolean), ...rest); setShouldFetch(false); setIsGlobalLoading(false); } }, ...restSWRConfig }); const handleStart = useCallback(() => { if (!text || isLoading) return; onStart?.(); reset(); setShouldFetch(true); setIsGlobalLoading(true); }, [text, isLoading]); useEffect(() => { handleReset(splitTextIntoSegments(text)); return () => { handleReset(); }; }, [text]); return { audio: restAudio, canStart: !isLoading && !!text, error, isGlobalLoading, isLoading, mutate, start: handleStart, stop: handleStop }; }; //#endregion export { useTTS };