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!