phoboslab / jsmpeg

MPEG1 Video Decoder in JavaScript
MIT License
6.3k stars 1.43k forks source link

Multiple video streams, different websocket? #391

Open thehijacker opened 2 years ago

thehijacker commented 2 years ago

Hello,

I would like to use the websocket relay. I have it running and I can push the video from ffmpeg to it with "secret" key. I wish to push multiple streams via multiple ffmpeg commands. Something like:

ffmpeg ... http://localhost:8081/secret/streamid1 ffmpeg ... http://localhost:8081/secret/streamid2 ffmpeg ... http://localhost:8081/secret/streamid3

And then fetch each over websocket url:

http://localhost:8082/streamid1 http://localhost:8082/streamid2 http://localhost:8082/streamid3

Can this be done or I need a different solution?

Thank you,

jazib93 commented 2 years ago

Can anybody please respond to the above question? I need to implement something similar. I have multiple cameras on the user dashboard and the source will be RTSP streams. How to manage this using web sockets solution?

nmielcarek commented 2 years ago

I accomplish this using different ports. I am not sure if it can be done using the same port with different identifiers.

node websocket-relay.js streamid1 8091 8081 node websocket-relay.js streamid2 8092 8082 node websocket-relay.js streamid2 8093 8083

ffmpeg ... http://localhost:8091/streamid1 ffmpeg ... http://localhost:8092/streamid2 ffmpeg ... http://localhost:8093/streamid3

Is that acceptable or do you need to only use a single port for every stream?

jazib93 commented 2 years ago

Basically, I will not be knowing how many streams will be there. There might be chances of having 50-100 jsmpeg streams at the same time. So how will manage the ports and start the listening process for different ports at the run time?

thehijacker commented 2 years ago

My project is now working as intended. I endeded up opening 16 different websocket relays. This is done on boot using systemd daemon script:

[Unit]
Description=WebSocket service
After=network.target

[Service]
Type=forking
User=t2admin
Group=t2admin
ExecStart=/bin/bash /home/t2admin/jsmpeg/websocketserver.sh
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

It calls bash script:

#!/bin/bash

for i in {01..16}
do
   cmd="/bin/screen -dmS Socket_${i} /usr/bin/node /home/user/jsmpeg/websocket-relay.js password 100${i} 110${i}"
   eval "$cmd"
done

So all the websockets are opened in background using screen. FFmpeg sends stream to port 100XX and I watch it in html GUI on port 110XX. 16 in total. And I do round robin stream rotation on each of those 16 sockets. FFmpeg starts new stream and after X seconds I kill previous one for smooth transition. The software that fires the FFmpeg processes is custom written in .NET and running under mono framework.

Here a warning if you will use multiple FFmpeg instances. Each instance uses 48 threads no matter what -thread parameter I use. So if I have max 32 ffmpeg instances. Plus 4 threads to monitor ffmpeg output. 32 48+32 4 = 1664 opened threads. Linux could have a limit how many threads per user can be opened.

GUI looks fantastic and very low system resources are needed to watch all 16 streams using jsmpeg library:

image

Using OBS and its browser source I can grab this web page and stream it forward as video (multicast, HLS, http, ...).

This is stable and I have no problem with opening 16 sockets in background-

jazib93 commented 2 years ago

Thanks for your description. I think I have to do the same workaround. But I've a fear that if there is a situation of x+1 streams at a time, how we will manage the new port? In your case x is 16.

phoboslab commented 2 years ago

Please note that the websocket-relay.js is intended as an example. A setup like OP asked for (one nodejs process accepting and serving different streams) is absolutely possible and straightforward to implement. There's no need to use multiple processes and different ports. Just read the streamId from the requested URL and bin WebSocket clients and incoming ffmpeg streams accordingly.

That said, spawning multiple nodejs processes has one advantage: nodejs is inherently single threaded. So if you want to serve hundreds of different streams and/or thousands of clients with the same script, you may need to investigate nodejs cluster to fully utilize your server.

jazib93 commented 2 years ago

With the same ports and reading through streamId, I got this. https://watch.screencastify.com/v/ujGncbWp6GwVdFM8FuK1 @phoboslab Do you have an example of the implementation with single port implementation? I will do the cluster part. Your help will be highly appreciated.

vegalou commented 2 years ago

websocket-relay.js serve as a TCP relay, for multiple input, maybe streaming server could meet your requirement.

jsmpeg DOES provide fatest video display performance.