JustPaste.it

audio-recorder.tsx

"use client";

import { useState, useEffect } from 'react';
import MicRecorder from 'mic-recorder';
import { Button } from '@/components/ui/button';

export default function AudioRecorder() {
  const [isRecording, setIsRecording] = useState(false);
  const [audioURL, setAudioURL] = useState<string | null>(null);
  const [recorder, setRecorder] = useState<MicRecorder | null>(null);
  const [audioBlob, setAudioBlob] = useState<Blob | null>(null); // Novo estado para armazenar o blob

  useEffect(() => {
    if (typeof window !== "undefined") {
      const newRecorder = new MicRecorder({
        bitRate: 128,
        encoder: 'wav',
        sampleRate: 44100,
      });
      setRecorder(newRecorder);
    }
  }, []);

  const startRecording = async () => {
    try {
      if (recorder) {
        await recorder.start();
        setIsRecording(true);
      }
    } catch (error) {
      console.error('Error starting recording:', error);
    }
  };

  const stopRecording = async () => {
    try {
      if (recorder) {
        const [buffer, blob] = await recorder.stop().getAudio();
        const timestamp = Date.now();
        const file = new File(buffer, `audio_${timestamp}.wav`, { type: blob.type });
        setAudioBlob(blob); // Armazenar o blob para reprodução
        await uploadToUploadThing(file);
        setIsRecording(false);
      }
    } catch (error) {
      console.error('Error stopping recording:', error);
    }
  };

  const uploadToUploadThing = async (file: File) => {
    try {
      const slug = 'courseAttachment';

      const presignedResponse = await fetch(`/api/uploadthing?actionType=upload&slug=${slug}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          fileName: file.name,
          fileSize: file.size,
        }),
      });

      if (!presignedResponse.ok) {
        const errorData = await presignedResponse.json();
        throw new Error(`Failed to obtain presigned URL: ${errorData.message || presignedResponse.statusText}`);
      }

      const { url, fileKey } = await presignedResponse.json();

      const uploadResponse = await fetch(url, {
        method: 'PUT',
        body: file,
      });

      if (!uploadResponse.ok) {
        throw new Error('Upload failed');
      }

      const metadataResponse = await fetch(`https://{{REGION_ALIAS}}.ingest.uploadthing.com/route-metadata`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-uploadthing-api-key': `${process.env.UPLOADTHING_SECRET}`,
        },
        body: JSON.stringify({
          fileKeys: [fileKey],
          metadata: {
            uploadedBy: `${process.env.UPLOADTHING_APP_ID}`,
          },
          callbackUrl: `${process.env.NEXT_PUBLIC_APP_URL}/api/uploadthing`,
          callbackSlug: slug,
          awaitServerData: false,
          isDev: false,
        }),
      });

      if (!metadataResponse.ok) {
        const errorData = await metadataResponse.json();
        throw new Error(`Failed to register upload: ${errorData.message || metadataResponse.statusText}`);
      }

      console.log('Upload registered successfully!');
      setAudioURL(url.split('?')[0]); // A URL pública (sem query params)
      alert('Upload successful!');
    } catch (error) {
      console.error('Upload error:', error);
      alert(`Upload error: ${error}`);
    }
  };

  return (
    <div>
      <Button onClick={isRecording ? stopRecording : startRecording}>
        {isRecording ? 'Stop Recording' : 'Start Recording'}
      </Button>
      {audioURL && (
        <p>
          Audio uploaded! Access it <a href={audioURL} target="_blank" rel="noopener noreferrer">here</a>.
        </p>
      )}
      {audioBlob && (
        <div>
          <h3>Preview:</h3>
          <audio controls>
            <source src={URL.createObjectURL(audioBlob)} type="audio/wav" />
            Your browser does not support the audio tag.
          </audio>
        </div>
      )}
    </div>
  );
}

capturadetela20241031115645.png