File size: 1,404 Bytes
a8aec61 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
'use client'
import { memo, useMemo } from 'react'
import { type AudioData } from '@/types/playground'
import { decodeBase64Audio } from '@/lib/audio'
/**
* Renders a single audio item with controls
* @param audio - AudioData object containing url or base64 audio data
*/
const AudioItem = memo(({ audio }: { audio: AudioData }) => {
const audioUrl = useMemo(() => {
if (audio?.url) {
return audio.url
}
if (audio.base64_audio) {
return decodeBase64Audio(
audio.base64_audio,
audio.mime_type || 'audio/wav'
)
}
if (audio.content) {
return decodeBase64Audio(
audio.content,
'audio/pcm16',
audio.sample_rate,
audio.channels
)
}
return null
}, [audio])
if (!audioUrl) return null
return (
<audio
src={audioUrl}
controls
className="w-full rounded-lg"
preload="metadata"
/>
)
})
AudioItem.displayName = 'AudioItem'
/**
* Renders a list of audio elements
* @param audio - Array of AudioData objects
*/
const Audios = memo(({ audio }: { audio: AudioData[] }) => (
<div className="flex flex-col gap-4">
{audio.map((audio_item, index) => (
// TODO :: find a better way to handle the key
<AudioItem key={audio_item.id ?? `audio-${index}`} audio={audio_item} />
))}
</div>
))
Audios.displayName = 'Audios'
export default Audios
|