Using webrtc offline

Hi,

I use webrtcsink to stream video with a simple local configuration (two computers, local network). I’ve noticed that an internet connection is needed, otherwise the STUN server cannot be reached, and the pipeline fails.

libnice-WARNING **: 07:11:37.086: Agent: 0x7f3018024610: s:1: Can't resolve STUN server: Error resolving “stun.l.google.com”: Temporary failure in name resolution

Is a STUN server mandatory for such simple configurations? Can I make it work offline?

Thanks

You can disable STUN thanks to the stun-server property like so:

    let webrtcsink = gst::ElementFactory::make("webrtcsink")
        .property("stun-server", None::<String>)
        .build()
        .unwrap();

I’m doing this
webrtcbin.set_property("stun-server", None::<String>);
instead of

if let Some(stun_server) = settings.stun_server.as_ref() {
            webrtcbin.set_property("stun-server", stun_server);
}

in webrtcsink/imp.rs That’s what you suggest right?

Unfortunately I’ve got

0:00:03.178448549 51618 0x7fd20c020f60 ERROR webrtcnice nice.c:470:_add_stun_server:<webrtcbin-b3649156-fac9-4b19-92a0-36cb20b3aa91:ice> Stun server ‘’ has no host, must be of the form stun://:

which still work if I’m online, and not when I am offline. I guess libnice fallback to a default stun server. What do you think?

I’ve the same error If I set
gst-launch-1.0 webrtcsink stun-server=None ..

Sorry, I forgot you were using Gst.parse_launch in Python (my suggestion was a Rust call to the element factory with property initialisation, not a modification of gst-plugin-rs).

In Python, this should do the trick:

    pipeline = Gst.parse_launch(f"webrtcsink stun-server=NULL [...]")

One option could be running stun server locally e.g. as below:

docker run \
    -it \
    --rm \
    -p 3478:3478 \
    -p 3478:3478/udp \
    --network=host \
    --name=coturn-service \
    coturn/coturn \
    -n \
    --log-file=stdout \
    --verbose \
    --stun-only \
    --no-rfc5780 \
    --no-stun-backward-compatibility \
    --response-origin-only-with-rfc5780 \
    --realm=coturn-service

And then use stun://0.0.0.0:3478 for stun address.

Sorry, same error with the Gst.parse_launch(f"webrtcsink stun-server=NULL [...]")

0:00:00.383785094 15553 0x7fae3001f800 ERROR webrtcnice nice.c:470:_add_stun_server:<webrtcbin-aaab2123-b4d1-46a5-a90e-21484bc08f22:ice> Stun server ‘’ has no host, must be of the form stun://:

Streaming still works though If I am online, but if I’m not, this message spams and nothing is sent

0:00:01.421404867 14513 0x3a5acc0 WARN appsrc gstappsrc.c:2612:gst_app_src_push_internal:<audio_0> Dropping old item buffer: 0x7f13f401d000, pts 0:00:00.713500000, dts 0:00:00.713500000, dur 0:00:00.020000000, size 161, offset 5796, offset_end 5957, flags 0x0

Don’t set the stun-server property to NULL as that will print that error. I’m not sure why it is implemented like that, it could as well just ignore NULL. Maybe worth creating an issue in Gitlab about that :slight_smile:

That’s my plan B, thanks :slight_smile:

FWIW I think that’s unrelated to your actual problem, but I’m not sure why it should get stuck like this just because it fails resolving the STUN server. Or at least I would consider that a bug: it should just not use STUN in that case.

What gst-plugins-rs version do you use? I tried again locally: I see the error with webrtcsink stun-server=test but not with webrtcsink stun-server=NULL.

Well my mistake, the error was due to the rust code I modified. So I just pulled and compiled the plugin (commit a946895fad446acc06daf9f53b62cdaf2e87bfb8 ). The error is gone, but it is still not working.

The following example works when online, does not when offline. There is no error, but on the signalling server, the ice candidates are not sent. The consumer is waiting and there is no sound.

Producer
GST_DEBUG=3 gst-launch-1.0 webrtcsink stun-server=NULL name=ws meta="meta,name=gst-stream" audiotestsrc ! ws.

Consumer
GST_DEBUG=3 gst-launch-1.0 webrtcsrc stun-server=NULL signaller::uri="ws://127.0.0.1:8443" signaller::producer-peer-id=[peer-id] ! autoaudiosink

It works for me :slight_smile: … as long as I have at least one network device up (e.g. ethernet link connected to a switch).

I also tried streaming a video over a LAN (not connected to the Internet) and it worked (firewall off on the server for simplicity).

Ok great!

I was testing this example on a single computer with network disabled. I know this is an artificial setup, but I don’t need two computers to develop (although I do for testing). Now, on rare occasions, I develop offline. So it could be a real problem. I don’t if it worth opening a bug issue though.

Anyway, I’ll test in real conditions and I’ll let you know.

Oh I see the use case now!

libnice doesn’t include loopback by default. It is possible to specify local_addresses and there is a signal in GStreamer to set these. So you probably could retrieve the element on which to call this signal and set it to use 127.0.0.1

A quicker workaround is to crate a dummy ethernet interface:

nmcli con add type dummy ifname dummy0 ipv4.method manual ipv4.addresses 192.168.2.1/24

Tested with:

gst-launch-1.0 audiotestsrc ! webrtcsink

and

gst-launch-1.0 webrtcsrc signaller::producer-peer-id=[_PEER_ID_] ! autoaudiosink

Remove the dummy interface with:

nmcli con delete dummy-dummy0

@FabPoll did you get a chance to try the above?

Partially. It’s ok on my computer but I need to check in real life example. I’ll try tomorrow

All good for me. I can use webrtcsink offline. Thanks

Keep in mind that Firefox refuses to allow WebRTC connections when offline - they have a completely artificial check along the lines of if (internet != connected) abort();, meaning you can’t use WebRTC over LAN alone.

I recommend Chromium if you need this.

1 Like