Text to Speech (#2)
* Initial TTS scrapping implemented * Audio & copy buttons added * TTS langs mapping fix * Webkit audio api fix * Added TTS-related testing * Last tweaks
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export { default as useToastOnLoad } from "./useToastOnLoad";
|
||||
export { default as useAudioFromBuffer } from "./useAudioFromBuffer";
|
||||
|
||||
60
hooks/useAudioFromBuffer.ts
Normal file
60
hooks/useAudioFromBuffer.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
webkitAudioContext: typeof AudioContext
|
||||
}
|
||||
}
|
||||
|
||||
const useAudioFromBuffer = (bufferArray?: number[]) => {
|
||||
const audioCtxRef = useRef<AudioContext | null>(null);
|
||||
const [audioSource, setAudioSource] = useState<AudioBufferSourceNode | null>(null);
|
||||
const [audioBuffer, setAudioBuffer] = useState<AudioBuffer | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const AudioCtx = window.AudioContext || window.webkitAudioContext;
|
||||
if (!AudioCtx)
|
||||
return;
|
||||
audioCtxRef.current = new AudioCtx();
|
||||
return () => {
|
||||
audioCtxRef.current?.close();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!bufferArray)
|
||||
return setAudioBuffer(null);
|
||||
|
||||
audioCtxRef.current?.decodeAudioData(
|
||||
new Uint8Array(bufferArray).buffer
|
||||
).then(setAudioBuffer);
|
||||
}, [bufferArray]);
|
||||
|
||||
const onAudioClick = () => {
|
||||
if (!audioCtxRef.current)
|
||||
return;
|
||||
|
||||
if (!audioSource) {
|
||||
const source = audioCtxRef.current.createBufferSource();
|
||||
source.buffer = audioBuffer;
|
||||
source.connect(audioCtxRef.current.destination);
|
||||
source.start();
|
||||
source.onended = () => {
|
||||
setAudioSource(null);
|
||||
}
|
||||
setAudioSource(source);
|
||||
return;
|
||||
}
|
||||
audioSource.stop();
|
||||
audioSource.disconnect(audioCtxRef.current.destination);
|
||||
setAudioSource(null);
|
||||
};
|
||||
|
||||
return {
|
||||
audioExists: !!audioBuffer,
|
||||
isAudioPlaying: !!audioSource,
|
||||
onAudioClick
|
||||
};
|
||||
}
|
||||
|
||||
export default useAudioFromBuffer;
|
||||
Reference in New Issue
Block a user