mirror of
https://github.com/valmojr/armatak.git
synced 2026-06-14 01:23:30 +00:00
Added extension piece of code for handling the mavlink mocker
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use arma_rs::Context;
|
||||
use lazy_static::lazy_static;
|
||||
use log::info;
|
||||
use std::process::Command;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::Mutex;
|
||||
@@ -16,53 +17,34 @@ lazy_static! {
|
||||
#[cfg(target_os = "windows")]
|
||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||
|
||||
fn build_rtsp_url(
|
||||
address: &str,
|
||||
port: &str,
|
||||
stream_path: &str,
|
||||
username: &str,
|
||||
password: &str,
|
||||
) -> String {
|
||||
if username.is_empty() || password.is_empty() {
|
||||
format!("rtsp://{}:{}/{}", address, port, stream_path)
|
||||
} else {
|
||||
format!(
|
||||
"rtsp://{}:{}@{}:{}/{}",
|
||||
username, password, address, port, stream_path
|
||||
)
|
||||
fn stop_existing_stream() {
|
||||
if let Ok(mut lock) = STREAM_CTRL.lock() {
|
||||
if let Some(tx) = lock.take() {
|
||||
let _ = tx.send(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
fn spawn_ffmpeg(rtsp_url: String, stop_rx: Receiver<()>, status_tx: Sender<Result<(), String>>) {
|
||||
fn spawn_ffmpeg_with_args(
|
||||
mut cmd: Command,
|
||||
stop_rx: Receiver<()>,
|
||||
status_tx: Sender<Result<(), String>>,
|
||||
description: String,
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
let mut cmd = Command::new("ffmpeg");
|
||||
cmd.args(&[
|
||||
"-f",
|
||||
"x11grab",
|
||||
"-framerate",
|
||||
"30",
|
||||
"-video_size",
|
||||
"1920x1080",
|
||||
"-i",
|
||||
":0",
|
||||
"-f",
|
||||
"rtsp",
|
||||
"-rtsp_transport",
|
||||
"tcp",
|
||||
&rtsp_url,
|
||||
]);
|
||||
info!("Starting FFmpeg video stream: {}", description);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let child_result = cmd.creation_flags(CREATE_NO_WINDOW).spawn();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let child_result = cmd.spawn();
|
||||
|
||||
match child_result {
|
||||
Ok(mut child) => {
|
||||
let _ = status_tx.send(Ok(()));
|
||||
let _ = stop_rx.recv();
|
||||
info!("Stopping FFmpeg video stream: {}", description);
|
||||
let _ = child.kill();
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -80,47 +62,169 @@ pub fn start_stream(
|
||||
username: String,
|
||||
password: String,
|
||||
) -> &'static str {
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
{
|
||||
let (stop_tx, stop_rx) = mpsc::channel();
|
||||
let (status_tx, status_rx) = mpsc::channel();
|
||||
stop_existing_stream();
|
||||
|
||||
let rtsp_url = build_rtsp_url(&address, &port, &stream_path, &username, &password);
|
||||
let (stop_tx, stop_rx) = mpsc::channel();
|
||||
let (status_tx, status_rx) = mpsc::channel();
|
||||
|
||||
spawn_ffmpeg(rtsp_url, stop_rx, status_tx);
|
||||
let rtsp_url = if username.is_empty() || password.is_empty() {
|
||||
format!("rtsp://{}:{}/{}", address, port, stream_path)
|
||||
} else {
|
||||
format!("rtsp://{}:{}@{}:{}/{}", username, password, address, port, stream_path)
|
||||
};
|
||||
|
||||
match STREAM_CTRL.lock() {
|
||||
Ok(mut lock) => *lock = Some(stop_tx),
|
||||
Err(e) => {
|
||||
let _ = ctx.callback_data(
|
||||
"VIDEO ERROR",
|
||||
"Failed to acquire lock for stream control",
|
||||
e.to_string(),
|
||||
);
|
||||
return "stream control lock error";
|
||||
}
|
||||
}
|
||||
let mut cmd = Command::new("ffmpeg");
|
||||
#[cfg(target_os = "windows")]
|
||||
cmd.args([
|
||||
"-f",
|
||||
"gdigrab",
|
||||
"-framerate",
|
||||
"15",
|
||||
"-i",
|
||||
"desktop",
|
||||
"-an",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-preset",
|
||||
"ultrafast",
|
||||
"-tune",
|
||||
"zerolatency",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-f",
|
||||
"rtsp",
|
||||
"-rtsp_transport",
|
||||
"tcp",
|
||||
&rtsp_url,
|
||||
]);
|
||||
|
||||
match status_rx.recv_timeout(Duration::from_secs(2)) {
|
||||
Ok(Ok(())) => {
|
||||
let _ = ctx.callback_null("VIDEO", "FFmpeg started successfully");
|
||||
"starting video stream"
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
let _ = ctx.callback_data("VIDEO ERROR", "FFmpeg failed to start", e);
|
||||
"ffmpeg failed to start"
|
||||
}
|
||||
Err(_) => {
|
||||
let _ = ctx.callback_null("VIDEO ERROR", "FFmpeg did not respond in time");
|
||||
"ffmpeg did not respond"
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
cmd.args([
|
||||
"-f",
|
||||
"x11grab",
|
||||
"-framerate",
|
||||
"15",
|
||||
"-video_size",
|
||||
"1280x720",
|
||||
"-i",
|
||||
":0.0",
|
||||
"-an",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-preset",
|
||||
"ultrafast",
|
||||
"-tune",
|
||||
"zerolatency",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-f",
|
||||
"rtsp",
|
||||
"-rtsp_transport",
|
||||
"tcp",
|
||||
&rtsp_url,
|
||||
]);
|
||||
|
||||
spawn_ffmpeg_with_args(cmd, stop_rx, status_tx, format!("RTSP {}", rtsp_url));
|
||||
|
||||
if let Ok(mut lock) = STREAM_CTRL.lock() {
|
||||
*lock = Some(stop_tx);
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
|
||||
{
|
||||
ctx.callback_null("VIDEO ERROR", "Screen capture is only supported on Windows");
|
||||
"unsupported platform"
|
||||
match status_rx.recv_timeout(Duration::from_secs(2)) {
|
||||
Ok(Ok(())) => {
|
||||
let _ = ctx.callback_null("VIDEO", "FFmpeg RTSP stream started successfully");
|
||||
"starting video stream"
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
let _ = ctx.callback_data("VIDEO ERROR", "FFmpeg failed to start", e);
|
||||
"ffmpeg failed to start"
|
||||
}
|
||||
Err(_) => {
|
||||
let _ = ctx.callback_null("VIDEO ERROR", "FFmpeg did not respond in time");
|
||||
"ffmpeg did not respond"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_rtp_stream(ctx: Context, address: String, port: String) -> &'static str {
|
||||
stop_existing_stream();
|
||||
|
||||
let (stop_tx, stop_rx) = mpsc::channel();
|
||||
let (status_tx, status_rx) = mpsc::channel();
|
||||
let rtp_url = format!("rtp://{}:{}", address, port);
|
||||
|
||||
let mut cmd = Command::new("ffmpeg");
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
cmd.args([
|
||||
"-f",
|
||||
"gdigrab",
|
||||
"-framerate",
|
||||
"15",
|
||||
"-i",
|
||||
"desktop",
|
||||
"-an",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-preset",
|
||||
"ultrafast",
|
||||
"-tune",
|
||||
"zerolatency",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-g",
|
||||
"30",
|
||||
"-f",
|
||||
"rtp",
|
||||
&rtp_url,
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
cmd.args([
|
||||
"-f",
|
||||
"x11grab",
|
||||
"-framerate",
|
||||
"15",
|
||||
"-video_size",
|
||||
"1280x720",
|
||||
"-i",
|
||||
":0.0",
|
||||
"-an",
|
||||
"-c:v",
|
||||
"libx264",
|
||||
"-preset",
|
||||
"ultrafast",
|
||||
"-tune",
|
||||
"zerolatency",
|
||||
"-pix_fmt",
|
||||
"yuv420p",
|
||||
"-g",
|
||||
"30",
|
||||
"-f",
|
||||
"rtp",
|
||||
&rtp_url,
|
||||
]);
|
||||
|
||||
spawn_ffmpeg_with_args(cmd, stop_rx, status_tx, format!("RTP {}", rtp_url));
|
||||
|
||||
if let Ok(mut lock) = STREAM_CTRL.lock() {
|
||||
*lock = Some(stop_tx);
|
||||
}
|
||||
|
||||
match status_rx.recv_timeout(Duration::from_secs(2)) {
|
||||
Ok(Ok(())) => {
|
||||
info!("Started RTP video stream toward {}", rtp_url);
|
||||
let _ = ctx.callback_null("VIDEO", "FFmpeg RTP stream started successfully");
|
||||
"starting RTP video stream"
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
let _ = ctx.callback_data("VIDEO ERROR", "FFmpeg failed to start RTP stream", e);
|
||||
"ffmpeg failed to start RTP stream"
|
||||
}
|
||||
Err(_) => {
|
||||
let _ = ctx.callback_null("VIDEO ERROR", "FFmpeg RTP stream did not respond in time");
|
||||
"ffmpeg RTP stream did not respond"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user