webrtcsrc: Added LiveKit source element

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1461>
This commit is contained in:
Jordan Yelloz 2024-02-13 11:48:29 -07:00
parent 96037fbcc5
commit fa006b9fc9
3 changed files with 133 additions and 0 deletions

View file

@ -7319,6 +7319,38 @@
},
"rank": "none"
},
"livekitwebrtcsrc": {
"author": "Jordan Yelloz <jordan.yelloz@collabora.com>",
"description": "WebRTC source with LiveKit signaller",
"hierarchy": [
"GstLiveKitWebRTCSrc",
"GstBaseWebRTCSrc",
"GstBin",
"GstElement",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
"interfaces": [
"GstChildProxy"
],
"klass": "Source/Network/WebRTC",
"pad-templates": {
"audio_%%u": {
"caps": "audio/x-raw(ANY):\napplication/x-rtp:\naudio/x-opus:\n",
"direction": "src",
"presence": "sometimes",
"type": "GstWebRTCSrcPad"
},
"video_%%u": {
"caps": "video/x-raw(ANY):\napplication/x-rtp:\nvideo/x-vp8:\nvideo/x-h264:\nvideo/x-vp9:\nvideo/x-h265:\n",
"direction": "src",
"presence": "sometimes",
"type": "GstWebRTCSrcPad"
}
},
"rank": "none"
},
"webrtcsink": {
"author": "Mathieu Duponchelle <mathieu@centricular.com>",
"description": "WebRTC sink with custom protocol signaller",

View file

@ -2,6 +2,7 @@
use gst::prelude::*;
use crate::livekit_signaller::LiveKitSignaller;
use crate::signaller::{prelude::*, Signallable, Signaller};
use crate::utils::{Codec, Codecs, NavigationEvent, AUDIO_CAPS, RTP_CAPS, VIDEO_CAPS};
use crate::webrtcsrc::WebRTCSrcPad;
@ -1290,3 +1291,44 @@ impl ObjectSubclass for WhipServerSrc {
type Type = super::WhipServerSrc;
type ParentType = super::BaseWebRTCSrc;
}
#[derive(Default)]
pub struct LiveKitWebRTCSrc;
impl ObjectImpl for LiveKitWebRTCSrc {
fn constructed(&self) {
self.parent_constructed();
let element = self.obj();
let ws = element.upcast_ref::<super::BaseWebRTCSrc>().imp();
let _ = ws.set_signaller(LiveKitSignaller::new_consumer().upcast());
}
}
impl GstObjectImpl for LiveKitWebRTCSrc {}
impl BinImpl for LiveKitWebRTCSrc {}
impl ElementImpl for LiveKitWebRTCSrc {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
gst::subclass::ElementMetadata::new(
"LiveKitWebRTCSrc",
"Source/Network/WebRTC",
"WebRTC source with LiveKit signaller",
"Jordan Yelloz <jordan.yelloz@collabora.com>",
)
});
Some(&*ELEMENT_METADATA)
}
}
impl BaseWebRTCSrcImpl for LiveKitWebRTCSrc {}
#[glib::object_subclass]
impl ObjectSubclass for LiveKitWebRTCSrc {
const NAME: &'static str = "GstLiveKitWebRTCSrc";
type Type = super::LiveKitWebRTCSrc;
type ParentType = super::BaseWebRTCSrc;
}

View file

@ -53,6 +53,10 @@ glib::wrapper! {
pub struct WhipServerSrc(ObjectSubclass<imp::WhipServerSrc>) @extends BaseWebRTCSrc, gst::Bin, gst::Element, gst::Object, @implements gst::URIHandler, gst::ChildProxy;
}
glib::wrapper! {
pub struct LiveKitWebRTCSrc(ObjectSubclass<imp::LiveKitWebRTCSrc>) @extends BaseWebRTCSrc, gst::Bin, gst::Element, gst::Object, @implements gst::URIHandler, gst::ChildProxy;
}
glib::wrapper! {
pub struct WebRTCSrcPad(ObjectSubclass<pad::WebRTCSrcPad>) @extends gst::GhostPad, gst::ProxyPad, gst::Pad, gst::Object;
}
@ -76,5 +80,60 @@ pub fn register(plugin: Option<&gst::Plugin>) -> Result<(), glib::BoolError> {
WhipServerSrc::static_type(),
)?;
/**
* element-livekitwebrtcsrc:
*
* The `livekitwebrtcsrc` plays streams from a LiveKit room.
*
* The element can either subscribe to the streams published by a single
* peer in the room using the same `signaller::producer-peer-id` child
* property that other webrtcsrc elements use or auto-subscribe to all peers
* in a room by not specifying anything for that property. When in
* auto-subscribe mode, you can use
* `signaller::excluded-producer-peer-ids=<a,b,c>` to ignore peers `a`, `b`,
* and `c` while subscribing to all other members of the room.
*
* ## Sample Pipeline
*
* First, start the livekit server with the `--dev` flag to enable the test credentials.
*
* Next, publish a stream:
*
* ```shell
* gst-launch-1.0 \
* videotestsrc is-live=1 \
* ! video/x-raw,width=640,height=360,framerate=15/1 \
* ! timeoverlay ! videoconvert ! queue \
* ! livekitwebrtcsink name=sink \
* signaller::ws-url=ws://127.0.0.1:7880 \
* signaller::api-key=devkey \
* signaller::secret-key=secret \
* signaller::room-name=testroom \
* signaller::identity=gst-producer \
* signaller::participant-name=gst-producer \
* video-caps='video/x-vp8'
* ```
*
* Finally, watch the stream:
*
* ```shell
* gst-launch-1.0 \
* livekitwebrtcsrc \
* signaller::ws-url=ws://127.0.0.1:7880 \
* signaller::api-key=devkey \
* signaller::secret-key=secret \
* signaller::room-name=testroom \
* signaller::identity=gst-consumer \
* signaller::participant-name=gst-consumer \
* ! queue ! videoconvert ! autovideosink
* ```
*/
gst::Element::register(
plugin,
"livekitwebrtcsrc",
gst::Rank::NONE,
LiveKitWebRTCSrc::static_type(),
)?;
Ok(())
}