/webrtc-grabber

Grabber application for stealthily peeking at other computer's screens

Primary LanguageGoMIT LicenseMIT

WebRTC-grabber


The main use case is streaming live screen video from contestants' screens on ICPC World Finals as a part of ICPC Live broadcast.

Table of Contents

  1. WebRTC Protocol
  2. Grabber
  3. Signaling
  4. TURN
  5. FAQ
  6. License

WebRTC Protocol


WebRTC is a new protocol widely used for video calling and screen sharing. It works over a local network, allows to start the stream on-demand within roughly 1 sec and can be distributed portably. There are multiple public implementations of WebRTC protocols, including electron applications that we use as a reference point in this project.

WebRTC works by connecting each peer with each other to achieve peer to peer communication.

In the environment of an ICPC competition, it’s hard to allow communication between a computer inside the “blue” network and “red” network. WebRTC needs ranges of UDP and TCP ports in order to send video. Opening all of them to any device in the “red” network didn’t seem plausible. So we decided upon using a TURN server on the edge of two networks to allow for communication between those networks. TURN is a server that provides service of connecting computers behind multiple NAT-s.

It is able to do so because it has a constant globally available IP address and anybody can connect to it using any TCP/UDP port. Then, after both parties established a connection to it, the server passes all the data between the peers. We decided upon using it because it seemed like it’s the easiest way to connect peers from the “blue” network with computers from the “red” network.

The solution consisted of 3 main parts:

  • Grabber - standalone application for background capturing and sharing screen and webcam.
  • Signaling - webserver to exchange connection data between the grabber and players, capture video in browser and maintain a list of active grabbers.
  • TURN - server for forwarding video packages between grabber and players when they separated using NAT.

Grabber


Grabber is an electron application that is running in the background and listens for incoming calls from signaling.

Configuration

Grabber config.json:

{
  "webcamConstraint": {
    "aspectRatio": 1.7777777778
  },
  "webcamAudioConstraint": true,
  "desktopConstraint": {
    "width": 1280,
    "height": 720
  }
}

where

Property Description Type
webcamConstraint Webcam constraints object
aspectRatio Source aspect ratio number
webcamAudioConstraint Sets the constraints on contestant's webcam audio boolean
desktopConstraint Constraints on screen sharing object
width Width of the sharing screen number
height Height of the sharing screen number

Build sources

Clone the repository and run the following commands from the project root:

Windows

$ grabber_build_win64.bat

Linux & MacOS

$ sh grabber_build.sh <platform> <arch>

where

  • <platform> can be one of linux, win32, macos;
  • <arch> can be x64 or arm64.

Run

On the contestants' PC you need to extract files from the webrtc_grabber_grabber_<platform>_<arch>.zip archive, which you can find on the Release page.

After that, you can run the grabber using executable:

Windows

  • Launch in background (see runner.bat):

    $ ~dp0grabber.exe . --peerName={number of computer} --signalingUrl="{signalling url}"
    
  • For testing use the script tester.bat:

    $ ~dp0grabber.exe . --debugMode --peerName={number of computer} 
    --signalingUrl="{signalling url}"
    
  • Stop the grabber with the stopper.bat script.

Linux

Use grabber-linux.sh script:

  • Launch in background:

    $ bash grabber-linux.sh run {computer number} {signalling url}
  • For testing use

    $ bash grabber-linux.sh test {computer number} {signalling url}
  • Stop the grabber with

    $ bash grabber-linux.sh stop {computer number} {signalling url}

MacOS

The same as for Linux, but name of the script is grabber-darwin.sh.

Signaling


Signaling part of the suite is a statefull express http server with two socket.io endpoints. One for connecting the peers - /peer, and another to connect the viewers - /admin. The admin endpoint can be protected with a token that is specified in the config file. Signaling is also responsible in providing the peers with the peer config which contains the ICE servers to establish a connection between the peers. The peer endpoint is used to talk to the team computers. A peerConfig is sent to the grabber upon initial connection. The admin endpoint is used to see all available peers and initiate the connection to the peers.

Configuration

Signaling config.json:

{
  "participants": [
    "001",
    "002",
    "003",
    "004",
    "005",
    "006",
    "007",
    "008"
  ],
  "peerConnectionConfig": {
    "iceServers": [
      {
        "urls": "turn:193.233.204.163:3478",
        "username": "admin",
        "credential": "credential"
      }
    ]
  },
  "grabberPingInterval": 3000,
  "adminCredential": "live"
}

where

