2022-10-18 18:16:49 +00:00
// SPDX-License-Identifier: MPL-2.0
2022-11-19 00:43:03 +00:00
use crate ::signaller ::Signallable ;
2023-06-08 23:06:36 +00:00
/**
* SECTION :element - webrtcsink
* @ symbols :
* - GstBaseWebRTCSink
* - GstRSWebRTCSignallableIface
*
* ` webrtcsink ` is an element that can be used to serve media streams
* to multiple consumers through WebRTC .
*
* It uses a signaller that implements the protocol supported by the default
* signalling server we additionally provide , take a look at the subclasses of
* #GstBaseWebRTCSink for other supported protocols , or implement your own .
*
* See the [ documentation of the plugin ] ( plugin - rswebrtc ) for more information
* on features and usage .
* /
2022-10-20 10:25:32 +00:00
/**
2023-06-08 23:06:36 +00:00
* GstBaseWebRTCSink :
* @ title : Base class for WebRTC producers
2022-10-20 10:25:32 +00:00
*
2023-06-08 23:06:36 +00:00
* Base class for WebRTC sinks to implement and provide their own protocol for .
* /
/**
* GstRSWebRTCSignallableIface :
* @ title : Interface for WebRTC signalling protocols
2022-10-20 10:25:32 +00:00
*
2023-06-08 23:06:36 +00:00
* Interface that WebRTC elements can implement their own protocol with .
2022-10-20 10:25:32 +00:00
* /
2021-10-05 21:28:05 +00:00
use gst ::glib ;
use gst ::prelude ::* ;
2022-05-11 20:58:53 +00:00
use gst ::subclass ::prelude ::* ;
2021-10-05 21:28:05 +00:00
2022-07-28 03:22:25 +00:00
mod homegrown_cc ;
2022-11-19 00:43:03 +00:00
2021-10-05 21:28:05 +00:00
mod imp ;
2024-01-19 21:59:55 +00:00
mod pad ;
2021-10-05 21:28:05 +00:00
glib ::wrapper! {
2023-04-13 15:02:18 +00:00
pub struct BaseWebRTCSink ( ObjectSubclass < imp ::BaseWebRTCSink > ) @ extends gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
2021-10-05 21:28:05 +00:00
}
2024-01-19 21:59:55 +00:00
glib ::wrapper! {
pub struct WebRTCSinkPad ( ObjectSubclass < pad ::WebRTCSinkPad > ) @ extends gst ::GhostPad , gst ::ProxyPad , gst ::Pad , gst ::Object ;
}
2023-03-01 23:01:43 +00:00
glib ::wrapper! {
2023-04-13 15:02:18 +00:00
pub struct WebRTCSink ( ObjectSubclass < imp ::WebRTCSink > ) @ extends BaseWebRTCSink , gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
}
glib ::wrapper! {
pub struct AwsKvsWebRTCSink ( ObjectSubclass < imp ::AwsKvsWebRTCSink > ) @ extends BaseWebRTCSink , gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
2023-03-01 23:01:43 +00:00
}
2021-10-05 21:28:05 +00:00
2023-04-06 22:41:16 +00:00
glib ::wrapper! {
pub struct WhipWebRTCSink ( ObjectSubclass < imp ::WhipWebRTCSink > ) @ extends BaseWebRTCSink , gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
}
2023-06-21 19:54:00 +00:00
glib ::wrapper! {
pub struct LiveKitWebRTCSink ( ObjectSubclass < imp ::LiveKitWebRTCSink > ) @ extends BaseWebRTCSink , gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
}
2023-10-16 16:16:52 +00:00
glib ::wrapper! {
pub struct JanusVRWebRTCSink ( ObjectSubclass < imp ::JanusVRWebRTCSink > ) @ extends BaseWebRTCSink , gst ::Bin , gst ::Element , gst ::Object , @ implements gst ::ChildProxy , gst_video ::Navigation ;
}
2021-12-21 22:37:29 +00:00
#[ derive(thiserror::Error, Debug) ]
pub enum WebRTCSinkError {
2022-07-14 18:25:12 +00:00
#[ error( " no session with id " ) ]
NoSessionWithId ( String ) ,
2021-12-21 22:37:29 +00:00
#[ error( " consumer refused media " ) ]
2022-07-14 18:25:12 +00:00
ConsumerRefusedMedia { session_id : String , media_idx : u32 } ,
2021-12-21 22:37:29 +00:00
#[ error( " consumer did not provide valid payload for media " ) ]
2022-07-14 18:25:12 +00:00
ConsumerNoValidPayload { session_id : String , media_idx : u32 } ,
2021-12-21 22:37:29 +00:00
#[ error( " SDP mline index is currently mandatory " ) ]
MandatorySdpMlineIndex ,
2022-07-14 18:25:12 +00:00
#[ error( " duplicate session id " ) ]
DuplicateSessionId ( String ) ,
2021-12-21 22:37:29 +00:00
#[ error( " error setting up consumer pipeline " ) ]
2022-07-14 18:25:12 +00:00
SessionPipelineError {
session_id : String ,
peer_id : String ,
details : String ,
} ,
2021-12-21 22:37:29 +00:00
}
2023-04-13 15:02:18 +00:00
impl Default for BaseWebRTCSink {
2022-11-19 00:43:03 +00:00
fn default ( ) -> Self {
glib ::Object ::new ( )
}
2021-10-05 21:28:05 +00:00
}
2023-04-13 15:02:18 +00:00
impl BaseWebRTCSink {
2022-11-19 00:43:03 +00:00
pub fn with_signaller ( signaller : Signallable ) -> Self {
2023-04-13 15:02:18 +00:00
let ret : BaseWebRTCSink = glib ::Object ::new ( ) ;
2021-10-05 21:28:05 +00:00
2022-10-23 20:03:22 +00:00
let ws = ret . imp ( ) ;
2021-10-05 21:28:05 +00:00
ws . set_signaller ( signaller ) . unwrap ( ) ;
ret
}
}
2021-11-24 14:05:44 +00:00
#[ derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, glib::Enum) ]
2021-11-04 17:26:50 +00:00
#[ repr(u32) ]
2021-11-24 14:05:44 +00:00
#[ enum_type(name = " GstWebRTCSinkCongestionControl " ) ]
2021-11-04 17:26:50 +00:00
pub enum WebRTCSinkCongestionControl {
2021-11-24 14:05:44 +00:00
#[ enum_value(name = " Disabled: no congestion control is applied " , nick = " disabled " ) ]
2021-11-04 17:26:50 +00:00
Disabled ,
2021-11-24 14:05:44 +00:00
#[ enum_value(name = " Homegrown: simple sender-side heuristic " , nick = " homegrown " ) ]
2021-11-04 17:26:50 +00:00
Homegrown ,
2022-05-11 20:58:53 +00:00
#[ enum_value(name = " Google Congestion Control algorithm " , nick = " gcc " ) ]
GoogleCongestionControl ,
2021-11-04 17:26:50 +00:00
}
2021-11-30 21:43:17 +00:00
#[ glib::flags(name = " GstWebRTCSinkMitigationMode " ) ]
enum WebRTCSinkMitigationMode {
#[ flags_value(name = " No mitigation applied " , nick = " none " ) ]
NONE = 0b00000000 ,
#[ flags_value(name = " Lowered resolution " , nick = " downscaled " ) ]
DOWNSCALED = 0b00000001 ,
#[ flags_value(name = " Lowered framerate " , nick = " downsampled " ) ]
DOWNSAMPLED = 0b00000010 ,
}
2021-10-05 21:28:05 +00:00
pub fn register ( plugin : & gst ::Plugin ) -> Result < ( ) , glib ::BoolError > {
2024-01-19 21:59:55 +00:00
WebRTCSinkPad ::static_type ( ) . mark_as_plugin_api ( gst ::PluginAPIFlags ::empty ( ) ) ;
2023-04-13 15:02:18 +00:00
BaseWebRTCSink ::static_type ( ) . mark_as_plugin_api ( gst ::PluginAPIFlags ::empty ( ) ) ;
2022-08-16 14:44:41 +00:00
WebRTCSinkCongestionControl ::static_type ( ) . mark_as_plugin_api ( gst ::PluginAPIFlags ::empty ( ) ) ;
2021-10-05 21:28:05 +00:00
gst ::Element ::register (
Some ( plugin ) ,
" webrtcsink " ,
2023-11-02 12:10:59 +00:00
gst ::Rank ::NONE ,
2021-10-05 21:28:05 +00:00
WebRTCSink ::static_type ( ) ,
2023-03-01 23:01:43 +00:00
) ? ;
gst ::Element ::register (
Some ( plugin ) ,
" awskvswebrtcsink " ,
2023-11-02 12:10:59 +00:00
gst ::Rank ::NONE ,
2023-03-01 23:01:43 +00:00
AwsKvsWebRTCSink ::static_type ( ) ,
) ? ;
2023-04-06 22:41:16 +00:00
gst ::Element ::register (
Some ( plugin ) ,
2023-08-16 06:48:04 +00:00
" whipclientsink " ,
2023-11-02 12:10:59 +00:00
gst ::Rank ::NONE ,
2023-04-06 22:41:16 +00:00
WhipWebRTCSink ::static_type ( ) ,
) ? ;
2023-06-21 19:54:00 +00:00
gst ::Element ::register (
Some ( plugin ) ,
" livekitwebrtcsink " ,
2023-11-02 12:10:59 +00:00
gst ::Rank ::NONE ,
2023-06-21 19:54:00 +00:00
LiveKitWebRTCSink ::static_type ( ) ,
) ? ;
2023-10-16 16:16:52 +00:00
/**
* element - janusvrwebrtcsink :
*
* The ` JanusVRWebRTCSink ` is a plugin that integrates with the [ Video Room plugin ] ( https ://janus.conf.meetecho.com/docs/videoroom) of the [Janus Gateway](https://github.com/meetecho/janus-gateway). It basically streams whatever data you pipe to it (video, audio) into WebRTC using Janus as the signaller.
*
* ## How to use it
*
* You ' ll need to have :
*
* - A Janus server endpoint ;
* - Any WebRTC browser application that uses Janus as the signaller , eg : the ` html ` folder of [ janus - gateway repository ] ( https ://github.com/meetecho/janus-gateway).
*
* You can pipe the video like this ( if you don ' t happen to run Janus locally , you can set the endpoint
* like this : ` signaller ::janus - endpoint = ws ://127.0.0.1:8188`):
*
* ` ` ` bash
* $ gst - launch - 1.0 videotestsrc ! janusvrwebrtcsink signaller ::room - id = 1234
* ` ` `
*
* And for audio ( yes you can do both at the same time , you just need to pipe it properly ) .
*
* ` ` ` bash
* $ gst - launch - 1.0 audiotestsrc ! janusvrwebrtcsink signaller ::room - id = 1234
* ` ` `
*
* And you can set the display name via ` signaller ::display - name ` , eg :
*
* ` ` ` bash
* $ gst - launch - 1.0 videotestsrc ! janusvrwebrtcsink signaller ::room - id = 1234 signaller ::display - name = ana
* ` ` `
*
* You should see the GStreamer ` videotestsrc ` / ` audiotestsrc ` output in your browser now !
*
* If for some reason you can ' t run Janus locally , you can use their open [ demo webpage ] ( https ://janus.conf.meetecho.com/demos/videoroom.html), and point to its WebSocket server:
*
* ` ` ` bash
* $ gst - launch - 1.0 videotestsrc ! janusvrwebrtcsink signaller ::room - id = 1234 signaller ::janus - endpoint = wss ://janus.conf.meetecho.com/ws
* ` ` `
*
* ## Reference links
*
* - [ Janus REST / WebSockets docs ] ( https ://janus.conf.meetecho.com/docs/rest.html)
* - [ Example implementation in GStreamer ] ( https ://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/269ab858813e670d521cc4b6a71cc0ec4a6e70ed/subprojects/gst-examples/webrtc/janus/rust/src/janus.rs)
*
* ## Notes
*
* - This plugin supports both the legacy Video Room plugin as well as the ` multistream ` one ;
* - If you see a warning in the logs related to ` rtpgccbwe ` , you ' re probably missing the ` gst - plugin - rtp ` in your system .
* /
gst ::Element ::register (
Some ( plugin ) ,
" janusvrwebrtcsink " ,
gst ::Rank ::NONE ,
JanusVRWebRTCSink ::static_type ( ) ,
) ? ;
2023-03-01 23:01:43 +00:00
Ok ( ( ) )
2021-10-05 21:28:05 +00:00
}