admin
Some checks are pending
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
71e4926395
commit
44f56e0554
2 changed files with 50 additions and 7 deletions
|
|
@ -386,7 +386,26 @@ function VoiceItem({ voice, onRemove, disabled }: VoiceItemProps) {
|
|||
const handlePlayPause = () => {
|
||||
if (!audioRef.current) {
|
||||
try {
|
||||
const audio = new Audio(`data:audio/mpeg;base64,${voice.voiceUrl}`)
|
||||
// voiceUrl can be either:
|
||||
// 1. Presigned URL (http/https) - new format
|
||||
// 2. Base64 data URL (data:audio/...) - legacy format
|
||||
// 3. UUID - if presigned URL generation failed (shouldn't happen, but handle gracefully)
|
||||
let audioUrl = voice.voiceUrl
|
||||
|
||||
// If it's a UUID (not a URL and not base64), we can't play it directly
|
||||
// This shouldn't happen as backend should return presigned URL, but handle it
|
||||
if (!audioUrl.startsWith('http://') && !audioUrl.startsWith('https://') && !audioUrl.startsWith('data:')) {
|
||||
// Check if it looks like a UUID
|
||||
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
||||
if (uuidPattern.test(audioUrl)) {
|
||||
toast.error('Audio URL is not available. Please refresh the page.')
|
||||
return
|
||||
}
|
||||
// Otherwise, assume it's legacy base64 without data: prefix
|
||||
audioUrl = `data:audio/mpeg;base64,${audioUrl}`
|
||||
}
|
||||
|
||||
const audio = new Audio(audioUrl)
|
||||
audioRef.current = audio
|
||||
|
||||
audio.onended = () => {
|
||||
|
|
@ -394,9 +413,18 @@ function VoiceItem({ voice, onRemove, disabled }: VoiceItemProps) {
|
|||
audioRef.current = null
|
||||
}
|
||||
|
||||
audio.onerror = (e) => {
|
||||
audio.onerror = (e: Event | string) => {
|
||||
console.error('Audio playback error:', e)
|
||||
toast.error('Failed to play audio. The file may be corrupted or in an unsupported format.')
|
||||
let errorMessage = 'Failed to play audio. The file may be corrupted, in an unsupported format, or the URL may have expired.'
|
||||
|
||||
if (e instanceof Event) {
|
||||
const audioElement = e.target as HTMLAudioElement | null
|
||||
if (audioElement?.error) {
|
||||
errorMessage = `Failed to load audio: ${audioElement.error.message || 'Unknown error'}`
|
||||
}
|
||||
}
|
||||
|
||||
toast.error(errorMessage)
|
||||
setIsPlaying(false)
|
||||
audioRef.current = null
|
||||
}
|
||||
|
|
@ -407,7 +435,10 @@ function VoiceItem({ voice, onRemove, disabled }: VoiceItemProps) {
|
|||
|
||||
audio.play().catch((error) => {
|
||||
console.error('Audio play error:', error)
|
||||
toast.error('Failed to play audio. Please check your browser audio settings.')
|
||||
const errorMessage = error instanceof Error
|
||||
? error.message
|
||||
: 'Failed to play audio'
|
||||
toast.error(`Failed to play audio: ${errorMessage}. Please check your browser audio settings.`)
|
||||
setIsPlaying(false)
|
||||
audioRef.current = null
|
||||
})
|
||||
|
|
|
|||
|
|
@ -173,9 +173,18 @@ export function AudioUpload({
|
|||
audioRef.current = null
|
||||
}
|
||||
|
||||
audio.onerror = (e) => {
|
||||
audio.onerror = (e: Event | string) => {
|
||||
console.error('Audio playback error:', e)
|
||||
alert('Failed to play audio. The file may be corrupted or in an unsupported format.')
|
||||
let errorMessage = 'Failed to play audio. The file may be corrupted, in an unsupported format, or the URL may have expired.'
|
||||
|
||||
if (e instanceof Event) {
|
||||
const audioElement = e.target as HTMLAudioElement | null
|
||||
if (audioElement?.error) {
|
||||
errorMessage = `Failed to load audio: ${audioElement.error.message || 'Unknown error'}`
|
||||
}
|
||||
}
|
||||
|
||||
alert(errorMessage)
|
||||
setIsPlaying(false)
|
||||
audioRef.current = null
|
||||
}
|
||||
|
|
@ -186,7 +195,10 @@ export function AudioUpload({
|
|||
|
||||
audio.play().catch((error) => {
|
||||
console.error('Audio play error:', error)
|
||||
alert('Failed to play audio. Please check your browser audio settings.')
|
||||
const errorMessage = error instanceof Error
|
||||
? error.message
|
||||
: 'Failed to play audio'
|
||||
alert(`Failed to play audio: ${errorMessage}. Please check your browser audio settings.`)
|
||||
setIsPlaying(false)
|
||||
audioRef.current = null
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue