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