Implement audio player component with HTML5 audio and download functionality
This commit is contained in:
@@ -2,8 +2,9 @@ import { useState } from 'react'
|
||||
import './App.css'
|
||||
import TextInputSection from './components/TextInputSection'
|
||||
import VoiceAssignmentSection from './components/VoiceAssignmentSection'
|
||||
import AudioPlayerSection from './components/AudioPlayerSection'
|
||||
import type { Role } from './api/tts'
|
||||
import { detectRoles } from './api/tts'
|
||||
import { detectRoles, generateAudiobook } from './api/tts'
|
||||
|
||||
function App() {
|
||||
const [text, setText] = useState('')
|
||||
@@ -15,6 +16,7 @@ function App() {
|
||||
const [speed, setSpeed] = useState(1.0) // Default: 1.0x
|
||||
const [isGenerating, setIsGenerating] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [audioUrl, setAudioUrl] = useState<string | null>(null)
|
||||
|
||||
const handleTextChange = (newText: string) => {
|
||||
setText(newText)
|
||||
@@ -63,26 +65,46 @@ function App() {
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
// TODO: Implement audio generation
|
||||
console.log('Generating audiobook with:', {
|
||||
// Convert voice assignments to the format expected by the API
|
||||
const rolesArray = Array.from(voiceAssignments.entries()).map(([id, voice]) => ({
|
||||
id,
|
||||
voice
|
||||
}))
|
||||
|
||||
// Generate the audiobook
|
||||
const audioBlob = await generateAudiobook({
|
||||
text,
|
||||
language,
|
||||
voiceAssignments: Array.from(voiceAssignments.entries()),
|
||||
lang: language,
|
||||
roles: rolesArray,
|
||||
speed
|
||||
})
|
||||
|
||||
// Placeholder - will be implemented in later tasks
|
||||
setTimeout(() => {
|
||||
setIsGenerating(false)
|
||||
setPhase('generated')
|
||||
}, 1000)
|
||||
// Create a blob URL for the audio
|
||||
const url = URL.createObjectURL(audioBlob)
|
||||
setAudioUrl(url)
|
||||
|
||||
// Move to generated phase
|
||||
setPhase('generated')
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to generate audiobook')
|
||||
console.error('Generation error:', err)
|
||||
} finally {
|
||||
setIsGenerating(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDownload = () => {
|
||||
if (!audioUrl) return
|
||||
|
||||
// Create a temporary anchor element to trigger download
|
||||
const link = document.createElement('a')
|
||||
link.href = audioUrl
|
||||
link.download = 'audiobook.wav'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
// Check if all roles have assigned voices
|
||||
const allRolesAssigned = roles.length > 0 && roles.every(role => voiceAssignments.has(role.id))
|
||||
|
||||
@@ -122,10 +144,11 @@ function App() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{phase === 'generated' && (
|
||||
<div className="text-center">
|
||||
<p>Audio player phase (to be implemented)</p>
|
||||
</div>
|
||||
{phase === 'generated' && audioUrl && (
|
||||
<AudioPlayerSection
|
||||
audioUrl={audioUrl}
|
||||
onDownload={handleDownload}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user