Added extension calls for starting and stopping a RTSP Video Stream for being used by OTS MEDIAMTX

This commit is contained in:
Valmo Trindade
2025-04-06 05:38:41 -03:00
parent 6eca9e92b6
commit 871d6ec9d3
2 changed files with 91 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ mod websocket;
mod util;
mod cot_router;
mod cot_generator;
mod video_stream;
#[arma]
pub fn init() -> Extension {
@@ -49,5 +50,11 @@ pub fn init() -> Extension {
.command("send_digital_pointer_cot", cot_router::send_digital_pointer_cot)
.command("stop", cot_router::stop)
)
.group(
"video_stream",
Group::new()
.command("start", video_stream::start_stream)
.command("stop", video_stream::stop_stream)
)
.finish()
}

84
src/video_stream.rs Normal file
View File

@@ -0,0 +1,84 @@
use arma_rs::Context;
use lazy_static::lazy_static;
use std::process::Command;
use std::sync::mpsc::{self, Receiver, Sender};
use std::sync::Mutex;
use std::thread;
lazy_static! {
static ref STREAM_CTRL: Mutex<Option<Sender<()>>> = Mutex::new(None);
}
pub fn start_stream(
ctx: Context,
address: String,
port: String,
stream_path: String,
username: String,
password: String,
) -> &'static str {
let (tx, rx): (Sender<()>, Receiver<()>) = mpsc::channel();
let rtsp_url = format!(
"rtsp://{}:{}@{}:{}/{}",
username, password, address, port, stream_path
);
let rtsp_url_clone = rtsp_url.clone();
thread::spawn(move || {
let mut child = match Command::new("ffmpeg")
.args(&[
"-f",
"gdigrab",
"-i",
"desktop",
"-f",
"rtsp",
"-rtsp_transport",
"tcp",
&rtsp_url_clone,
])
.spawn()
{
Ok(child) => child,
Err(e) => {
return ctx.callback_data("armatak_video_error", "Failed to Start FFmpeg", e.to_string())
}
};
if rx.recv().is_err() {
return ctx.callback_null("armatak_video_error", "Error receiving stop signal");
}
Ok(if let Err(e) = child.kill() {
return ctx.callback_data("armatak_video_error", "Failed to Stop FFmpeg", e.to_string())
})
});
match STREAM_CTRL.lock() {
Ok(mut lock) => *lock = Some(tx),
Err(e) => {
eprintln!("Failed to acquire lock: {}", e);
}
}
"starting video stream"
}
pub fn stop_stream(ctx: Context) -> &'static str {
match STREAM_CTRL.lock() {
Ok(mut lock) => {
if let Some(tx) = lock.take() {
if let Err(e) = tx.send(()) {
let _ = ctx.callback_data("armatak_video_error", "Failed to send stop signal", e.to_string());
}
} else {
let _ = ctx.callback_null("armatak_video_error", "Tried to stop an unexistant stream");
}
}
Err(e) => {
let _ = ctx.callback_data("armatak_video_error", "Failed to acquire lock", e.to_string());
}
}
"starting video stream"
}