Automatically determine xmpp-domain if not specified, update README
This commit is contained in:
parent
ca8cca9393
commit
32a0742d08
11
README.md
11
README.md
|
@ -1,6 +1,6 @@
|
||||||
# gst-meet: Integrate Jitsi Meet conferences with GStreamer pipelines
|
# gst-meet: Integrate Jitsi Meet conferences with GStreamer pipelines
|
||||||
|
|
||||||
Note: gst-meet is in an **alpha** state and is under active development. The command-line options and the lib-gst-meet API are subject to change, and some important features (simulcast, RTX, TCC) are not yet fully functional.
|
Note: gst-meet is in an **alpha** state and is under active development. The command-line options and the lib-gst-meet API are subject to change.
|
||||||
|
|
||||||
gst-meet provides a library and tool for integrating Jitsi Meet conferences with GStreamer pipelines. You can pipe audio and video into a conference as a participant, and pipe out other participants' audio and video streams.
|
gst-meet provides a library and tool for integrating Jitsi Meet conferences with GStreamer pipelines. You can pipe audio and video into a conference as a participant, and pipe out other participants' audio and video streams.
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ You can pass two different pipeline fragments to gst-meet.
|
||||||
|
|
||||||
`--send-pipeline` is for sending audio and video. If it contains an element named `audio`, this audio will be streamed to the conference. The audio codec must be 48kHz Opus. If it contains an element named `video`, this video will be streamed to the conference. The video codec must match the codec passed to `--video-codec`, which is VP8 by default.
|
`--send-pipeline` is for sending audio and video. If it contains an element named `audio`, this audio will be streamed to the conference. The audio codec must be 48kHz Opus. If it contains an element named `video`, this video will be streamed to the conference. The video codec must match the codec passed to `--video-codec`, which is VP8 by default.
|
||||||
|
|
||||||
`--recv-pipeline-participant-template` is for receiving audio and video from other participants. This pipeline will be created once for each other participant in the conference. If it contains an element named `audio`, the participant's audio (48kHz Opus) will be sent to that element. If it contains an element named `video`, the participant's video (encoded with the codec selected by `--video-codec`) will be sent to that element. The strings `{jid}`, `{jid_user}`, `{participant_id}` and `{nick}` are replaced in the template with the participant's full JID, user part, MUC JID resource part (a.k.a. participant/occupant ID) and nickname respectively.
|
`--recv-pipeline-participant-template` is for receiving audio and video from other participants. This pipeline will be created once for each other participant in the conference. If it contains an element named `audio`, the participant's audio (48kHz Opus) will be sent to that element. If it contains an element named `video`, the participant's video will be sent to that element. The strings `{jid}`, `{jid_user}`, `{participant_id}` and `{nick}` are replaced in the template with the participant's full JID, user part, MUC JID resource part (a.k.a. participant/occupant ID) and nickname respectively.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
@ -54,7 +54,6 @@ Stream an Opus audio file to the conference. This is very efficient; the Opus da
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--send-pipeline="filesrc location=sample.opus ! queue ! oggdemux name=audio"
|
--send-pipeline="filesrc location=sample.opus ! queue ! oggdemux name=audio"
|
||||||
```
|
```
|
||||||
|
@ -63,7 +62,6 @@ Stream a FLAC audio file to the conference, transcoding it to Opus:
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--send-pipeline="filesrc location=shake-it-off.flac ! queue ! flacdec ! audioconvert ! audioresample ! opusenc name=audio"
|
--send-pipeline="filesrc location=shake-it-off.flac ! queue ! flacdec ! audioconvert ! audioresample ! opusenc name=audio"
|
||||||
```
|
```
|
||||||
|
@ -72,7 +70,6 @@ Stream a .webm file containing VP8 video and Vorbis audio to the conference. Thi
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--send-pipeline="filesrc location=big-buck-bunny_trailer.webm ! queue ! matroskademux name=demuxer
|
--send-pipeline="filesrc location=big-buck-bunny_trailer.webm ! queue ! matroskademux name=demuxer
|
||||||
demuxer.video_0 ! queue name=video
|
demuxer.video_0 ! queue name=video
|
||||||
|
@ -83,7 +80,6 @@ Stream the default video & audio inputs to the conference, encoding as VP8 and O
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--send-pipeline="autovideosrc ! queue ! videoconvert ! vp8enc buffer-size=1000 deadline=1 name=video
|
--send-pipeline="autovideosrc ! queue ! videoconvert ! vp8enc buffer-size=1000 deadline=1 name=video
|
||||||
autoaudiosrc ! queue ! audioconvert ! audioresample ! opusenc name=audio" \
|
autoaudiosrc ! queue ! audioconvert ! audioresample ! opusenc name=audio" \
|
||||||
|
@ -95,7 +91,6 @@ Record a .webm file for each other participant, containing VP8 video and Opus au
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--recv-pipeline-participant-template="webmmux name=muxer ! filesink location={participant_id}.webm
|
--recv-pipeline-participant-template="webmmux name=muxer ! filesink location={participant_id}.webm
|
||||||
opusparse name=audio ! muxer.audio_0
|
opusparse name=audio ! muxer.audio_0
|
||||||
|
@ -106,7 +101,6 @@ The above .webm file unfortunately may not play in most players, because the res
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--recv-pipeline-participant-template="webmmux name=muxer ! filesink location={participant_id}.webm
|
--recv-pipeline-participant-template="webmmux name=muxer ! filesink location={participant_id}.webm
|
||||||
opusparse name=audio ! muxer.audio_0
|
opusparse name=audio ! muxer.audio_0
|
||||||
|
@ -118,7 +112,6 @@ Play a YouTube video in the conference. By requesting Opus audio and VP9 video f
|
||||||
```
|
```
|
||||||
YOUTUBE_URL="https://www.youtube.com/watch?v=vjV_2Ri2rfE"
|
YOUTUBE_URL="https://www.youtube.com/watch?v=vjV_2Ri2rfE"
|
||||||
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
|
||||||
--xmpp-domain=your.jitsi.domain \
|
|
||||||
--room-name=roomname \
|
--room-name=roomname \
|
||||||
--video-codec=vp9 \
|
--video-codec=vp9 \
|
||||||
--send-pipeline="curlhttpsrc location=\"$(youtube-dl -g $YOUTUBE_URL -f 'bestaudio[acodec=opus]')\" ! queue ! matroskademux name=audiodemux
|
--send-pipeline="curlhttpsrc location=\"$(youtube-dl -g $YOUTUBE_URL -f 'bestaudio[acodec=opus]')\" ! queue ! matroskademux name=audiodemux
|
||||||
|
|
|
@ -9,6 +9,7 @@ use gstreamer::{
|
||||||
prelude::{ElementExt, GstBinExt},
|
prelude::{ElementExt, GstBinExt},
|
||||||
GhostPad,
|
GhostPad,
|
||||||
};
|
};
|
||||||
|
use http::Uri;
|
||||||
use lib_gst_meet::{
|
use lib_gst_meet::{
|
||||||
init_tracing, Authentication, Connection, JitsiConference, JitsiConferenceConfig, MediaType,
|
init_tracing, Authentication, Connection, JitsiConference, JitsiConferenceConfig, MediaType,
|
||||||
};
|
};
|
||||||
|
@ -24,15 +25,28 @@ use tracing::{error, info, trace, warn};
|
||||||
struct Opt {
|
struct Opt {
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
web_socket_url: String,
|
web_socket_url: String,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
xmpp_domain: String,
|
long,
|
||||||
|
help = "If not specified, assumed to be the host part of <web-socket-url>",
|
||||||
|
)]
|
||||||
|
xmpp_domain: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
room_name: String,
|
room_name: String,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "If not specified, assumed to be conference.<xmpp-domain>",
|
||||||
|
)]
|
||||||
muc_domain: Option<String>,
|
muc_domain: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "If not specified, assumed to be focus@auth.<xmpp-domain>/focus",
|
||||||
|
)]
|
||||||
focus_jid: Option<String>,
|
focus_jid: Option<String>,
|
||||||
#[structopt(long, default_value = "vp8")]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
default_value = "vp8",
|
||||||
|
help = "The video codec to negotiate support for. One of: vp8, vp9, h264",
|
||||||
|
)]
|
||||||
video_codec: String,
|
video_codec: String,
|
||||||
#[structopt(long, default_value = "gst-meet")]
|
#[structopt(long, default_value = "gst-meet")]
|
||||||
nick: String,
|
nick: String,
|
||||||
|
@ -42,13 +56,25 @@ struct Opt {
|
||||||
send_pipeline: Option<String>,
|
send_pipeline: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
recv_pipeline_participant_template: Option<String>,
|
recv_pipeline_participant_template: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "Comma-separated endpoint IDs to select (prioritise receiving of)",
|
||||||
|
)]
|
||||||
select_endpoints: Option<String>,
|
select_endpoints: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "The maximum number of video streams we would like to receive",
|
||||||
|
)]
|
||||||
last_n: Option<u16>,
|
last_n: Option<u16>,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "The maximum height to receive video at."
|
||||||
|
)]
|
||||||
recv_video_height: Option<u16>,
|
recv_video_height: Option<u16>,
|
||||||
#[structopt(long)]
|
#[structopt(
|
||||||
|
long,
|
||||||
|
help = "The video type to signal that we are sending. One of: camera, desktop"
|
||||||
|
)]
|
||||||
video_type: Option<String>,
|
video_type: Option<String>,
|
||||||
#[structopt(long)]
|
#[structopt(long)]
|
||||||
start_bitrate: Option<u32>,
|
start_bitrate: Option<u32>,
|
||||||
|
@ -128,10 +154,18 @@ async fn main_inner() -> Result<()> {
|
||||||
.map(|pipeline| gstreamer::parse_bin_from_description(pipeline, false))
|
.map(|pipeline| gstreamer::parse_bin_from_description(pipeline, false))
|
||||||
.transpose()
|
.transpose()
|
||||||
.context("failed to parse send pipeline")?;
|
.context("failed to parse send pipeline")?;
|
||||||
|
|
||||||
|
let web_socket_url: Uri = opt.web_socket_url.parse()?;
|
||||||
|
|
||||||
|
let xmpp_domain = opt
|
||||||
|
.xmpp_domain
|
||||||
|
.as_deref()
|
||||||
|
.or_else(|| web_socket_url.host())
|
||||||
|
.context("invalid WebSocket URL")?;
|
||||||
|
|
||||||
let (connection, background) = Connection::new(
|
let (connection, background) = Connection::new(
|
||||||
&opt.web_socket_url,
|
&opt.web_socket_url,
|
||||||
&opt.xmpp_domain,
|
xmpp_domain,
|
||||||
Authentication::Anonymous,
|
Authentication::Anonymous,
|
||||||
#[cfg(feature = "tls-insecure")]
|
#[cfg(feature = "tls-insecure")]
|
||||||
opt.tls_insecure,
|
opt.tls_insecure,
|
||||||
|
@ -151,13 +185,13 @@ async fn main_inner() -> Result<()> {
|
||||||
opt
|
opt
|
||||||
.muc_domain
|
.muc_domain
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| { format!("conference.{}", opt.xmpp_domain) }),
|
.unwrap_or_else(|| { format!("conference.{}", xmpp_domain) }),
|
||||||
);
|
);
|
||||||
|
|
||||||
let focus_jid = opt
|
let focus_jid = opt
|
||||||
.focus_jid
|
.focus_jid
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| format!("focus@auth.{}/focus", opt.xmpp_domain,));
|
.unwrap_or_else(|| format!("focus@auth.{}/focus", xmpp_domain));
|
||||||
|
|
||||||
let Opt {
|
let Opt {
|
||||||
nick,
|
nick,
|
||||||
|
|
Loading…
Reference in New Issue