I am using an open source JavaScript library MediaStreamRecorder to record audio and video webRTC calls in Mozilla Firefox and Google Chrome.
The calls are recording successfully but I am facing the following issue.
If I use the time interval of 1 second (1000ms) in multiStreamRecorder.start()
then multiStreamRecorder.ondataavailable
event doesn't fire. And that's why No error or No log in console.
But, if I use the time interval of 1.5 seconds (1500ms) or greater, it fires the multiStreamRecorder.ondataavailable
event and everything works perfectly fine.
(Only in Video Case)
I want to keep the interval to 1 second (1000ms) only.
var ws;
function start() {
ws = new WebSocket("wss://xyz/");
ws.onopen = function () {
console.log("WebSocket has been opened!");
};
ws.onmessage = function (message) {
console.log("A messsage is received from WebSocket Server.", message);
};
ws.onclose = function (e) {
console.log('WebSocket is closed. Reconnection will be attempted in 5 second.', e.reason);
setTimeout(function () {
start();
}, 5000);
};
ws.onerror = function (err) {
console.error('WebSocket encountered an error: ', err.message, 'Closing WebSocket');
ws.close();
};
}
start();
function startRecording(localStream, remoteStream) {
if (localStream != null && remoteStream != null) {
multiStreamRecorder = new MultiStreamRecorder([localStream, remoteStream], "video/webm");
multiStreamRecorder.mimeType = "video/webm";
multiStreamRecorder.ondataavailable = function (blob) {
console.log("sending blob to websocket server", blob);
ws.send(blob);
};
// It doesn't work with the 1000ms time interval
multiStreamRecorder.start(1500);
}
else{
console.error("One or more streams are null.");
}
}
I suspect one second is not enough time for the camera stream to warm up. While you can attach a recorder to a stream instantly, it doesn't appear to be ready for play/recording in zero time.
Video elements have .onloadedmetadata
to let you wait for data to be ready; recorders do not.
You can make one though (use https fiddle for Chrome):
var haveLoadedMetadata = stream => {
let preview = document.createElement("video");
preview.srcObject = stream;
return new Promise(resolve => preview.onloadedmetadata = resolve);
};
var start = ms => navigator.mediaDevices.getUserMedia({video: true})
.then(stream => haveLoadedMetadata(stream)
.then(() => record(stream, ms))
.then(recording => {
stop(stream);
video.src = link.href = URL.createObjectURL(new Blob(recording));
link.download = "recording.webm";
link.innerHTML = "Download recording";
log("Playing "+ recording[0].type +" recording:");
}))
.catch(log);
var record = (stream, ms) => {
var rec = new MediaRecorder(stream), data = [];
rec.ondataavailable = e => data.push(e.data);
rec.start();
log(rec.state + " for "+ (ms / 1000) +" seconds...");
var stopped = new Promise((y, n) => (rec.onstop = y, rec.onerror = e => n(e.error || e.name)));
return Promise.all([stopped, wait(ms).then(() => rec.stop())])
.then(() => data);
};
var stop = stream => stream.getTracks().forEach(track => track.stop());
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var log = msg => div.innerHTML += "<br>" + msg;
<button onclick="start(1000)">Record 1 second!</button>
<div id="div"></div><br>
<video id="video" height="120" width="160" autoplay></video>
<a id="link"></a>
(Both Chrome and Firefox implement MediaRecorder directly, so I've answered using that).
I had a similar problem. it didnt fired ondataavailable
event unless i started recording and stopped several times. After 2 days found out that problem was my microphone drivers :). It probably keeps trying microphone so it takes few seconds till it figure out that it doesnt work. Once set audio
to false
all works perfectly. Just no sound lol.
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