How to send a recorded getusermedia stream to a nodejs server in real time
I can send a blob stream using socket.io to node js server. But it is blinking refreshing the blob data in the video player. I want it to run smoothly. How can I send data without video player flickering. Here is my server code
var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);
var fs = require("fs")
app.use(express.static('public'))
app.get("/", function(req, res){
res.sendFile(__dirname+ "/public/index.html");
});
io.on("connection", function(socket) {
console.log("A user is connected");
socket.on("send", function(data){
console.log(data);
socket.emit("data", data);
});
socket.on("disconnect", function() {
console.log("A user is disconnected");
});
});
http.listen(3000, function(){
console.log("Server is started at port 3000\nTo close use Ctrl+C");
});
And here is my client side code,
<html>
<head><title>Testing</title>
<script src="socket.io/socket.io.js"></script>
<script type="text/javascript" src="MediaStreamRecorder.js"></script>
</head>
<body>
<video autoplay="true" id="video"></video>
<script type="text/javascript">
var socket = io();
window.URL.createObjectURL = window.URL.createObjectURL || window.URL.webkitCreateObjectURL || window.URL.mozCreateObjectURL || window.URL.msCreateObjectURL;
socket.on("data", function(data){
var binaryData = [];
binaryData.push(data);
videoElement = document.getElementById('video');
videoElement.src = window.URL.createObjectURL(new Blob(binaryData, {type: "video/webm"}));
});
var mediaConstraints = {
video: true
};
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var arrayOfStreams = [stream];
var medias = new MediaStreamRecorder(stream);
medias.ondataavailable = function(blob) {
socket.emit("send", blob);
};
medias.start();
}
function onMediaError(e) {
console.error('media error', e);
}
</script>
</body>
</html>
I have a change timeslice value in the MediaStreamRecorder api to 500 by default. Thus, sending data to the server after 500 milliseconds. But flashing on the webpage. I have to do it in real time. Any help would be appreciated.
source to share
But it is blinking refreshing the blob data in the video player.
You are changing the .src
item <video>
.
URL.createObjectURL()
and are MediaStreamRecorder
not needed.
Instead of changing the element of an .src
element, <video>
you can pass the object MediaStream
once and set <video>
element .srcObject
to the passed one MediaStream
.
videoElement = document.getElementById("video");
function onMediaSuccess(stream) {
if (videoElement.srcObject === null) {
videoElement.srcObject = stream
}
}
var videoElement = document.getElementById("video");
videoElement.oncanplay = function() {
videoElement.play();
}
var media = document.createElement("video");
media.src = "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4";
media.oncanplay = function() {
media.play();
var stream = media.captureStream();
onMediaSuccess(stream);
}
function onMediaSuccess(stream) {
if (videoElement.srcObject === null) {
videoElement.srcObject = stream
}
}
<video id="video"></video>
If you need to upload Blob
, you can use MediaSource
, convert Blob
to ArrayBuffer
with, FileReader
or fetch()
and add ArrayBuffer
to SourceBuffer
, see Can't upload videos via website in Firefox .
source to share
You are using socket.io which uses a TCP connection. If you want to make your real-time application something like skype, you must use a UDP connection.
If one frame is lagging your application should ignore that, but in your case you are using a TCP connection, so it will always be fine. Firewall is also a problem for TCP connections. You said you were trying to set the timeout to 500ms, which is too long for realtime applications, so your video is flashing.
If you are ready to give up TCP connection, I have a small solution for that. I tried this and it works fine.
https://www.youtube.com/watch?v=ieBtXwHvoNk
Only one problem is that in this case, you cannot send your packets to the WAN directly, as you can easily do in websockets. You have to implement STUN / TURN or something similar on your server.
If you still have some doubts, have a look at this github issue and read all the answers: https://github.com/socketio/socket.io/issues/1175
Hope this helps.
source to share