Send webRTC getUserMedia webCam stream over socketio - node.js

I have this piece of code:
navigator.mediaDevices.getUserMedia(param)
.then(function(stream) {
video.srcObject = stream;
video.play();
}
})
.catch(function (err) {});
In this code I want to send this stream over socketio to nodejs server so that I can use it on receiver end for display in video element.
How can I achieve this?

I think something like this is your best bet: https://stackoverflow.com/a/17938723/5915143
You'd record the stream using MediaStreamRecorder and send it with 'emit()' calls on socket io to your server.
Alternatively you can use a streaming library built on socket.io like Endpoint.js to handle the stream.

Related

Streaming API - how to send data from node JS connection (long-running HTTP GET call) to frontend (React application)

We are attempting to ingest data from a streaming sports API in Node.Js, for our React app (a MERN app). According to their API docs: "The livestream read APIs are long running HTTP GET calls. They are designed to be used to receive a continuous stream of game actions." So we am attempting to ingest data from long-running HTTP GET call in Node Js, to use in our React app.
Are long-running HTTP GET calls the same as websockets? We have not ingested streaming data previously, so not sure about either of these.
So far, we have added the following code into the index.js of our node app:
index.js
...
// long-running HTTP request
http.get(`https://live.test.wh.geniussports.com/v2/basketball/read/1234567?ak=OUR_KEY`, res => {
res.on('data', chunk => {
console.log(`NEW CHUNK`);
console.log(Buffer.from(chunk).toString('utf-8')); // simply console log for now
});
res.on('end', () => {
console.log('ENDING');
});
});
// Start Up The Server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => console.log(`Express server up and running on port: ${PORT}`));
This successfully connects and console-log's data in the terminal, and continues to console log new data as it becomes available in the long-running GET call.
Is it possible to send this data from our http.get() request up to React? Can we create a route for a long-running request in the same way that other routes are made? And then call that routes in React?
Server-sent events works like this, with a text/event-stream content-type header.
Server-sent events have a number of benefits over Websockets, so I wouldn't say that it's an outdated technique, but it looks like they rolled their own SSE, which is definitely not great.
My recommendation is to actually just use SSE for your use-case. Built-in browser support and ideal for a stream of read-only data.
To answer question #1:
Websockets are different from long-running HTTP GET calls. Websockets are full-duplex connections that let you send messages of any length in either direction. When a Websocket is created, it uses HTTP for the handshake, but then changes the protocol using the Upgrade: header. The Websockets protocol itself is just a thin layer over TCP, to enable discrete messages rather than a stream. It's pretty easy to design your own protocol on top of Websockets.
To answer question #2:
I find Websockets flexible and easy to use, though I haven't used the server-sent events that Evert describes in his answer. Websockets could do what you need (as could SSE according to Evert).
If you go with Websockets, note that it's possible to queue a message to be sent, and then (like any network connection) have the Websocket close before it's sent, losing any unsent messages. Thus, you probably want to build in acknowledgements for important messages. Also note that Websockets close after about a minute of being idle, at least on Android, so you need to either send heartbeat messages or be prepared to reconnect as needed.
If you decided to go on with websockets , I would recommend this approach using socket.io for both client and server:
Server-Side code:
const server = require('http').createServer();
const io = require('socket.io')(server);
io.on("connection", (socket) => {
http.get(`https://live.test.wh.geniussports.com/v2/basketball/read/1234567?ak=OUR_KEY`, res => {
res.on('data', chunk => {
console.log(`NEW CHUNK`);
let dataString = Buffer.from(chunk).toString('utf-8)
socket.emit('socketData' , {data:dataString});
});
res.on('end', () => {
console.log('ENDING');
});
});
});
server.liste(PORT);
Client-Side code:
import {
io
} from 'socket.io-client';
const socket = io('<your-backend-url>');
socket.on('socketData', (data) => {
//data is the same data object that we emited from server
console.log(data)
//use your websocket data
})

Receiving media stream for Electron app on my react native app on the same network

I'm trying to send a media stream from Electron js to my react native mobile app.
I can connect to my localhost PeerJS Server and the two devices connect. I can send data using the .send() method:
conn.send("Message from electron")
When I try to send the stream, like this:
const call = peer.call(mobileId, newStream);
The mobile receives the call and the answer seems to work. However, this listener (for the stream) never executes and it seems like the stream never arrives:
mobPeer.on('call', function(call) {
console.log("Web calling", call); // THIS WORKS FINE
call.answer(null);
call.on('stream', function(stream) {
console.log('stream from desktop') // THIS NEVER EXECUTES
});
});
Is it because I'm trying to share a stream from getUserMedia and it needs to be over https? If so, anyway to get it to work when both devices are on the same network? Thanks in advance.

Stream data from Browser to nodejs server using getUserMedia

I'm trying to send data (video and audio) from Browser to a NodeJS server. On the client side, I'm using getUserMedia to get a stream data and trying to send it over websockets via SockJS. Here is my code so far :
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
})
.then(function(stream){
// trying to send stream
var video = window.URL.createObjectURL(stream);
// send stream
mystream.send(video.play());
})
Where mystream is a SockJS instance.
My need is to persist the video as it is watched by a peer.
Has anyone ever sent a stream video to a server ? I'm out of ideas on this one. Any help/hint is appreciated.
After hours of researching, I just gave up and used Kurento. It is well documented and there is some pretty interesting examples involving NodeJS sample code. I let the question open in case someone comes with a better idea.

