feat: echte Pair-Audios statt TTS, Klick auf Satz spielt Audio (preloaded)
- usePairAudio-Hook: preload beim Kachel-Mount, nur eine Stimme gleichzeitig - PairSentenceCard: audio_url statt speechSynthesis (TTS nur noch Fallback) - PairYesNoCard/PairWordCard: Frage klickbar + Speaker-Button (vorher kein Audio) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
42
src/hooks/usePairAudio.js
Normal file
42
src/hooks/usePairAudio.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
// Nur eine Stimme gleichzeitig im Feed
|
||||
let currentAudio = null
|
||||
|
||||
export default function usePairAudio(url) {
|
||||
const audioRef = useRef(null)
|
||||
const [playing, setPlaying] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!url) { audioRef.current = null; return }
|
||||
const audio = new Audio(url)
|
||||
audio.preload = 'auto'
|
||||
const onPlay = () => setPlaying(true)
|
||||
const onStop = () => setPlaying(false)
|
||||
audio.addEventListener('play', onPlay)
|
||||
audio.addEventListener('pause', onStop)
|
||||
audio.addEventListener('ended', onStop)
|
||||
audioRef.current = audio
|
||||
return () => {
|
||||
audio.pause()
|
||||
audio.removeEventListener('play', onPlay)
|
||||
audio.removeEventListener('pause', onStop)
|
||||
audio.removeEventListener('ended', onStop)
|
||||
if (currentAudio === audio) currentAudio = null
|
||||
audio.src = ''
|
||||
audioRef.current = null
|
||||
}
|
||||
}, [url])
|
||||
|
||||
function play() {
|
||||
const audio = audioRef.current
|
||||
if (!audio) return false
|
||||
if (currentAudio && currentAudio !== audio) currentAudio.pause()
|
||||
currentAudio = audio
|
||||
audio.currentTime = 0
|
||||
audio.play().catch(() => {})
|
||||
return true
|
||||
}
|
||||
|
||||
return { play, playing }
|
||||
}
|
||||
Reference in New Issue
Block a user