From 7fcf6d6faf6900116f10e83cce439728fdbc5a91 Mon Sep 17 00:00:00 2001 From: Maksym Khomenko Date: Fri, 3 Nov 2023 23:24:54 +0200 Subject: [PATCH] webrtcsrc: add turn-servers property Part-of: --- docs/plugins/gst_plugins_cache.json | 15 +++++++++-- net/webrtc/src/webrtcsrc/imp.rs | 42 ++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json index 25b8ef6a..2bf5f2a2 100644 --- a/docs/plugins/gst_plugins_cache.json +++ b/docs/plugins/gst_plugins_cache.json @@ -6270,17 +6270,28 @@ "writable": true }, "stun-server": { - "blurb": "NULL", + "blurb": "The STUN server of the form stun://host:port", "conditionally-available": false, "construct": false, "construct-only": false, "controllable": false, "default": "stun://stun.l.google.com:19302", - "mutable": "null", + "mutable": "ready", "readable": true, "type": "gchararray", "writable": true }, + "turn-servers": { + "blurb": "The TURN servers of the form <\"turn(s)://username:password@host:port\", \"turn(s)://username1:password1@host1:port1\">", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "mutable": "ready", + "readable": true, + "type": "GstValueArray", + "writable": true + }, "video-codecs": { "blurb": "Names of video codecs to be be used during the SDP negotiation. Valid values: [VP8, H264, VP9, H265]", "conditionally-available": false, diff --git a/net/webrtc/src/webrtcsrc/imp.rs b/net/webrtc/src/webrtcsrc/imp.rs index 73a59c54..e10f0a1f 100644 --- a/net/webrtc/src/webrtcsrc/imp.rs +++ b/net/webrtc/src/webrtcsrc/imp.rs @@ -31,6 +31,7 @@ const RTP_TWCC_URI: &str = struct Settings { stun_server: Option, + turn_servers: gst::Array, signaller: Signallable, meta: Option, video_codecs: Vec, @@ -58,8 +59,21 @@ impl ObjectImpl for WebRTCSrc { static PROPS: Lazy> = Lazy::new(|| { vec![ glib::ParamSpecString::builder("stun-server") + .nick("The STUN server to use") + .blurb("The STUN server of the form stun://host:port") .flags(glib::ParamFlags::READWRITE) .default_value(DEFAULT_STUN_SERVER) + .mutable_ready() + .build(), + gst::ParamSpecArray::builder("turn-servers") + .nick("List of TURN servers to use") + .blurb("The TURN servers of the form <\"turn(s)://username:password@host:port\", \"turn(s)://username1:password1@host1:port1\">") + .element_spec(&glib::ParamSpecString::builder("turn-server") + .nick("TURN Server") + .blurb("The TURN server of the form turn(s)://username:password@host:port.") + .build() + ) + .mutable_ready() .build(), glib::ParamSpecObject::builder::("signaller") .flags(glib::ParamFlags::READWRITE | glib::ParamFlags::CONSTRUCT_ONLY) @@ -104,29 +118,33 @@ impl ObjectImpl for WebRTCSrc { "video-codecs" => { self.settings.lock().unwrap().video_codecs = value .get::() - .expect("Type checked upstream") + .expect("type checked upstream") .as_slice() .iter() .filter_map(|codec_name| { - Codecs::find(codec_name.get::<&str>().expect("Type checked upstream")) + Codecs::find(codec_name.get::<&str>().expect("type checked upstream")) }) .collect::>() } "audio-codecs" => { self.settings.lock().unwrap().audio_codecs = value .get::() - .expect("Type checked upstream") + .expect("type checked upstream") .as_slice() .iter() .filter_map(|codec_name| { - Codecs::find(codec_name.get::<&str>().expect("Type checked upstream")) + Codecs::find(codec_name.get::<&str>().expect("type checked upstream")) }) .collect::>() } "stun-server" => { self.settings.lock().unwrap().stun_server = value .get::>() - .expect("type checked upstream") + .expect("type checked upstream"); + } + "turn-servers" => { + let mut settings = self.settings.lock().unwrap(); + settings.turn_servers = value.get::().expect("type checked upstream"); } "meta" => { self.settings.lock().unwrap().meta = value @@ -159,6 +177,7 @@ impl ObjectImpl for WebRTCSrc { ) .to_value(), "stun-server" => self.settings.lock().unwrap().stun_server.to_value(), + "turn-servers" => self.settings.lock().unwrap().turn_servers.to_value(), "meta" => self.settings.lock().unwrap().meta.to_value(), name => panic!("{} getter not implemented", name), } @@ -215,6 +234,7 @@ impl Default for Settings { Self { stun_server: DEFAULT_STUN_SERVER.map(|v| v.to_string()), + turn_servers: Default::default(), signaller: signaller.upcast(), meta: Default::default(), audio_codecs: Codecs::audio_codecs() @@ -420,8 +440,16 @@ impl WebRTCSrc { .build() .with_context(|| "Failed to make element webrtcbin".to_string())?; - if let Some(stun_server) = self.settings.lock().unwrap().stun_server.as_ref() { - webrtcbin.set_property("stun-server", stun_server); + { + let settings = self.settings.lock().unwrap(); + + if let Some(stun_server) = settings.stun_server.as_ref() { + webrtcbin.set_property("stun-server", stun_server); + } + + for turn_server in settings.turn_servers.iter() { + webrtcbin.emit_by_name::("add-turn-server", &[&turn_server]); + } } let bin = gst::Bin::new();