Fix tts audition (#4637)

Co-authored-by: luowei <glpat-EjySCyNjWiLqAED-YmwM>
Co-authored-by: crazywoola <427733928@qq.com>
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com>
This commit is contained in:
Charlie.Wei 2024-05-25 12:55:04 +08:00 committed by GitHub
parent 026175c8f7
commit 5bd432a85f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 41 additions and 20 deletions

View File

@ -375,6 +375,7 @@ const Answer: FC<IAnswerProps> = ({
<div className='mx-1 w-[1px] h-[14px] bg-gray-200'/> <div className='mx-1 w-[1px] h-[14px] bg-gray-200'/>
<AudioBtn <AudioBtn
value={content} value={content}
noCache={false}
className={cn(s.playBtn)} className={cn(s.playBtn)}
/> />
</> </>

View File

@ -41,13 +41,14 @@ const TextToSpeech: FC = () => {
<AudioBtn <AudioBtn
value={languageInfo?.example} value={languageInfo?.example}
voice={voiceItem?.value} voice={voiceItem?.value}
isAudition={true} isAudition
noCache
/> />
)} )}
</div> </div>
} }
noBodySpacing noBodySpacing
isShowTextToSpeech={true} isShowTextToSpeech
/> />
) )
} }

View File

@ -422,6 +422,7 @@ const GenerationItem: FC<IGenerationItemProps> = ({
<div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div> <div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div>
<AudioBtn <AudioBtn
value={content} value={content}
noCache={false}
className={'mr-1'} className={'mr-1'}
/> />
</> </>

View File

@ -78,6 +78,7 @@ const SavedItems: FC<ISavedItemsProps> = ({
<div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div> <div className='ml-2 mr-2 h-[14px] w-[1px] bg-gray-200'></div>
<AudioBtn <AudioBtn
value={answer} value={answer}
noCache={false}
className={'mr-1'} className={'mr-1'}
/> />
</> </>

View File

@ -13,6 +13,7 @@ type AudioBtnProps = {
voice?: string voice?: string
className?: string className?: string
isAudition?: boolean isAudition?: boolean
noCache: boolean
} }
type AudioState = 'initial' | 'loading' | 'playing' | 'paused' | 'ended' type AudioState = 'initial' | 'loading' | 'playing' | 'paused' | 'ended'
@ -22,6 +23,7 @@ const AudioBtn = ({
voice, voice,
className, className,
isAudition, isAudition,
noCache,
}: AudioBtnProps) => { }: AudioBtnProps) => {
const audioRef = useRef<HTMLAudioElement | null>(null) const audioRef = useRef<HTMLAudioElement | null>(null)
const [audioState, setAudioState] = useState<AudioState>('initial') const [audioState, setAudioState] = useState<AudioState>('initial')
@ -38,12 +40,12 @@ const AudioBtn = ({
const loadAudio = async () => { const loadAudio = async () => {
const formData = new FormData() const formData = new FormData()
if (value !== '') {
setAudioState('loading')
formData.append('text', removeCodeBlocks(value)) formData.append('text', removeCodeBlocks(value))
formData.append('voice', removeCodeBlocks(voice)) formData.append('voice', removeCodeBlocks(voice))
if (value !== '') {
setAudioState('loading')
let url = '' let url = ''
let isPublic = false let isPublic = false
@ -72,15 +74,16 @@ const AudioBtn = ({
} }
} }
const handleToggle = () => { const handleToggle = async () => {
if (audioState === 'initial') if (audioState === 'initial' || noCache) {
loadAudio() await loadAudio()
if (audioRef.current) { }
else if (audioRef.current) {
if (audioState === 'playing') { if (audioState === 'playing') {
audioRef.current.pause() audioRef.current.pause()
setAudioState('paused') setAudioState('paused')
} }
else if (audioState === 'paused' || audioState === 'ended') { else {
audioRef.current.play() audioRef.current.play()
setAudioState('playing') setAudioState('playing')
} }
@ -89,27 +92,31 @@ const AudioBtn = ({
useEffect(() => { useEffect(() => {
const currentAudio = audioRef.current const currentAudio = audioRef.current
const handleLoading = () => { const handleLoading = () => {
setAudioState('loading') setAudioState('loading')
} }
const handlePlay = () => { const handlePlay = () => {
currentAudio?.play() currentAudio?.play()
setAudioState('playing') setAudioState('playing')
} }
const handleEnded = () => { const handleEnded = () => {
setAudioState('ended') setAudioState('ended')
} }
currentAudio?.addEventListener('progress', handleLoading) currentAudio?.addEventListener('progress', handleLoading)
currentAudio?.addEventListener('canplaythrough', handlePlay) currentAudio?.addEventListener('canplaythrough', handlePlay)
currentAudio?.addEventListener('ended', handleEnded) currentAudio?.addEventListener('ended', handleEnded)
return () => { return () => {
if (currentAudio) { currentAudio?.removeEventListener('progress', handleLoading)
currentAudio.removeEventListener('progress', handleLoading) currentAudio?.removeEventListener('canplaythrough', handlePlay)
currentAudio.removeEventListener('canplaythrough', handlePlay) currentAudio?.removeEventListener('ended', handleEnded)
currentAudio.removeEventListener('ended', handleEnded) URL.revokeObjectURL(currentAudio?.src || '')
URL.revokeObjectURL(currentAudio.src) currentAudio?.pause()
currentAudio.src = '' currentAudio?.setAttribute('src', '')
}
} }
}, []) }, [])
@ -131,9 +138,17 @@ const AudioBtn = ({
<button <button
disabled={audioState === 'loading'} disabled={audioState === 'loading'}
className={`box-border p-0.5 flex items-center justify-center cursor-pointer ${isAudition || '!p-0 rounded-md bg-white'}`} className={`box-border p-0.5 flex items-center justify-center cursor-pointer ${isAudition || '!p-0 rounded-md bg-white'}`}
onClick={handleToggle}> onClick={handleToggle}
{audioState === 'loading' && <div className='w-6 h-6 rounded-md flex items-center justify-center p-2'><Loading /></div>} >
{audioState !== 'loading' && <div className={`w-6 h-6 rounded-md ${!isAudition ? 'w-4 h-4 hover:bg-gray-50' : 'hover:bg-gray-50'} ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>} {audioState === 'loading'
? (
<div className='w-6 h-6 rounded-md flex items-center justify-center p-2'>
<Loading />
</div>
)
: (
<div className={`w-6 h-6 rounded-md ${!isAudition ? 'w-4 h-4 hover:bg-gray-50' : 'hover:bg-gray-50'} ${(audioState === 'playing') ? s.pauseIcon : s.playIcon}`}></div>
)}
</button> </button>
</Tooltip> </Tooltip>
<audio ref={audioRef} src='' className='hidden' /> <audio ref={audioRef} src='' className='hidden' />

View File

@ -120,6 +120,7 @@ const Operation: FC<OperationProps> = ({
<div className='mx-1 w-[1px] h-[14px] bg-gray-200'/> <div className='mx-1 w-[1px] h-[14px] bg-gray-200'/>
<AudioBtn <AudioBtn
value={content} value={content}
noCache={false}
voice={config?.text_to_speech?.voice} voice={config?.text_to_speech?.voice}
className='hidden group-hover:block' className='hidden group-hover:block'
/> />

View File

@ -47,6 +47,7 @@ const TextToSpeech = ({
{ languageInfo?.example && ( { languageInfo?.example && (
<AudioBtn <AudioBtn
value={languageInfo?.example} value={languageInfo?.example}
noCache={false}
isAudition={true} isAudition={true}
/> />
)} )}