Home

Awesome

WebRTC command-line peer

Build

webrtc-cli is a small command-line tool allowing to stream to and from audio devices and files via WebRTC.

Features:

What is supported

Configurations:

Media types:

Audio devices:

File formats:

RTP codecs:

Operating systems:

Installation

From sources

Install dependencies:

sudo apt-get install gcc make pkg-config libopus-dev libopusfile-dev libpulse-dev

Install recent Go (at least 1.12 is needed):

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt-get update
sudo apt-get install golang-go

Clone and build:

git clone https://github.com/gavv/webrtc-cli.git
cd webrtc-cli
make

Run the tool:

./webrtc-cli -h

You can also install the tool system-wide, e.g.:

sudo cp ./webrtc-cli /usr/local/bin

Using go get

Alternatively, you can install webrtc-cli into GOPATH using go get.

First make sure that the Go version is at least 1.12:

go version

And then run this command:

go get -v github.com/gavv/webrtc-cli

It will automatically fetch sources and build and install webrtc-cli executable into $GOPATH/bin directory or into ~/go/bin if $GOPATH is not set.

Options

$ webrtc-cli --help
Usage of webrtc-cli:
      --offer                     enable offer mode
      --answer                    enable answer mode
      --source string             pulseaudio source or input wav file
      --sink string               pulseaudio sink
      --timeout duration          exit if can't connect during timeout
      --ice string                STUN or TURN server URL (default "stun:stun.l.google.com:19302")
      --ports string              use specific UDP port range (e.g. "3100:3200")
      --override-ip string        override IP address in SDP offer/answer
      --rate uint                 sample rate (default 48000)
      --chans uint                # of channels (default 2)
      --source-frame duration     source frame size (default 40ms)
      --sink-frame duration       sink frame size (default 40ms)
      --jitter-buf duration       jitter buffer size (default 120ms)
      --pulse-buf duration        pulseaudio buffer size (default 20ms)
      --max-drift duration        maximum jitter buffer drift (default 30ms)
      --mode string               opus encoder mode: voip|audio|lowdelay (default "voip")
      --complexity uint           opus encoder complexity (default 10)
      --loss-perc uint            expected packet loss percent, passed to opus encoder (default 25)
      --simulate-loss-perc uint   simulate given loss percent when receiving packets
      --debug                     enable more logs

Operation

The tool works in one of the two operation modes:

In both modes, the user is responsible to deliver SDP offer and answer between the two peers (e.g. between the two instances of the tool or between the tool and the browser).

When the tool reads SDP offer or answer from stdin, it reads all bytes until EOF is reached. If you're manually pasting it in the terminal, press ^D after pasting the text.

The tool may also work in one of the two direction modes:

It does not matter what peer is generating an offer or answer and what peer has a sink or source or both. All combinations are allowed.

Latency

Recording (source) latency is the sum of:

Playback (sink) latency is the sum of:

The overall latency is the sum of recoding latency, network latency, and playback latency.

The following frame sizes are supported: 10ms, 20ms, 40ms, and 60ms.

To employ FEC, jitter buffer should be at least two packet sizes. However, for seamless playback, it is recommended to set it to three packet sizes. The maximum drift parameter specifies how much the actual jitter buffer size may differ from the configured size.

PulseAudio usually doesn't handle very low latencies well. It's recommended to set PulseAudio buffer size at least to 20ms.

Limitations

Browser demo

This repo also provides WebRTC demo (source code). It contains a sample JavaScript code that can interact with this tool. The demo was tested on the Chromium browser.

If you allow it to access the microphone, it will play sound from the remote peer and send sound from the microphone to the remote peer. Otherwise, it will only play sound from the remote peer.

Examples

Stream from WAV file to PulseAudio sink

First peer:

webrtc-cli --offer --source ./test.wav

Second peer:

webrtc-cli --answer --sink alsa_output.pci-0000_00_1f.3.analog-stereo

Stream from PulseAudio source to PulseAudio sink

First peer:

webrtc-cli --offer --source alsa_input.pci-0000_00_1f.3.analog-stereo

Second peer:

webrtc-cli --answer --sink alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo

Bidirectional streaming

First peer:

webrtc-cli --offer \
    --source alsa_input.pci-0000_00_1f.3.analog-stereo \
    --sink alsa_input.pci-0000_00_1f.3.analog-stereo

Second peer:

webrtc-cli --answer \
    --source alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo \
    --sink alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo

Stream between web browser and webrtc-cli

First peer: WebRTC demo (source code)

Second peer:

webrtc-cli --answer \
    --source alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo \
    --sink alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo

Use lower latency

webrtc-cli \
    --pulse-buf 20ms \
    --source-frame 10ms --sink-frame 10ms \
    --jitter-buf 20ms --max-drift 20ms \
    ...

Force specific IP address and UDP port range

webrtc-cli --offer --override-ip 93.184.216.34 --ports 5100:5200 ...

This will restrict what UDP ports can be used to given range and replace IP addresses of all ICE candidates in generated SDP offer with given IP.

Dependencies

Build tools:

Go libraries:

C libraries:

Acknowledgments

This tool was initially developed for a freelance project. Big thanks to my customer who has kindly allowed to open-source it!

I'm working on another related open-source project, Roc Toolkit. It offers a wider functionality and better service quality, but so far has no WebRTC support.

Contributing

Feel free to report bugs, suggest improvements, and send pull requests!

Build:

make

Run checks:

make check

Format code:

make fmt

Authors

See here.

License

MIT