I am unable to get blobs recorded by an instance of MediaRecorder
that are sent over WebSocket to playback on the client machine’s video
element. Here is an excerpt of my code:
sender.js:
navigator.getUserMedia({
video: {
facingMode: 'user'
},
audio = true
}).then((stream) => {
const recorder = new MediaRecorder(stream);
recorder.ondataavailable((event) => {
socket.send(event.data); // according to the client console, THIS SENDS A BLOB!!!
});
recorder.start(1000);
});
receiver.js:
socket.onmessage = (message) => {
console.log(message.data); // instanceof Blob
blob = message.data;
// tried this answer but it still does not work: https://stackoverflow.com/a/72772924/1079320
blob = new Blob([message.data], { // the Blob.type attribute is ignored when sent by WebSocket: https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
type: 'video/webm; codecs=vp9'
});
// blob = blob.slice(0, blob.size, 'video/webm; codecs=vp9'); // this answer does not work: https://stackoverflow.com/a/50875615/1079320
video.srcObject = blob; // under "Usage notes" from https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject the URL.createObjectUrl() method is no longer needed!
video.play(); // const video = document.getElementById('video-element-id');
};
I get no errors, but the video element simply does not play. Testing using the Firefox browser.
2
Answers
I've finally figured it out: The key was to use the
MediaSource
API. Example code can be found under "Examples" here:https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/MediaSource
Firstly, it is important to note that I couldn't make this code work within the
body.onload
listener I was using before: Instead, I had to put the<script>
tag directly in the<body>
of the HTML document itself.Furthermore, I had to pass the raw
Blob
contents as anarrayBuffer
using theblob.arrayBuffer()
promise.That said, here is the revised version of my code:
receiver.js:
And BAH-BAM! Everything is working as it should now.
Thanks to "guest271314" for suggesting I look into
MediaSource
.recorder.ondataavailable(event => {
should berecorder.ondataavailable = (event) => {}
orrecorder.addEventListener("dataavailable", (event) => {})
. Ifmessage.data
is aBlob
and not anArrayBuffer
you don’t have to create a newBlob
, just use theBlob
defined on theevent
. Additionally,Blob
set assrc
won’t work. You are not setting aMediaStream
tosrcObject
. Pass theBlob
toURL.createObjectURL()
then set the Blob URL as theHTMLMediaElement
src
.