Property Description Type
participants Participant names string array
peerConnectionConfig Connection config object
iceServers Turn servers object array
urls Turn server URL string
username Turn server username string
credential Turn server password string
grabberPingInterval Ping to grabber in milliseconds number
adminCredential Signaling server password string

Build sources

Clone the repository and run the following commands from the packages/relay/cmd/signaling:

$ go mod tidy
$ go build

Run

Extract files from the webrtc_grabber_signaling_<platform>_<arch>.zip archive, which you can find on the Release page.

After that, you can run the signaling using scripts:

Windows

$ signaling.cmd

Linux & MacOS

$ sh signaling.sh

TURN


Turn server is used to transmit video/audio data across different networks. We use an open source implementation of turn called coturn inside docker with host network type.

Build sources

Clone the repository and run the following commands from the packages/go-turn:

$ go mod tidy
$ go build

Run

Extract files from the webrtc_grabber_turn_<platform>_<arch>.zip archive, which you can find on the Release page.

After that, you can run the signaling using scripts:

Windows

$ turn.cmd

Linux & MacOS

$ sh turn.sh

FAQ


General

Q: Is it true that VLC is no longer needed on the participants' computers?
A: Yes.

Q: Is it true that when webrtc-grabber starts, it starts uploading the image to the network without any additional requests?
A: No. It starts pinging the server with an interval of 3 seconds (can be configured in signaling config.json, grabberPingInterval parameter) and gives the stream only if it receives a request.

Q: Is it true that during the update it will be necessary to completely re-upload grabber executable (~100MB)?
A: Yes.

Q: How to test the performance of webrtc-grabber without access to the Internet, on Ubuntu, Windows?
A: It is necessary to raise the signaling. This is a Go server. See instructions above: How to run signaling. If the computers on the local network have direct access to each other (without intermediate NAT), then the turn server is not needed.

Q: How to check if the signaling service is up and running?
A: If you run signaling service, you will be able to see the interface on localhost:8000.

Connections and TURN-relay

Q: How many (TCP/UDP) ports do you really need? Does their number depend on the number of streams and how?
A: The number of ports depends on the number of simultaneous connections.

Q: Is it true that clients only differ in peerName in config.json, and technically they all use the same port in signalingUrl?
A: Yes. All grabbers use the same signalingUrl port. In fact, the unique identifier of the grabber is the id of the socket with it. peerName is an acquisition above it, that is, the relationship between peerId and peerName occurs after the connection.

Q: What width of the channel is needed to the client?
A: It is claimed that one connection needs 2-3 Mbps.

Q: What delays are acceptable for normal operation [1-100-10000ms]?
A: We use SRTP connection for video, http/websocket connection for signaling. So packet loss is allowed at all levels. The way the peers can tell if they are connected or not depending on the latency is controlled by the underlying WebRTC implementation of Chromium and the browser on the viewer side.

We didn't do any testing with adding latency to the connection, but we know that grabber successfully connects and shows a reliable stream over the internet using wifi. That proves that it can be used in local networks even over wifi.

Another relevant question to ask is how reliable the connection must be. And this question is perfectly answered by the ability to have video calls in Telegram / VK / Discord / Google meet from the subway. The connection will try to recover under the same conditions until we break it by force.

Q: Have you tested compatibility with OpenVPN?
A: We tried streaming over VPN, it worked.

Q: Is it true that the Turn-relay should be at the edge of the network of participants, and the signaling server is in Live?
A: There should be access to the turn service from the contestants network, and from the live network. Theoretically, turn may not necessarily be on the border if all the required packets of the WebRTC protocol are properly proxied/redirected.

Q: How many, what (TCP/UDP) and in what direction (from or to the contestants) packets with which ports do we need to allow through the firewall and is it true that in this case we can do without installing Turn-relay? Or in other words: how to make it work without the turn service and what changes must be made to the firewall for that to happen?
A: You can see the screens without a turn-relay if the computers of the contestants, the signaling server and the viewer computer are reachable from the same network. It's easy to see that this doesn't fit the conditions of the competition, because of the way the network is usually set up. It's easier to assume that WebRTC uses an arbitrary UDP port when the two peers connect.

If we use Turn-relay, we need to allow traffic from the participants network to TCP port 3000 (signaling), port 3478 (TCP and UDP) and a certain range of UDP ports (As experiments have shown, one active connection consumes 2 ports. Probably, 200 ports will be enough with more The numbers can be anything, for example 40000-40199).

Q: Which Turn-relay can be used under Windows (highly desirable without Cygwin)?
A: You can use our Turn-relay. See Turn.

License


This project is licensed under the MIT license. You can freely use our tools in your commercial or opensource software.