When we develop a web app we can think browsers like a swiss knifes, these include a bunch of utilities (APIs), one of them is get media devices access through mediaDevices
API from the navigator
object, this allows to devs create features related with the user media devices, this features migth be create voice notes, like Whatsapp Web does.
Today we're gonna create an app that records the user's voice and then saves the recorded voice on an <audio>
tag will be played later, this app looks like this
Apart mediaDevices
API we require
-
MediaRecorder
constructor, this creates a recorder object from the requested media device throughmediaDevices.getUserMedia()
method. -
Blob
constructor, this one allows create a blob object from the data adquired fromMediaRecorder
instance. -
URL.createObjectURL(blob)
method, this creates a URL, the URL contains the data (voice) create previously from theBlob
instance and it is gonna be use like<audio src=URL/
.
If you don't understand, don't worry, I'll explain you below. First, look at the <App/>
component.
<App/>
consumes a custom hook that provides the recorderState and several handlers. If you don't know how to use a custom hook I share with you a post about this.
The recorderState is like this:
-
recordingMinutes
andrecordingSeconds
are use to show the recording time andinitRecording
initializates the recorder. - The other parts of the state,
mediaStream
will be the media device provide bymediaDevices.getUserMedia()
andmediaRecorder
will be the instance ofMediaRecorder
,audio
will be the URL mentioned previously.
mediaStream
is set by the handler startRecording
After set the mediaStream
, MediaRecorder
instance is created
To adquire the voice and create the audio mediaRecorder
needs create two event listeners ondataavailable
and onstop
the first one gets chunks of the voice and pushes it to the array chunks
and the second one is use to create the blob through chunks
then audio is created. The stop event is fired by saveRecording
handler or the effect cleanup function, the cleanup function is called when recording is cancel.
Now take a look at the components <RecorderControls/>
and <RecordingsList/>
.
<RecorderControls/>
have the prop handlers and this is used by the jsx
<RecordingsList/>
receives audio
and consumes a custom hook that pushes the audio created previously.
The handler deleteAudio
is like this
And that's it! With React we can make use of useEffect
to access the user devices and create related features.
Top comments (11)
Can you replace the images with code blocks? We can copy it easily then...
how can i create a way for a user to respond directly to a voice recording like for example if jhon recorded a comment and i wanted to respond to jhon how would i structure that
I'm not sure on what you mean? Let's see if I got it: Do you want create a comment system? Like IG but with voice recordings?
thanks for responding yes thats exactly what im trying to do
I will try my best...
First you need an array of objects , each one is a specific recording. The recording structure can be as follow:
Recording: {
id: you can use UUID,
voiceNote: {
id,
data
},
from: user that made the comment,
to: user that create the post ,
nestedComments: [Recording]
}
this structure will be the main, you can add another fields like createdAt, updatedAt, etc. I hope it results usefull for you.
PD: about the voiceNote field you need to convert the blob to any audio format if you want store on a static resources store like S3, if I'm not wrong OGG is better for web.
Thanks a lot I really appreciate it man I'm going to try it out 9 out of 10 I'll probably be writing you again for some assistance
Ciao Leonardo, I've found that in Chrome, you can replay the recorded audio once, but then for some period of time it appears to be muted. Then it plays OK again. Firefox doesnt have this weird behavior. I'm looking into it, but do you have any thoughts?
Thanks for sharing this work
Hello abogaard! I'm not sure on what's happening with recorder on Chrome! Could be a Chrome issue or an unexpected bug(I think could be a blob creation bug). If you can resolve this don't hesitate share your solution here or recorder repo.
Regards!
@leonardo Bravo Thanks for this Code, I want to add more condition in this recorder like that: Recorder can not Stop Before 10s and Recorder can auto stop after 60s.
Is that possible? Please replay ASAP. Thanks In advance.
Hello Leonardo How can i save the notes, and persist the data?
Great. This is exactly what I've been looking for