I'm trying to record and play audio in html using MediaSourceExtensions and MediaRecorder.
here is my code:
async function recordAudio()
{
let mediaDevices = navigator.mediaDevices;
let MediaStream = await mediaDevices.getUserMedia({audio: true});
let mediaRecorder = new MediaRecorder(MediaStream);
let audio = document.querySelector('audio');
let chunks = [];
mediaRecorder.start(400);
var mediaSource = new MediaSource();
audio.src = URL.createObjectURL(mediaSource);
var sourceBuffer = mediaSource.addSourceBuffer("audio/mp4; codecs="mp4a.40.2"");
mediaRecorder.ondataavailable = (e) =>
{
sourceBuffer.appendSourceBuffer(e.data);
};
}
here are the errors I'm getting(on Firefox):
Uncaught (in promise) DOMException: An attempt was made to use an object that is not, or is no longer, usable (line 11).
what I'm going for is for the voice to be played almost immediately/400ms after the input but I have no idea how to fix it.
Any help would be much appreciated.
You can pass the stream directly to the audio element without having it going through the MediaRecorder instance. You can do this by assigning the MediaStream instance to the srcObject of the <audio> element.
audio.srcObject = MediaStream;
If you want to maniuplate the audio and create a controlled delay, then you could use the Web Audio API and manipulate the audio passing through.
In the example below the stream is passed through a DelayNode which can offset the playing time by a given value in seconds.
const audioContext = new AudioContext();
const mediaStreamSource = audioContext.createMediaStreamSource(MediaStream);
const delay = audioContext.createDelay();
const streamDestination = audioContext.createMediaStreamDestination();
delay.delayTime.value = 0.4; // Set delay to 400ms.
mediaStreamSource.connect(delay); // Pass the stream through the delay.
delay.connect(streamDestination); // Pass the delay into a new, modified stream.
Use the Web Audio API stream and set it to the <audio> element..
audio.srcObject = streamDestination.stream;
..or pass the audio signal directly to the speakers.
delay.connect(audioContext.destination);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With