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.

0


source to share


2 answers


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>
      

Run codeHide result


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 .

+1


source


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.

0


source







All Articles