Add a WebRTC WHEP source element

This implements WHEP specification based on
https://datatracker.ietf.org/doc/html/draft-murillo-whep-00

and has been tested with Cloudflare.

Server offers are likely to be removed from the WHEP specification
in upcoming revisions, to avoid compatibility issues. None of the
commercial services implementing WHEP support server initiated offers.
So we only support client side initiated offers.

Follows session setup and tear down as covered in Figure 1, Section 3
of the specification.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/949>
This commit is contained in:
Sanchayan Maity 2022-10-24 12:18:31 +05:30
parent 3172bcd095
commit 6be5796888
5 changed files with 1357 additions and 5 deletions

View file

@ -7748,8 +7748,145 @@
"url": "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
},
"webrtchttp": {
"description": "GStreamer WebRTC Plugin for WebRTC HTTP protocols (WHIP)",
"description": "GStreamer WebRTC Plugin for WebRTC HTTP protocols (WHIP/WHEP)",
"elements": {
"whepsrc": {
"author": "Sanchayan Maity <sanchayan@asymptotic.io>",
"description": "A bin to stream media using the WebRTC HTTP Egress Protocol (WHEP)",
"hierarchy": [
"GstWhepSrc",
"GstBin",
"GstElement",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
"interfaces": [
"GstChildProxy"
],
"klass": "Source/Network/WebRTC",
"long-name": "WHEP Source Bin",
"pad-templates": {
"src_%%u": {
"caps": "application/x-rtp:\n",
"direction": "src",
"presence": "sometimes"
}
},
"properties": {
"audio-caps": {
"blurb": "Governs what audio codecs will be proposed",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "audio/x-opus",
"mutable": "null",
"readable": true,
"type": "GstCaps",
"writable": true
},
"auth-token": {
"blurb": "Authentication token to use, will be sent in the HTTP Header as 'Bearer <auth-token>'",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "NULL",
"mutable": "null",
"readable": true,
"type": "gchararray",
"writable": true
},
"ice-transport-policy": {
"blurb": "The policy to apply for ICE transport",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "all (0)",
"mutable": "null",
"readable": true,
"type": "GstRsWebRTCICETransportPolicy",
"writable": true
},
"stun-server": {
"blurb": "The STUN server of the form stun://hostname:port",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "NULL",
"mutable": "null",
"readable": true,
"type": "gchararray",
"writable": true
},
"timeout": {
"blurb": "Value in seconds to timeout WHEP endpoint requests (0 = No timeout).",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "15",
"max": "3600",
"min": "0",
"mutable": "null",
"readable": true,
"type": "guint",
"writable": true
},
"turn-server": {
"blurb": "The TURN server of the form turn(s)://username:password@host:port.",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "NULL",
"mutable": "null",
"readable": true,
"type": "gchararray",
"writable": true
},
"use-link-headers": {
"blurb": "Use link headers to configure ICE servers from the WHEP server response.",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"video-caps": {
"blurb": "Governs what video codecs will be proposed",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "video/x-vp8; video/x-h264; video/x-vp9; video/x-h265",
"mutable": "null",
"readable": true,
"type": "GstCaps",
"writable": true
},
"whep-endpoint": {
"blurb": "The WHEP server endpoint to POST SDP offer to. Example: http://localhost:7090/whep/endpoint/abc123",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "NULL",
"mutable": "null",
"readable": true,
"type": "gchararray",
"writable": true
}
},
"rank": "marginal"
},
"whipsink": {
"author": "Taruntej Kanakamalla <taruntej@asymptotic.io>",
"description": "A bin to stream media using the WebRTC HTTP Ingestion Protocol (WHIP)",
@ -7816,7 +7953,23 @@
},
"filename": "gstwebrtchttp",
"license": "MPL",
"other-types": {},
"other-types": {
"GstRsWebRTCICETransportPolicy": {
"kind": "enum",
"values": [
{
"desc": "All: get both STUN and TURN candidate pairs",
"name": "all",
"value": "0"
},
{
"desc": "Relay: get only TURN candidate pairs",
"name": "relay",
"value": "1"
},
]
},
},
"package": "gst-plugin-webrtchttp",
"source": "gst-plugin-webrtchttp",
"tracers": {},

View file

@ -5,7 +5,7 @@ authors = ["Taruntej Kanakamalla <taruntej@asymptotic.io"]
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
license = "MPL-2.0"
edition = "2021"
description = "GStreamer WebRTC Plugin for WebRTC HTTP protocols (WHIP)"
description = "GStreamer WebRTC Plugin for WebRTC HTTP protocols (WHIP/WHEP)"
rust-version = "1.63"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -21,6 +21,7 @@ once_cell = "1.0"
parse_link_header = {version = "0.3", features = ["url"]}
tokio = { version = "1.20.1", default-features = false, features = ["time", "rt-multi-thread"] }
futures = "0.3.23"
bytes = "1"
[dev-dependencies.gst-check]
git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs"

View file

@ -1,5 +1,6 @@
// Copyright (C) 2022, Asymptotic Inc.
// Copyright (C) 2022, Asymptotic Inc.
// Author: Taruntej Kanakamalla <taruntej@asymptotic.io>
// Author: Sanchayan Maity <sanchayan@asymptotic.io>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
@ -14,10 +15,30 @@
* Since: plugins-rs-0.9.0
*/
use gst::glib;
mod whepsrc;
mod whipsink;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, glib::Enum)]
#[repr(u32)]
#[enum_type(name = "GstRsWebRTCICETransportPolicy")]
#[non_exhaustive]
pub enum GstRsWebRTCICETransportPolicy {
#[enum_value(name = "All: get both STUN and TURN candidate pairs", nick = "all")]
All = 0,
#[enum_value(name = "Relay: get only TURN candidate pairs", nick = "relay")]
Relay = 1,
}
fn plugin_init(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
whipsink::register(plugin)
#[cfg(feature = "doc")]
{
GstRsWebRTCICETransportPolicy::static_type()
.mark_as_plugin_api(gst::PluginAPIFlags::empty());
}
whipsink::register(plugin)?;
whepsrc::register(plugin)?;
Ok(())
}
gst::plugin_define!(

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
// Copyright (C) 2022, Asymptotic Inc.
// Author: Sanchayan Maity <sanchayan@asymptotic.io>
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at
// <https://mozilla.org/MPL/2.0/>.
//
// SPDX-License-Identifier: MPL-2.0
use gst::glib;
use gst::prelude::*;
pub mod imp;
glib::wrapper! {
pub struct WhepSrc(ObjectSubclass<imp::WhepSrc>) @extends gst::Bin, gst::Element, gst::Object;
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),
"whepsrc",
gst::Rank::Marginal,
WhepSrc::static_type(),
)
}