Reputation: 372
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.
Upvotes: 3
Views: 518
Reputation: 20954
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);
Upvotes: 1