Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send video (from getUserMedia) to Node.js server?

I'm looking to build a chat/live stream application (video + text chat). I'm not settled on an approach at the moment, but I'm moving forward with one, and I've gotten stuck.

I'm trying to grab the video stream using getUserMedia, and send it to my Node.js server over Socket.io.

So far I've got the blob url: "mediastream:http://192.168.1.20:3000/1c267861-a2da-41df-9a83-ae69fdfd883b" but I'm not sure how to grab the data from it to send over socket.io.

Any help would rock.

Server:

// server.js

var http = require('http');
var socketio = require('socket.io')
var fs = require('fs');

var server = http.createServer(function (req, res) {
  if (req.url ==='/') {
    fs.readFile('index.html', function (err, html) {
      res.writeHeader(200, {"Content-Type": "text/html"});
      res.write(html);
      return res.end();
    });
  } else {
    res.end('hi!');
  }
});

var io = socketio(server);

server.listen(8000, function () {
  console.log('Jumping on port 8000!');
});

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
  socket.on('video', function (video) {
    console.log(video);
  });
});

Client:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Video Café</title>
    <meta name="description" content="A place online where we can get together and chat...">
    <meta name="viewport" content="width=device-width">
    <style type="text/css">
      *, *::before, *::after {box-sizing: border-box}
      body {padding: 1em;}
      h1, div {text-align: center; margin: 1em auto;}
      #localVideo {
        width: calc(50% - 2em);
        margin: 1em auto;
      }
    </style>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      ;(function () {
        "use strict";
        window.addEventListener('load', function (event) {
          var socket = io('http://localhost');
          socket.on('news', function (data) {
            console.log(data);
            socket.emit('my other event', { my: 'data' });
          });

          // Shims
          var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
          var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
          var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
          navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;

          document.getElementById('startButton').addEventListener('click', function (event) {
            console.log('working...');
            navigator.getUserMedia({
              video: true,
              audio: true
            }, function (localMediaStream) {
              var blob = window.URL.createObjectURL(localMediaStream);
              window.stream = localMediaStream; // stream available to console
              var video = document.getElementById('localVideo');
              video.src = blob;
              video.play();
              // Send localstream to node
              console.log(blob);
              socket.emit('video', { my: blob });
            }, function (error){
              console.log("navigator.getUserMedia error: ", error);
            });
          }, false);

          // var pc = new RTCPeerConnection(null);
          // pc.onaddstream = gotRemoteStream;
          // pc.addStream(localStream);
          // pc.createOffer(gotOffer);

          // function gotOffer(desc) {
          //   pc.setLocalDescription(desc);
          //   sendOffer(desc);
          // }

          // function gotAnswer(desc) {
          //   pc.setRemoteDescription(desc);
          // }

          // function gotRemoteStream(e) {
          //   attachMediaStream(remoteVideo, e.stream);
          // }


        }, false);
      }());
    </script>
  </head>
  <body>
    <h1>Video Café</h1>
    <video id="localVideo" muted autoplay></video>
    <video id="remoteVideo" autoplay></video>
    <div>
      <button id="startButton">Start</button>
      <button id="callButton">Call</button>
      <button id="hangupButton">Hang Up</button>
    </div>
  </body>
</html>
like image 531
Costa Michailidis Avatar asked Dec 30 '14 20:12

Costa Michailidis


1 Answers

You could use MediaRecorder API for grabbing the stream and WebSockets for sending it to node.js

Here are a bit of details (link is to my own blog): https://www.webrtcexample.com/blog/?go=all/tutorial-recording-video/

In short, MediaRecorder API put pack of frames into your call-back function, and it then sends the frames to the server (node.js) via WebSockets (or any other binary channel).

It works perfect with Firefox. Chrome has experimental implementation of MediaRecorder API so far.

like image 120
fycth Avatar answered Oct 31 '22 20:10

fycth