File size: 2,423 Bytes
5d4d4d4
 
 
 
 
 
 
8e0957b
 
 
5d4d4d4
8e0957b
 
5d4d4d4
 
 
 
 
 
 
8e0957b
 
 
 
 
5d4d4d4
c3f0f02
 
8e0957b
 
5d4d4d4
 
 
 
 
 
8e0957b
 
5d4d4d4
8e0957b
 
5d4d4d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8e0957b
 
 
 
 
 
 
 
5d4d4d4
 
8e0957b
64db5cc
8e0957b
5d4d4d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8e0957b
 
 
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import React, { useMemo, useEffect, useState } from 'react';
import {
  audioBufferToMp3,
  blobFromAudioBuffer,
  cleanupFilename,
  delay,
} from '../utils/utils';

interface AudioPlayerProps {
  audioBuffer: AudioBuffer;
  title: string;
}

export const AudioPlayer: React.FC<AudioPlayerProps> = ({
  audioBuffer,
  title,
}) => {
  const [isConverting, setIsConverting] = useState(false);
  const [mp3Buffer, setMp3Buffer] = useState<ArrayBuffer | null>(null);

  const blobUrl = useMemo(() => {
    const wavBlob = blobFromAudioBuffer(audioBuffer);
    return URL.createObjectURL(wavBlob);
  }, [audioBuffer]);

  const downloadWavUrl = useMemo(() => {
    const wavBlob = blobFromAudioBuffer(audioBuffer);
    return URL.createObjectURL(wavBlob);
  }, [audioBuffer]);

  const downloadMp3Url = useMemo(() => {
    if (!mp3Buffer) return '';
    const mp3Blob = new Blob([mp3Buffer], { type: 'audio/mp3' });
    return URL.createObjectURL(mp3Blob);
  }, [audioBuffer]);

  // Clean up the object URL when the component unmounts or audioBuffer changes.
  useEffect(() => {
    return () => URL.revokeObjectURL(blobUrl);
  }, [blobUrl]);

  useEffect(() => {
    return () => URL.revokeObjectURL(downloadWavUrl);
  }, [downloadWavUrl]);

  useEffect(() => {
    return () => URL.revokeObjectURL(downloadMp3Url);
  }, [downloadMp3Url]);

  const convertToMp3 = async () => {
    setIsConverting(true);
    await delay(10); // wait a bit for the button to be rendered
    setMp3Buffer(audioBufferToMp3(audioBuffer));
    setIsConverting(false);
  };

  return (
    <div className="mt-4 flex items-center">
      <audio controls src={blobUrl}>
        Your browser does not support the audio element.
      </audio>

      <a
        className="btn btn-sm btn-primary ml-2"
        href={downloadWavUrl}
        download={`Podcast_${cleanupFilename(title)}.wav`}
      >
        Download WAV
      </a>
      {mp3Buffer ? (
        <a
          className="btn btn-sm btn-primary ml-2"
          href={downloadMp3Url}
          download={`Podcast_${cleanupFilename(title)}.mp3`}
        >
          Download MP3
        </a>
      ) : (
        <button
          className="btn btn-sm ml-2"
          disabled={isConverting}
          onClick={convertToMp3}
        >
          {isConverting
            ? 'Converting...'
            : 'Convert to MP3 (may take ~10 seconds)'}
        </button>
      )}
    </div>
  );
};