mirror of
https://github.com/valmojr/armatak.git
synced 2026-06-13 13:23:28 +00:00
(WIP) refacotred video stream generator
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use arma_rs::Context;
|
||||
use lazy_static::lazy_static;
|
||||
use std::io::Write;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::process::Command;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::Mutex;
|
||||
use std::thread;
|
||||
@@ -28,39 +27,6 @@ fn build_rtsp_url(address: &str, port: &str, stream_path: &str, username: &str,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_klv_packet() -> Vec<u8> {
|
||||
fn encode_u16(value: f64, min: f64, max: f64) -> u16 {
|
||||
let scale = (value - min) / (max - min);
|
||||
(scale * u16::MAX as f64).round() as u16
|
||||
}
|
||||
|
||||
fn encode_i64(value: f64, min: f64, max: f64) -> i64 {
|
||||
let scale = (value - min) / (max - min);
|
||||
(scale * i64::MAX as f64).round() as i64
|
||||
}
|
||||
|
||||
let mut pkt = vec![];
|
||||
|
||||
// Heading (0x02)
|
||||
pkt.extend([0x02, 0x02]);
|
||||
pkt.extend(&encode_u16(182.0, 0.0, 360.0).to_be_bytes());
|
||||
|
||||
// Latitude (0x0D)
|
||||
pkt.extend([0x0D, 0x08]);
|
||||
pkt.extend(&encode_i64(-30.123456, -90.0, 90.0).to_be_bytes());
|
||||
|
||||
// Longitude (0x0E)
|
||||
pkt.extend([0x0E, 0x08]);
|
||||
pkt.extend(&encode_i64(-51.123456, -180.0, 180.0).to_be_bytes());
|
||||
|
||||
// Altitude (0x0F)
|
||||
pkt.extend([0x0F, 0x04]);
|
||||
let alt = ((430.0 / 19999.0) * u32::MAX as f64).round() as u32;
|
||||
pkt.extend(&alt.to_be_bytes());
|
||||
|
||||
pkt
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||
fn spawn_ffmpeg(
|
||||
rtsp_url: String,
|
||||
@@ -69,50 +35,26 @@ fn spawn_ffmpeg(
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
let mut cmd = Command::new("ffmpeg");
|
||||
|
||||
cmd.args(&[
|
||||
"-f", "gdigrab",
|
||||
"-i", "desktop",
|
||||
"-f", "klv",
|
||||
"-i", "-",
|
||||
"-map", "0:v",
|
||||
"-map", "1",
|
||||
"-c:v", "libx264",
|
||||
"-metadata:s:1", "handler_name=klv_data",
|
||||
"-f", "rtsp",
|
||||
"-rtsp_transport", "tcp",
|
||||
"-f","x11grab",
|
||||
"-framerate","30",
|
||||
"-video_size","1920x1080",
|
||||
"-i" ,":0",
|
||||
"-f","rtsp",
|
||||
"-rtsp_transport","tcp",
|
||||
&rtsp_url,
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let child_result = cmd
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.stdin(Stdio::piped())
|
||||
.spawn();
|
||||
let child_result = cmd.creation_flags(CREATE_NO_WINDOW).spawn();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let child_result = cmd.stdin(Stdio::piped()).spawn();
|
||||
let child_result = cmd.spawn();
|
||||
|
||||
match child_result {
|
||||
Ok(mut child) => {
|
||||
let _ = status_tx.send(Ok(()));
|
||||
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
let klv = generate_klv_packet();
|
||||
loop {
|
||||
if stop_rx.try_recv().is_ok() {
|
||||
break;
|
||||
}
|
||||
if stdin.write_all(&klv).is_err() {
|
||||
break;
|
||||
}
|
||||
if stdin.flush().is_err() {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
|
||||
let _ = stop_rx.recv();
|
||||
let _ = child.kill();
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -130,6 +72,8 @@ 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();
|
||||
|
||||
@@ -163,6 +107,13 @@ pub fn start_stream(
|
||||
"ffmpeg did not respond"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "windows", target_os = "linux")))]
|
||||
{
|
||||
ctx.callback_null("VIDEO ERROR", "Screen capture is only supported on Windows");
|
||||
"unsupported platform"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop_stream(ctx: Context) -> &'static str {
|
||||
|
||||
Reference in New Issue
Block a user