k-yle / rtsp-relay

📽 View an RTSP stream in your web browser using an express.js server
https://npm.im/rtsp-relay
MIT License
322 stars 58 forks source link

WSS server is not working #191

Open felp99 opened 1 year ago

felp99 commented 1 year ago

Good afternoon.

I am replicating the SSL example for creating a WSS. However, when running through npm start or node there is no response on the expected port (8080).

I have tried reading other problems here but none go through this type of solution.

Could someone please help me?

Code:

var express = require('express');
var router = express.Router();
const app = express();

const rtspRelay = require('rtsp-relay');
const express = require('express');
const https = require('https');
const fs = require('fs');

const key = fs.readFileSync('secret/key.pem', 'utf8');
const cert = fs.readFileSync('secret/cert.pem', 'utf8');

const app = express();
const server = https.createServer({ key:key, cert:cert,passphrase:'palomar99'}, app);

const { proxy, scriptUrl } = rtspRelay(app, server);

app.ws('/api/stream/:cameraIP', (ws, req) =>
  proxy({
    url: `rtsp://10.24.64.${req.params.cameraIP}:554/stream1`,
    additionalFlags: ['-vf', 'scale=450:250', '-b:v', '500k', '-fflags', 'nobuffer']
  })(ws),
);

app.get('/', (req, res) =>
  res.send(`
  <canvas id='canvas1'></canvas>
  <canvas id='canvas2'></canvas>

  <script src='${scriptUrl}'></script>
  <script>
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/15',
      canvas: document.getElementById('canvas1')
    });
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/16',
      canvas: document.getElementById('canvas2')
    });
  </script>
`),
);

let port = process.env.PORT || 443;

server.listen(port, () => {
  console.log(`O servidor está rodando na porta ${port}`)
})
tobitoi commented 1 year ago

Good afternoon.

I am replicating the SSL example for creating a WSS. However, when running through npm start or node there is no response on the expected port (8080).

I have tried reading other problems here but none go through this type of solution.

Could someone please help me?

Code:

var express = require('express');
var router = express.Router();
const app = express();

const rtspRelay = require('rtsp-relay');
const express = require('express');
const https = require('https');
const fs = require('fs');

const key = fs.readFileSync('secret/key.pem', 'utf8');
const cert = fs.readFileSync('secret/cert.pem', 'utf8');

const app = express();
const server = https.createServer({ key:key, cert:cert,passphrase:'palomar99'}, app);

const { proxy, scriptUrl } = rtspRelay(app, server);

app.ws('/api/stream/:cameraIP', (ws, req) =>
  proxy({
    url: `rtsp://10.24.64.${req.params.cameraIP}:554/stream1`,
    additionalFlags: ['-vf', 'scale=450:250', '-b:v', '500k', '-fflags', 'nobuffer']
  })(ws),
);

app.get('/', (req, res) =>
  res.send(`
  <canvas id='canvas1'></canvas>
  <canvas id='canvas2'></canvas>

  <script src='${scriptUrl}'></script>
  <script>
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/15',
      canvas: document.getElementById('canvas1')
    });
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/16',
      canvas: document.getElementById('canvas2')
    });
  </script>
`),
);

let port = process.env.PORT || 443;

server.listen(port, () => {
  console.log(`O servidor está rodando na porta ${port}`)
})

im run normally, for ws im exposed in 8433 and for frontend in 443

tobitoi commented 1 year ago