Send MediaStream through NodeJS

I have the MediaStream object returned from getUserMedia and can show it in my own screen.
The thing is, I don't know how to *send / pipe / stream/ * that MediaStream from Point A through NodeJS using socket.io to Point B.
My code right now is:
// Cámara
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true, video: true}, function(stream) {
video.src = URL.createObjectURL(stream) || window.URL.createObjectURL(stream);
webcamstream = stream;
}, onVideoFail);
} else {
alert ('failed');
}
});
function onVideoFail(e) {
console.log('webcam fail!', e);
};
I need the way to make this stream being sent constantly to other user using NodeJS.
The comment made in the answer for Audio and video conference with NodeJS are still valid
if you were to send the streams through socket.io instead of a peer connection, in any case that would be the raw video content (bytes). You would lose:
the streaming part (RTP/RTCP), and corresponding packet loss cancellation
the bandwidth adaptation
the encryption (DTLS)
the media engine (jitter correction, …)
over webRTC.
why not implement an SFU in node.js? Use node.js/socket.io for the signaling (i.e. the initial handshake) but also use node.js as a peer connection endpoint which relays/routes the media stream to (an)other(s) peer(s)? You would have an intermediate server like you seem to want, and all the advantages of webRTC.
another solution is to use an MCU, google webrtc+mcu and you will find many.
this might be a little late, but there's now a library called wrtc/node-webrtc. use that! https://github.com/node-webrtc/node-webrtc

How to stream video from node.js into kafka with kafka stream?

I need to implement a video streaming with the help of kafka.I am able to stream the video to the browser with the help of node.js.But I want to know how to stream video from node.js to kafka producer and also the consumer.
I got this code for sending text messages but i want to send the live video.
const Transform = require('stream').Transform;
const ProducerStream = require('./lib/producerStream');
const _ = require('lodash');
const producer = new ProducerStream();
const stdinTransform = new Transform({
objectMode: true,
decodeStrings: true,
transform (text, encoding, callback) {
text = _.trim(text);
console.log(`pushing message ${text} to ExampleTopic`);
callback(null, {
topic: 'ExampleTopic',
messages: text
});
}
});
process.stdin.setEncoding('utf8');
process.stdin.pipe(stdinTransform).pipe(producer);

Resources