Search code examples
node.jswebrtcrtspip-camerakurento

RTSP to Kurento/WebRTC from behind firewall


We currently have a Kurento signaling server in node.js that creates a room and allows one-to-one, one-to-many, and many-to-many WebRTC conferencing. It can also pull an RTSP stream (via PlayerEndpoint) into the room as a presenter.

One requirement that we have is to access an RTSP stream that lives behind a firewall without modifying the firewall settings (e.g. opening the RTSP stream's port).

One thought we had was to install a "camera controller" on the local network behind the firewall that connects to our signaling server (cloud) via websocket on port 443 (https), which is typically open for outbound traffic. The websocket connection would get upgraded, giving us a method to communicate with the controller. When a user wants to view the camera, the signaling server would send a message to the camera controller and have it initiate a WebRTC call as a presenter via normal WebRTC methods (using kurento-utils-js).

The problem that we have is how to push the RTSP stream to Kurento. Using kurento-utils-js, we are creating a WebRTCPeer (WebRtcPeerSendonly), but we can't get a hold of the RTSP stream this way.

We currently have something like this:

let video = document.createElement("video");
video.id = username;
video.autoplay = true;

document.getElementById("main").appendChild(video);

let constraints = {
    audio: true,
    video: {
      mandatory: {
        maxWidth: 320,
        maxFrameRate: 15,
        minFrameRate: 15
      }
    }
  };

let options = {
    localVideo: video, // This works for webcams, but how do we get RTSP stream in here?
    onicecandidate: onIceCandidate,
    mediaConstraints: constraints
  };

participant.rtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function (err) {
      if (err) {
        return console.error(err);
      }
      this.generateOffer(onOffer);
    });

const onIceCandidate = (candidate, wp) => {
    console.log("sending ice candidates");
    let message = {
      event: "candidate",
      senderId: participant.id,
      roomName: data.roomname,
      candidate: candidate
    };
    sendMessage(message);
  };

const onOffer = (err, offer, wp) => {
    console.log("sending offer");
    let message = {
      event: "receiveVideoFrom",
      senderId: participant.id,
      roomName: data.roomname,
      sdpOffer: offer
    };
    sendMessage(message);
  };

Do we need to have the camera controller connect directly to Kurento (via kurento-client) instead of using kurento-utils-js so that we can create a PlayerEndpoint? That would require opening the Kurento Media Server port and we'd be duplicating a large portion of the signaling server.

Is something like this possible, and if so, can you give an example of how to do it?


Solution

  • If you can I would run a WebRTC Agent inside the network with the RTSP Agent, and then have it connect to Kurento.

    RTSPtoWebRTC is a RTSP -> WebRTC bridge, but it does the signaling for you. It can be used as a library as well like rtsp-bench

    What you will want to do is instead signal with Kurento, so your topology will look like this.

    RTSP -> WebRTC -> | NAT | -> Kurento -> Viewers