'''js

const rtspRelay = require('rtsp-relay'); const express = require('express'); const https = require('https'); const fs = require('fs'); const key = fs.readFileSync('./server.key', 'utf8'); const cert = fs.readFileSync('./server.crt', 'utf8'); const app = express(); const server = https.createServer({ key, cert }, app); const { proxy } = rtspRelay(app, server); app.ws('/endpoint', proxy({ url: url, // if your RTSP stream need credentials, include them in the URL as above verbose: true })); server.listen(8443);

and in the front end in this case im using vue

felp99 commented 1 year ago

Good evening, how are you?

Thanks for the reply.

I am trying to upload this node app into an Azure application but the app won't open on any port.

When I try to do it without SSH, I get an error that this should be with WSS.

When I use the certificate and SHH, the application does not open and I get timeout.

I am using an Azure Linux B2 Web App.

Can the developer of the tool help me? @k-yle

tobitoi commented 1 year ago

Wss only run with ssh Make sure the certificate valid

k-yle commented 1 year ago

I am trying to upload this node app into an Azure application [...]

For that to work, microsoft's data centre would need access to your unencrypted RTSP stream, via some sort of reverse tunnel or a public IP address. I would not recommend this, for obvious security reasons - anyone who knows the link to your RTSP stream can see the camera feed.

So @felp99, perhaps you could explain your infrastructure arangement a bit more - How can it be that Azure has access to your RTSP stream in the first place?

felp99 commented 1 year ago

Ok. This is my infrastructure arangement where the url is the certificated website.

Esquemas de Arquitetura-Página-3 drawio

When I run my code locally, I can se my camera feed online with a GET (created by node in client side).

It works ok with the wrong certificate of course for local.

image

When I deploy this in my Azure Web App, it keeps running but return nothing... after some time, the app is shutted down due to timeout.

Inside the VM Linux, while running, I can type netstat -npvat and I receive the following:

image

The code:

// Import the modules
const express = require("express");
const expressSanitizer = require("express-sanitizer");
const rtspRelay = require('rtsp-relay');

// Importing the fs and https modules -------------- STEP 1
const https = require("https");
const fs = require("fs");

// Will this be deployed?:
const deploy = true;

// Read the certificate and the private key for the https server options 
// ------------------- STEP 2
const options = {
  key: fs.readFileSync("./config/cert.key"),
  cert: fs.readFileSync("./config/cert.crt"),
  passphrase: '1234'
}

// Initialize instance of express
const app = express();

// Iniciate server
var server = https.createServer(options, app);

// Import rtsp variables
const { proxy, scriptUrl } = rtspRelay(app, server);

// Init Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Mount express-sanitizer middleware here
app.use(expressSanitizer());

// Server uses get statement to create both canvas to stream
app.get('/', (req, res) =>
  res.send(`
  <h1> VMN-MiningLab-StreamConverter </h1>
  <canvas id='canvas1' style="border: 1px solid black;" width="450" height="250"></canvas>
  <canvas id='canvas2' style="border: 1px solid black;" width="450" height="250"></canvas>

  <script src='${scriptUrl}'></script>
  <script>
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/15' || 'ws://' + location.host + '/api/stream/15',
      canvas: document.getElementById('canvas1')
    });
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream/16' || 'ws://' + location.host + '/api/stream/16',
      canvas: document.getElementById('canvas2')
    });
  </script>
`),
);

app.ws('/api/stream/:cameraIP', (ws, req) =>
  proxy({
    url: `rtsp://10.xx.xx.${req.params.cameraIP}:xxx/stream1`,
    additionalFlags: ['-vf', 'scale=450:250', '-b:v', '500k', '-fflags', 'nobuffer']
  })(ws),
);

server.listen(8080, () => {
  console.log(`HTTPS server started on port ${process.env.PORT}`);
});
tobitoi commented 1 year ago

It is camera using ip public or local?

felp99 commented 1 year ago

The camera is using a local IP but has been granted IP access via the service application.

k-yle commented 1 year ago

If this code is running on Azure, how does Azure have access to 10.xx.xx.16? If I understand you correctly, 10.xx.xx.16 is an internal IP address on your local network. So are you using some sort reverse-tunneling system which coincidentally uses exactly the same IP address and port?

tobitoi commented 1 year ago

You must have ip public to communicate camera to cloud , maybe better your using one server on premise to communicate all camera via ip local and redirect the frontend ip to domain

Keep in mind you must have ip public and register it to domain

felp99 commented 1 year ago

I saw this in an Azure documentation. How could I implement it?

image

k-yle commented 1 year ago

Yes, azure supports websockets. But your Azure server is physically sitting in a building owned by microsoft, probably in a different country to your cameras. This means Azure cannot access your cameras, for obvious security reasons. There are ways around it, but they're unlikely to work well.

Your server needs access to your cameras, which means it needs to be on the same local network as the cameras