how to get audio file from mediastream

Viewed 11

I'm trying to record audio in a react application.

Recording it, playing it back, pausing it, is all working fine. But accessing the audio file itself to process it via a fetch query isn't working.

This is the code so far.

 const submitRecording = () => {
    if (status == RECORD_STATUS.IDLE || status == RECORD_STATUS.PAUSED ) {

      const answer = localStream.getAudioTracks()
      console.log("What is this audio result?: ",answer, "\ntype?: ", typeof answer)
      // let binary = atob(audioResult.split(',')[1])
      // let array = []
      // for (var i = 0; i < binary.length; i++) {
      //   array.push(binary.charCodeAt(i))
      // }
      // let blobData = new Blob([new Uint8Array(array)], {type: 'audio/mp3'})
      apiRequest(audioResult)
    } else {
      return 
    }
  }

The complete code is this - >

type record_status_type =
  | RECORD_STATUS.RECORDING
  | RECORD_STATUS.PAUSED
  | RECORD_STATUS.IDLE

//https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
let mediaRecorder: MediaRecorder
//https://stackoverflow.com/questions/48603402/how-to-set-srcobject-on-audio-element-with-react
let localStream: MediaStream

export const useAudioRecorder = () => {
  const dataArray = useRef<Array<Blob>>([])

  const [status, setStatus] = useState<record_status_type>(RECORD_STATUS.IDLE)
  const [audioResult, setAudioResult] = useState<string>('')
  const [errorMessage, setErrorMessage] = useState<string>('')

  const {
    timer,
    handleStartTimer,
    handlePauseTimer,
    handleResumeTimer,
    handleResetTimer
  } = useTimer()

  const startRecording = () => {
    if (status === RECORD_STATUS.IDLE) {
      try {
        setErrorMessage('')
        navigator.mediaDevices
          .getUserMedia({ audio: true })
          .then((mediaStreamObj: MediaStream) => {
            localStream = mediaStreamObj
            mediaRecorder = new MediaRecorder(mediaStreamObj)
            mediaRecorder.start()
            mediaRecorder.onstart = () => {
              handleStartTimer()
              setStatus(RECORD_STATUS.RECORDING)
            }
            mediaRecorder.ondataavailable = (event: BlobEvent) => {
              dataArray.current.push(event.data)
            }
          })
          .catch((error) => {
            setErrorMessage(error?.message)
          })
      } catch (error) {
        setErrorMessage(error?.message)
      }
    } else {
      return
    }
  }

  const resumeRecording = () => {
    if (status === RECORD_STATUS.PAUSED) {
      mediaRecorder.resume()
      mediaRecorder.onresume = () => {
        handleResumeTimer()
        setStatus(RECORD_STATUS.RECORDING)
      }
    } else {
      return
    }
  }

  const pauseRecording = () => {
    if (status === RECORD_STATUS.RECORDING) {
      mediaRecorder.pause()
      mediaRecorder.onpause = () => {
        handlePauseTimer()
        setStatus(RECORD_STATUS.PAUSED)
      }
    } else {
      return
    }
  }

  const stopRecording = () => {
    if (status !== RECORD_STATUS.IDLE) {
      mediaRecorder.stop()
      mediaRecorder.onstop = () => {
        handleResetTimer()
        let audioData = new Blob(dataArray.current, { type: 'audio/mp3' })
        dataArray.current = []
        setAudioResult(window.URL.createObjectURL(audioData))
        setStatus(RECORD_STATUS.IDLE)
        localStream.getAudioTracks().forEach((track: MediaStreamTrack) => {
          track.stop()
        })        
      }
    } else {
      return
    }
  }

  const submitRecording = () => {
    if (status == RECORD_STATUS.IDLE || status == RECORD_STATUS.PAUSED ) {

      const answer = localStream.getAudioTracks()
      console.log("What is this audio result?: ",answer, "\ntype?: ", typeof answer)
      // let binary = atob(audioResult.split(',')[1])
      // let array = []
      // for (var i = 0; i < binary.length; i++) {
      //   array.push(binary.charCodeAt(i))
      // }
      // let blobData = new Blob([new Uint8Array(array)], {type: 'audio/mp3'})
      apiRequest(audioResult)
    } else {
      return 
    }
  }

  return {
    startRecording,
    stopRecording,
    submitRecording,
    pauseRecording,
    resumeRecording,
    status,
    audioResult,
    errorMessage,
    timer
  }
}

Just to be able to upload the data itself to s3. Thanks!

0 Answers
Related