mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-05-12 13:22:46 +00:00
Merge branch 'webrtcsrc-support-mutli-producer' into 'main'
net/webrtc: multi producer support in webrtcsrc See merge request gstreamer/gst-plugins-rs!1339
This commit is contained in:
commit
2413bdd4a9
34
Cargo.lock
generated
34
Cargo.lock
generated
|
@ -1263,15 +1263,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
|
@ -1370,6 +1361,16 @@ dependencies = [
|
|||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf"
|
||||
dependencies = [
|
||||
"nix 0.27.1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.8"
|
||||
|
@ -2946,7 +2947,7 @@ dependencies = [
|
|||
"aws-types",
|
||||
"chrono",
|
||||
"clap",
|
||||
"crossbeam-channel",
|
||||
"ctrlc",
|
||||
"data-encoding",
|
||||
"fastrand",
|
||||
"futures",
|
||||
|
@ -4183,7 +4184,7 @@ dependencies = [
|
|||
"if-addrs",
|
||||
"log",
|
||||
"multimap 0.8.3",
|
||||
"nix",
|
||||
"nix 0.23.2",
|
||||
"rand",
|
||||
"socket2 0.4.10",
|
||||
"thiserror",
|
||||
|
@ -4674,6 +4675,17 @@ dependencies = [
|
|||
"memoffset 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nnnoiseless"
|
||||
version = "0.5.1"
|
||||
|
|
|
@ -58,7 +58,8 @@ livekit-protocol = { version = "0.3", optional = true }
|
|||
livekit-api = { version = "0.3", default-features = false, features = ["signal-client", "access-token", "native-tls"], optional = true }
|
||||
|
||||
warp = {version = "0.3", optional = true }
|
||||
crossbeam-channel = { version = "0.5", optional = true }
|
||||
ctrlc = {version = "3.4.0", optional = true }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
gst-plugin-rtp = { path = "../rtp" }
|
||||
|
@ -89,7 +90,7 @@ aws = ["dep:aws-config", "dep:aws-types", "dep:aws-credential-types", "dep:aws-s
|
|||
"dep:aws-sdk-kinesisvideosignaling", "dep:data-encoding", "dep:http", "dep:url-escape"]
|
||||
janus = ["dep:http"]
|
||||
livekit = ["dep:livekit-protocol", "dep:livekit-api"]
|
||||
whip = ["dep:async-recursion", "dep:crossbeam-channel", "dep:reqwest", "dep:warp"]
|
||||
whip = ["dep:async-recursion", "dep:reqwest", "dep:warp", "dep:ctrlc"]
|
||||
|
||||
[package.metadata.capi]
|
||||
min_version = "0.9.21"
|
||||
|
@ -119,3 +120,6 @@ name = "webrtc-precise-sync-send"
|
|||
|
||||
[[example]]
|
||||
name = "webrtc-precise-sync-recv"
|
||||
|
||||
[[example]]
|
||||
name = "whipserver"
|
||||
|
|
123
net/webrtc/examples/whipserver.rs
Normal file
123
net/webrtc/examples/whipserver.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use std::process::exit;
|
||||
|
||||
use anyhow::Error;
|
||||
use clap::Parser;
|
||||
use gst::prelude::*;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Args {
|
||||
host_addr: String,
|
||||
}
|
||||
|
||||
fn link_video(pad: &gst::Pad, pipeline: &gst::Pipeline) {
|
||||
let q = gst::ElementFactory::make_with_name(
|
||||
"queue",
|
||||
Some(format!("queue_{}", pad.name()).as_str()),
|
||||
)
|
||||
.unwrap();
|
||||
// let vconv = gst::ElementFactory::make_with_name("videoconvert", Some(format!("vconv_{}",pad.name()).as_str())).unwrap();
|
||||
let vsink = gst::ElementFactory::make_with_name(
|
||||
"autovideosink",
|
||||
Some(format!("vsink_{}", pad.name()).as_str()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
pipeline.add_many([&q, &vsink]).unwrap();
|
||||
gst::Element::link_many([&q, &vsink]).unwrap();
|
||||
let qsinkpad = q.static_pad("sink").unwrap();
|
||||
pad.link(&qsinkpad).expect("linking should work");
|
||||
|
||||
q.sync_state_with_parent().unwrap();
|
||||
// vconv.sync_state_with_parent().unwrap();
|
||||
vsink.sync_state_with_parent().unwrap();
|
||||
}
|
||||
|
||||
fn unlink_video(pad: &gst::Pad, pipeline: &gst::Pipeline) {
|
||||
let q = pipeline
|
||||
.by_name(format!("queue_{}", pad.name()).as_str())
|
||||
.unwrap();
|
||||
// let vconv = pipeline.by_name(format!("vconv_{}",pad.name()).as_str()).unwrap();
|
||||
let vsink = pipeline
|
||||
.by_name(format!("vsink_{}", pad.name()).as_str())
|
||||
.unwrap();
|
||||
|
||||
q.set_state(gst::State::Null).unwrap();
|
||||
// vconv.set_state(gst::State::Null).unwrap();
|
||||
vsink.set_state(gst::State::Null).unwrap();
|
||||
|
||||
pipeline.remove_many([&q, &vsink]).unwrap();
|
||||
}
|
||||
|
||||
fn link_audio(_pad: &gst::Pad) {}
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
gst::init()?;
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
let pipeline = gst::Pipeline::builder().build();
|
||||
let ws = gst::ElementFactory::make("whipserversrc").build()?;
|
||||
ws.dynamic_cast_ref::<gst::ChildProxy>()
|
||||
.unwrap()
|
||||
.set_child_property("signaller::host-addr", &args.host_addr);
|
||||
|
||||
ws.set_property("enable-data-channel-navigation", true);
|
||||
|
||||
let pipe = pipeline.clone();
|
||||
ws.connect_pad_added(move |_ws, pad| {
|
||||
if pad.name().contains("video_") {
|
||||
link_video(pad, &pipe);
|
||||
} else if pad.name().contains("audio_") {
|
||||
} else {
|
||||
println!("unknown pad type {}", pad.name());
|
||||
}
|
||||
});
|
||||
|
||||
let pipe = pipeline.clone();
|
||||
ws.connect_pad_removed(move |_ws, pad| {
|
||||
if pad.name().contains("video_") {
|
||||
unlink_video(pad, &pipe);
|
||||
} else if pad.name().contains("audio_") {
|
||||
} else {
|
||||
println!("unknown pad type {}", pad.name());
|
||||
}
|
||||
});
|
||||
pipeline.add(&ws)?;
|
||||
pipeline.set_state(gst::State::Playing)?;
|
||||
|
||||
let p = pipeline.clone();
|
||||
ctrlc::set_handler(move || {
|
||||
p.set_state(gst::State::Null).unwrap();
|
||||
exit(0);
|
||||
})
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
|
||||
let bus = pipeline.bus().expect("Pipeline should have a bus");
|
||||
for msg in bus.iter_timed(gst::ClockTime::NONE) {
|
||||
use gst::MessageView;
|
||||
|
||||
match msg.view() {
|
||||
MessageView::Eos(..) => {
|
||||
println!("EOS");
|
||||
break;
|
||||
}
|
||||
MessageView::Error(err) => {
|
||||
pipeline.set_state(gst::State::Null)?;
|
||||
eprintln!(
|
||||
"Got error from {}: {} ({})",
|
||||
msg.src()
|
||||
.map(|s| String::from(s.path_string()))
|
||||
.unwrap_or_else(|| "None".into()),
|
||||
err.error(),
|
||||
err.debug().unwrap_or_else(|| "".into()),
|
||||
);
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pipeline.set_state(gst::State::Null)?;
|
||||
|
||||
Ok(())
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -18,9 +18,8 @@ use reqwest::header::HeaderValue;
|
|||
use reqwest::StatusCode;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use core::time::Duration;
|
||||
use crossbeam_channel::unbounded;
|
||||
use std::net::SocketAddr;
|
||||
use tokio::sync::mpsc;
|
||||
use url::Url;
|
||||
use warp::{
|
||||
http,
|
||||
|
@ -47,7 +46,6 @@ const ENDPOINT_PATH: &str = "endpoint";
|
|||
const RESOURCE_PATH: &str = "resource";
|
||||
const DEFAULT_HOST_ADDR: &str = "http://127.0.0.1:8080";
|
||||
const DEFAULT_STUN_SERVER: Option<&str> = Some("stun://stun.l.google.com:19303");
|
||||
const DEFAULT_PRODUCER_PEER_ID: Option<&str> = Some("whip-client");
|
||||
const CONTENT_SDP: &str = "application/sdp";
|
||||
const CONTENT_TRICKLE_ICE: &str = "application/trickle-ice-sdpfrag";
|
||||
|
||||
|
@ -193,7 +191,7 @@ impl WhipClient {
|
|||
let mut headermap = HeaderMap::new();
|
||||
headermap.insert(
|
||||
reqwest::header::CONTENT_TYPE,
|
||||
HeaderValue::from_static("application/sdp"),
|
||||
HeaderValue::from_static(CONTENT_SDP),
|
||||
);
|
||||
|
||||
if let Some(token) = auth_token.as_ref() {
|
||||
|
@ -616,27 +614,14 @@ impl ObjectImpl for WhipClient {
|
|||
// WHIP server implementation
|
||||
|
||||
#[derive(Debug)]
|
||||
enum WhipServerState {
|
||||
Idle,
|
||||
Negotiating,
|
||||
Ready,
|
||||
}
|
||||
|
||||
impl Default for WhipServerState {
|
||||
fn default() -> Self {
|
||||
Self::Idle
|
||||
}
|
||||
}
|
||||
|
||||
struct WhipServerSettings {
|
||||
stun_server: Option<String>,
|
||||
turn_servers: gst::Array,
|
||||
host_addr: Url,
|
||||
producer_peer_id: Option<String>,
|
||||
timeout: u32,
|
||||
shutdown_signal: Option<tokio::sync::oneshot::Sender<()>>,
|
||||
server_handle: Option<tokio::task::JoinHandle<()>>,
|
||||
sdp_answer: Option<crossbeam_channel::Sender<Option<SDPMessage>>>,
|
||||
sdp_answer: Option<mpsc::Sender<Option<SDPMessage>>>,
|
||||
}
|
||||
|
||||
impl Default for WhipServerSettings {
|
||||
|
@ -645,7 +630,6 @@ impl Default for WhipServerSettings {
|
|||
host_addr: Url::parse(DEFAULT_HOST_ADDR).unwrap(),
|
||||
stun_server: DEFAULT_STUN_SERVER.map(String::from),
|
||||
turn_servers: gst::Array::new(Vec::new() as Vec<glib::SendValue>),
|
||||
producer_peer_id: DEFAULT_PRODUCER_PEER_ID.map(String::from),
|
||||
timeout: DEFAULT_TIMEOUT,
|
||||
shutdown_signal: None,
|
||||
server_handle: None,
|
||||
|
@ -654,18 +638,10 @@ impl Default for WhipServerSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct WhipServer {
|
||||
state: Mutex<WhipServerState>,
|
||||
settings: Mutex<WhipServerSettings>,
|
||||
}
|
||||
|
||||
impl Default for WhipServer {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
settings: Mutex::new(WhipServerSettings::default()),
|
||||
state: Mutex::new(WhipServerState::default()),
|
||||
}
|
||||
}
|
||||
canceller: Mutex<Option<futures::future::AbortHandle>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -694,7 +670,7 @@ impl WhipServer {
|
|||
WebRTCICEGatheringState::Complete => {
|
||||
gst::info!(CAT, obj: obj, "ICE gathering complete");
|
||||
let ans: Option<gst_sdp::SDPMessage>;
|
||||
let settings = obj.imp().settings.lock().unwrap();
|
||||
let mut settings = obj.imp().settings.lock().unwrap();
|
||||
if let Some(answer_desc) = webrtcbin
|
||||
.property::<Option<WebRTCSessionDescription>>("local-description")
|
||||
{
|
||||
|
@ -702,9 +678,22 @@ impl WhipServer {
|
|||
} else {
|
||||
ans = None;
|
||||
}
|
||||
if let Some(tx) = &settings.sdp_answer {
|
||||
tx.send(ans).unwrap()
|
||||
}
|
||||
let tx = settings
|
||||
.sdp_answer
|
||||
.take()
|
||||
.expect("SDP answer Sender needs to be valid");
|
||||
|
||||
let obj_weak = obj.downgrade();
|
||||
RUNTIME.spawn(async move {
|
||||
let obj = match obj_weak.upgrade() {
|
||||
Some(obj) => obj,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if let Err(e) = tx.send(ans).await {
|
||||
gst::error!(CAT, obj: obj, "Failed to send SDP {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -722,57 +711,23 @@ impl WhipServer {
|
|||
//FIXME: add state checking once ICE trickle is implemented
|
||||
}
|
||||
|
||||
async fn delete_handler(&self, _id: String) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
WhipServerState::Ready => {
|
||||
// FIXME: session-ended will make webrtcsrc send EOS
|
||||
// and producer-removed is not handled
|
||||
// Need to address the usecase where when the client terminates
|
||||
// the webrtcsrc should be running without sending EOS and reset
|
||||
// for next client connection like a usual server
|
||||
|
||||
self.obj().emit_by_name::<bool>("session-ended", &[&ROOT]);
|
||||
|
||||
gst::info!(CAT, imp:self, "Ending session");
|
||||
*state = WhipServerState::Idle;
|
||||
Ok(warp::reply::reply().into_response())
|
||||
}
|
||||
_ => {
|
||||
gst::error!(CAT, imp: self, "DELETE requested in {state:?} state. Can't Proceed");
|
||||
let res = http::Response::builder()
|
||||
.status(http::StatusCode::CONFLICT)
|
||||
.body(Body::from(String::from("Session not Ready")))
|
||||
.unwrap();
|
||||
Ok(res)
|
||||
}
|
||||
async fn delete_handler(&self, id: String) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
if self
|
||||
.obj()
|
||||
.emit_by_name::<bool>("session-ended", &[&id.as_str()])
|
||||
{
|
||||
gst::info!(CAT, imp:self, "Ended session {id}");
|
||||
} else {
|
||||
gst::info!(CAT, imp:self, "Failed to End session {id}");
|
||||
// FIXME: Do we send a different response
|
||||
}
|
||||
Ok(warp::reply::reply().into_response())
|
||||
}
|
||||
|
||||
async fn options_handler(&self) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
let peer_id = settings.producer_peer_id.clone().unwrap();
|
||||
drop(settings);
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
WhipServerState::Idle => {
|
||||
self.obj()
|
||||
.emit_by_name::<()>("session-started", &[&ROOT, &peer_id]);
|
||||
*state = WhipServerState::Negotiating
|
||||
}
|
||||
WhipServerState::Ready => {
|
||||
gst::error!(CAT, imp: self, "OPTIONS requested in {state:?} state. Can't proceed");
|
||||
let res = http::Response::builder()
|
||||
.status(http::StatusCode::CONFLICT)
|
||||
.body(Body::from(String::from("Session active already")))
|
||||
.unwrap();
|
||||
return Ok(res);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
drop(state);
|
||||
|
||||
let mut links = HeaderMap::new();
|
||||
let settings = self.settings.lock().unwrap();
|
||||
match &settings.stun_server {
|
||||
|
@ -806,7 +761,7 @@ impl WhipServer {
|
|||
}
|
||||
|
||||
let mut res = http::Response::builder()
|
||||
.header("Access-Post", "application/sdp")
|
||||
.header("Access-Post", CONTENT_SDP)
|
||||
.body(Body::empty())
|
||||
.unwrap();
|
||||
|
||||
|
@ -820,31 +775,15 @@ impl WhipServer {
|
|||
&self,
|
||||
body: warp::hyper::body::Bytes,
|
||||
) -> Result<http::Response<warp::hyper::Body>, warp::Rejection> {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
let peer_id = settings.producer_peer_id.clone().unwrap();
|
||||
let wait_timeout = settings.timeout;
|
||||
let (tx, rx) = unbounded::<Option<SDPMessage>>();
|
||||
settings.sdp_answer = Some(tx);
|
||||
drop(settings);
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
WhipServerState::Idle => {
|
||||
self.obj()
|
||||
.emit_by_name::<()>("session-started", &[&ROOT, &peer_id]);
|
||||
*state = WhipServerState::Negotiating
|
||||
}
|
||||
WhipServerState::Ready => {
|
||||
gst::error!(CAT, imp: self, "POST requested in {state:?} state. Can't Proceed");
|
||||
let res = http::Response::builder()
|
||||
.status(http::StatusCode::CONFLICT)
|
||||
.body(Body::from(String::from("Session active already")))
|
||||
.unwrap();
|
||||
return Ok(res);
|
||||
}
|
||||
_ => {}
|
||||
let session_id = uuid::Uuid::new_v4().to_string();
|
||||
let (tx, mut rx) = mpsc::channel::<Option<SDPMessage>>(1);
|
||||
let wait_timeout = {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
let wait_timeout = settings.timeout;
|
||||
settings.sdp_answer = Some(tx);
|
||||
drop(settings);
|
||||
wait_timeout
|
||||
};
|
||||
drop(state);
|
||||
|
||||
match gst_sdp::SDPMessage::parse_buffer(body.as_ref()) {
|
||||
Ok(offer_sdp) => {
|
||||
|
@ -854,7 +793,9 @@ impl WhipServer {
|
|||
);
|
||||
|
||||
self.obj()
|
||||
.emit_by_name::<()>("session-description", &[&"unique", &offer]);
|
||||
.emit_by_name::<()>("session-started", &[&session_id, &session_id]);
|
||||
self.obj()
|
||||
.emit_by_name::<()>("session-description", &[&session_id, &offer]);
|
||||
}
|
||||
Err(err) => {
|
||||
gst::error!(CAT, imp: self, "Could not parse offer SDP: {err}");
|
||||
|
@ -864,20 +805,32 @@ impl WhipServer {
|
|||
}
|
||||
}
|
||||
|
||||
// We don't want to wait infinitely for the ice gathering to complete.
|
||||
let answer = match rx.recv_timeout(Duration::from_secs(wait_timeout as u64)) {
|
||||
Ok(a) => a,
|
||||
Err(e) => {
|
||||
let reply = warp::reply::reply();
|
||||
let res;
|
||||
if e.is_timeout() {
|
||||
res = warp::reply::with_status(reply, http::StatusCode::REQUEST_TIMEOUT);
|
||||
gst::error!(CAT, imp: self, "Timedout waiting for SDP answer");
|
||||
} else {
|
||||
res = warp::reply::with_status(reply, http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||
gst::error!(CAT, imp: self, "Channel got disconnected");
|
||||
let result = wait_async(&self.canceller, rx.recv(), wait_timeout).await;
|
||||
|
||||
let answer = match result {
|
||||
Ok(ans) => match ans {
|
||||
Some(a) => a,
|
||||
None => {
|
||||
let err = "Channel closed, can't receive SDP".to_owned();
|
||||
let res = http::Response::builder()
|
||||
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.body(Body::from(err))
|
||||
.unwrap();
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
return Ok(res.into_response());
|
||||
},
|
||||
Err(e) => {
|
||||
let err = match e {
|
||||
WaitError::FutureAborted => "Aborted".to_owned(),
|
||||
WaitError::FutureError(err) => err.to_string(),
|
||||
};
|
||||
let res = http::Response::builder()
|
||||
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.body(Body::from(err))
|
||||
.unwrap();
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -947,10 +900,10 @@ impl WhipServer {
|
|||
drop(settings);
|
||||
|
||||
// Got SDP answer, send answer in the response
|
||||
let resource_url = "/".to_owned() + ROOT + "/" + RESOURCE_PATH + "/" + &peer_id;
|
||||
let resource_url = "/".to_owned() + ROOT + "/" + RESOURCE_PATH + "/" + &session_id;
|
||||
let mut res = http::Response::builder()
|
||||
.status(StatusCode::CREATED)
|
||||
.header(CONTENT_TYPE, "application/sdp")
|
||||
.header(CONTENT_TYPE, CONTENT_SDP)
|
||||
.header("location", resource_url)
|
||||
.body(Body::from(ans_text.unwrap()))
|
||||
.unwrap();
|
||||
|
@ -958,10 +911,6 @@ impl WhipServer {
|
|||
let headers = res.headers_mut();
|
||||
headers.extend(links);
|
||||
|
||||
let mut state = self.state.lock().unwrap();
|
||||
*state = WhipServerState::Ready;
|
||||
drop(state);
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
|
@ -1117,7 +1066,8 @@ impl SignallableImpl for WhipServer {
|
|||
gst::info!(CAT, imp: self, "stopped the WHIP server");
|
||||
}
|
||||
|
||||
fn end_session(&self, _session_id: &str) {
|
||||
fn end_session(&self, session_id: &str) {
|
||||
gst::info!(CAT, imp: self, "Session {session_id} ended");
|
||||
//FIXME: send any events to the client
|
||||
}
|
||||
}
|
||||
|
@ -1140,11 +1090,6 @@ impl ObjectImpl for WhipServer {
|
|||
.default_value(DEFAULT_HOST_ADDR)
|
||||
.flags(glib::ParamFlags::READWRITE)
|
||||
.build(),
|
||||
// needed by webrtcsrc in handle_webrtc_src_pad
|
||||
glib::ParamSpecString::builder("producer-peer-id")
|
||||
.default_value(DEFAULT_PRODUCER_PEER_ID)
|
||||
.flags(glib::ParamFlags::READABLE)
|
||||
.build(),
|
||||
glib::ParamSpecString::builder("stun-server")
|
||||
.nick("STUN Server")
|
||||
.blurb("The STUN server of the form stun://hostname:port")
|
||||
|
@ -1204,7 +1149,6 @@ impl ObjectImpl for WhipServer {
|
|||
"host-addr" => settings.host_addr.to_string().to_value(),
|
||||
"stun-server" => settings.stun_server.to_value(),
|
||||
"turn-servers" => settings.turn_servers.to_value(),
|
||||
"producer-peer-id" => settings.producer_peer_id.to_value(),
|
||||
"timeout" => settings.timeout.to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue