Compare commits
No commits in common. "6ab27127bfd19efe7395f8afe78960658d55d77e" and "27504d97540a53dae57d9526c8b182e1b4328819" have entirely different histories.
6ab27127bf
...
27504d9754
8 changed files with 2436 additions and 902 deletions
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"rust-analyzer.linkedProjects": [
|
||||||
|
"./helloworld/Cargo.toml",
|
||||||
|
]
|
||||||
|
}
|
3137
Cargo.lock
generated
3137
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
20
Cargo.toml
20
Cargo.toml
|
@ -9,18 +9,24 @@ edition = "2021"
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
config = "0.14.0"
|
config = "0.14.0"
|
||||||
ctrlc = "3.4.4"
|
ctrlc = "3.4.4"
|
||||||
|
gst-plugin-webrtc = { version = "0.13.0", features = ["v1_22"] }
|
||||||
|
|
||||||
gstreamer = { version = "0.23.0", features = ["v1_22"] }
|
gst-plugin-webrtchttp = "0.13.0"
|
||||||
gstreamer-app = { version = "0.23.0", features = ["v1_22"] }
|
gst-plugin-rtp = "0.13.0"
|
||||||
|
gst-plugin-rtsp = "0.13.0"
|
||||||
|
gst-plugin-hlssink3 = "0.13.0"
|
||||||
|
gst-plugin-reqwest = "0.13.0"
|
||||||
|
|
||||||
|
gstreamer = { version = "0.23.0", features = ["v1_24"] }
|
||||||
|
gstreamer-webrtc = { version = "0.23.0", features = ["v1_22"] }
|
||||||
|
lazy_static = "1.5.0"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
serde = { version = "1.0.204", features = ["derive"] }
|
serde = { version = "1.0.204", features = ["derive"] }
|
||||||
serde_json = "1.0.122"
|
serde_json = "1.0.122"
|
||||||
snafu = "0.8.4"
|
snafu = "0.8.4"
|
||||||
tokio = "1.39.2"
|
# tokio = "1.39.2"
|
||||||
tokio-tungstenite = "0.23.1"
|
# tokio-tungstenite = "0.23.1"
|
||||||
toml = "0.8.19"
|
toml = "0.8.19"
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = "0.3.18"
|
tracing-subscriber = "0.3.18"
|
||||||
webrtc = "0.11.0"
|
tungstenite = "0.23.0"
|
||||||
|
|
||||||
vcs-common = { git = "https://git.nickiel.net/VCC/vcs-common.git", branch = "main" }
|
|
||||||
|
|
9
rtsp-simple-server.yml
Normal file
9
rtsp-simple-server.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
webrtcAdditionalHosts: [localhost, 0.0.0.0, 127.0.0.1, 10.0.0.114]
|
||||||
|
|
||||||
|
logLevel: debug
|
||||||
|
webrtcLocalTCPAddress: :8188
|
||||||
|
api: yes
|
||||||
|
|
||||||
|
paths:
|
||||||
|
mystream:
|
||||||
|
source: publisher
|
13
rtsp-simple-server.yml.old
Normal file
13
rtsp-simple-server.yml.old
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
api: no
|
||||||
|
apiAddress: :9997
|
||||||
|
apiEncryption: no
|
||||||
|
|
||||||
|
paths:
|
||||||
|
mystream:
|
||||||
|
source: publisher
|
||||||
|
|
||||||
|
webrtc: yes
|
||||||
|
webrtcAddress: :8889
|
||||||
|
webrtcLocalUDPAddress: :8189
|
||||||
|
webrtcEncryption: no
|
23
src/main.rs
23
src/main.rs
|
@ -2,8 +2,12 @@ use std::sync::{atomic::AtomicBool, Arc};
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use gstreamer::{prelude::*, Element, ElementFactory, Pipeline, State};
|
use gstreamer::{prelude::*, Element, ElementFactory, Pipeline, State};
|
||||||
|
use gstrswebrtc::{signaller::Signallable, webrtcsink};
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
mod signaller;
|
||||||
|
|
||||||
|
use signaller::{SignallerEvent, SENDER_CHANNEL};
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
// TRACING SETUP
|
// TRACING SETUP
|
||||||
|
@ -14,6 +18,10 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
let config = config::load_config();
|
let config = config::load_config();
|
||||||
|
|
||||||
|
let (sender, receiver) = std::sync::mpsc::channel::<SignallerEvent>();
|
||||||
|
|
||||||
|
*SENDER_CHANNEL.lock().unwrap() = Some(sender.clone());
|
||||||
|
|
||||||
// EXIT HANDLER
|
// EXIT HANDLER
|
||||||
let to_quit = Arc::new(AtomicBool::new(false));
|
let to_quit = Arc::new(AtomicBool::new(false));
|
||||||
let to_quit_2 = to_quit.clone();
|
let to_quit_2 = to_quit.clone();
|
||||||
|
@ -24,7 +32,6 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
// GSTREAMER SETUP
|
// GSTREAMER SETUP
|
||||||
gstreamer::init()?;
|
gstreamer::init()?;
|
||||||
<<<<<<< HEAD
|
|
||||||
gstrswebrtc::plugin_register_static()?;
|
gstrswebrtc::plugin_register_static()?;
|
||||||
|
|
||||||
gstrsrtp::plugin_register_static()?;
|
gstrsrtp::plugin_register_static()?;
|
||||||
|
@ -75,20 +82,6 @@ fn main() -> Result<(), Error> {
|
||||||
gstreamer::ClockTime::NONE,
|
gstreamer::ClockTime::NONE,
|
||||||
&[gstreamer::MessageType::Eos]
|
&[gstreamer::MessageType::Eos]
|
||||||
);
|
);
|
||||||
=======
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if to_quit.load(std::sync::atomic::Ordering::SeqCst) {
|
|
||||||
println!("Recieved Ctrl+C, stopping");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
|
||||||
}
|
|
||||||
>>>>>>> 29a8ccf (added vcs-common)
|
|
||||||
|
|
||||||
println!("Success!");
|
println!("Success!");
|
||||||
|
|
||||||
|
|
110
src/signaller/imp.rs
Normal file
110
src/signaller/imp.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use gstreamer::glib;
|
||||||
|
use gstreamer::subclass::prelude::*;
|
||||||
|
use gstreamer_webrtc::WebRTCSessionDescription;
|
||||||
|
use gstrswebrtc::signaller::{Signallable, SignallableImpl};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref SENDER_CHANNEL: Mutex<Option<Sender<SignallerEvent>>> = Mutex::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum SignallerEvent {
|
||||||
|
Start,
|
||||||
|
Stop,
|
||||||
|
SendSDP(SdpMessage),
|
||||||
|
AddICE(ICE),
|
||||||
|
End(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ICE {
|
||||||
|
pub session_id: String,
|
||||||
|
pub candidate: String,
|
||||||
|
pub sdp_m_line_index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum SdpMessage {
|
||||||
|
Offer(String),
|
||||||
|
Answer(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Signaller {}
|
||||||
|
|
||||||
|
impl Signaller {}
|
||||||
|
|
||||||
|
impl SignallableImpl for Signaller {
|
||||||
|
fn start(&self) {
|
||||||
|
SENDER_CHANNEL.lock().unwrap().as_ref().map(|msg_bus| {
|
||||||
|
if let Err(e) = msg_bus.send(SignallerEvent::Start) {
|
||||||
|
error!("Could not send message from the signaller to the message bus! {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stop(&self) {
|
||||||
|
SENDER_CHANNEL.lock().unwrap().as_ref().map(|msg_bus| {
|
||||||
|
if let Err(e) = msg_bus.send(SignallerEvent::Stop) {
|
||||||
|
error!("Could not send message from the signaller to the message bus! {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_sdp(&self, _session_id: &str, sdp: &WebRTCSessionDescription) {
|
||||||
|
let message = {
|
||||||
|
if sdp.type_() == gstreamer_webrtc::WebRTCSDPType::Offer {
|
||||||
|
SdpMessage::Offer(sdp.sdp().as_text().unwrap())
|
||||||
|
} else {
|
||||||
|
SdpMessage::Answer(sdp.sdp().as_text().unwrap())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SENDER_CHANNEL.lock().unwrap().as_ref().map(|msg_bus| {
|
||||||
|
if let Err(e) = msg_bus.send(SignallerEvent::SendSDP(message)) {
|
||||||
|
error!("Could not send message from the signaller to the message bus! {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_ice(
|
||||||
|
&self,
|
||||||
|
session_id: &str,
|
||||||
|
candidate: &str,
|
||||||
|
sdp_m_line_index: u32,
|
||||||
|
_sdp_mid: Option<String>,
|
||||||
|
) {
|
||||||
|
let ice_msg = ICE {
|
||||||
|
session_id: session_id.to_string(),
|
||||||
|
candidate: candidate.to_string(),
|
||||||
|
sdp_m_line_index,
|
||||||
|
};
|
||||||
|
|
||||||
|
SENDER_CHANNEL.lock().unwrap().as_ref().map(|msg_bus| {
|
||||||
|
if let Err(e) = msg_bus.send(SignallerEvent::AddICE(ice_msg)) {
|
||||||
|
error!("Could not send message from the signaller to the message bus! {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_session(&self, sess_id: &str) {
|
||||||
|
let session_id = sess_id.to_string();
|
||||||
|
SENDER_CHANNEL.lock().unwrap().as_ref().map(|msg_bus| {
|
||||||
|
if let Err(e) = msg_bus.send(SignallerEvent::End(session_id)) {
|
||||||
|
error!("Could not send message from the signaller to the message bus! {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[glib::object_subclass]
|
||||||
|
impl ObjectSubclass for Signaller {
|
||||||
|
const NAME: &'static str = "MyCustomWebRTCSinkSignaller";
|
||||||
|
type Type = super::MyCustomSignaller;
|
||||||
|
type ParentType = glib::Object;
|
||||||
|
type Interfaces = (Signallable,);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for Signaller {}
|
21
src/signaller/mod.rs
Normal file
21
src/signaller/mod.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use gstreamer::glib;
|
||||||
|
use gstrswebrtc::signaller::Signallable;
|
||||||
|
|
||||||
|
mod imp;
|
||||||
|
pub use imp::{SdpMessage, SignallerEvent, ICE, SENDER_CHANNEL};
|
||||||
|
|
||||||
|
glib::wrapper! {
|
||||||
|
pub struct MyCustomSignaller(ObjectSubclass<imp::Signaller>) @implements Signallable;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MyCustomSignaller {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
glib::Object::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MyCustomSignaller {
|
||||||
|
fn default() -> Self {
|
||||||
|
MyCustomSignaller::new()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue