diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..67da2b47 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +TS_RS_EXPORT_DIR = { value = "frontend/types", relative = true } diff --git a/Cargo.lock b/Cargo.lock index 77453400..f33a110d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1266,6 +1266,7 @@ dependencies = [ "tokio", "tokio-stream", "toml_edit", + "ts-rs", "uuid", "walkdir", "zeromq", @@ -3663,6 +3664,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "tests" version = "0.24.0-rc2" @@ -3900,6 +3910,30 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "ts-rs" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a2f31991cee3dce1ca4f929a8a04fdd11fd8801aac0f2030b0fa8a0a3fef6b9" +dependencies = [ + "chrono", + "lazy_static", + "thiserror", + "ts-rs-macros", +] + +[[package]] +name = "ts-rs-macros" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea0b99e8ec44abd6f94a18f28f7934437809dd062820797c52401298116f70e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", + "termcolor", +] + [[package]] name = "typeid" version = "1.0.2" diff --git a/docs/closed_captions.md b/docs/closed_captions.md index c9cbf5e0..2d6877ac 100644 --- a/docs/closed_captions.md +++ b/docs/closed_captions.md @@ -1,7 +1,7 @@ ## Closed Captions #### Note: -**This is only an _experimental feature_. Please be aware that bugs and unexpected behavior may occur. To utilize this feature, a [special patched](https://github.com/jb-alvarado/compile-ffmpeg-osx-linux) version of FFmpeg is required. Importantly, there is currently no official support for this functionality.** +**This is only an _experimental feature_. Please be aware that bugs and unexpected behavior may occur. To utilize this feature, a version after 7.1 of FFmpeg is required. Importantly, there is currently no official support for this functionality.** ### Usage **ffplayout** can handle closed captions in WebVTT format for HLS streaming. @@ -16,7 +16,7 @@ To encode the closed captions, the **hls** mode needs to be enabled, and specifi -profile:v Main -level 3.1 -c:a aac -ar 44100 -b:a 128k -flags +cgop \ -muxpreload 0 -muxdelay 0 -f hls -hls_time 6 -hls_list_size 600 \ -hls_flags append_list+delete_segments+omit_endlist \ --var_stream_map v:0,a:0,s:0,sgroup:subs,name:English,language:en-US,default:YES \ +-var_stream_map v:0,a:0,s:0,sgroup:subs,sname:English,language:en-US,default:YES \ -master_pl_name master.m3u8 \ -hls_segment_filename \ live/stream-%d.ts live/stream.m3u8 diff --git a/docs/developer.md b/docs/developer.md index 46d83ce0..b255652c 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -69,6 +69,11 @@ cargo deb --no-build --target=aarch64-unknown-linux-gnu --variant=arm64 -p ffpla cargo generate-rpm --target=x86_64-unknown-linux-musl ``` +## Generate types for Frontend +The frontend uses TypeScript, to generate types for the rust structs run: `cargo test`. + +The generated types are then in [types folder](/frontend/types). + ## Setup Frontend Make sure to install the dependencies: diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 4a318545..43fda5da 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -61,6 +61,7 @@ time = { version = "0.3", features = ["formatting", "macros"] } tokio = { version = "1.29", features = ["full"] } tokio-stream = "0.1" toml_edit = {version = "0.22", features = ["serde"]} +ts-rs = { version = "10", features = ["chrono-impl", "no-serde-warnings"] } uuid = "1.8" walkdir = "2" zeromq = { version = "0.4", default-features = false, features = [ diff --git a/engine/src/utils/config.rs b/engine/src/utils/config.rs index 5d627187..0dc57df3 100644 --- a/engine/src/utils/config.rs +++ b/engine/src/utils/config.rs @@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize}; use shlex::split; use sqlx::{Pool, Sqlite}; use tokio::{fs, io::AsyncReadExt}; +use ts_rs::TS; use crate::db::{handles, models}; use crate::utils::{files::norm_abs_path, free_tcp_socket, time_to_sec}; @@ -52,7 +53,8 @@ pub const FFMPEG_UNRECOVERABLE_ERRORS: [&str; 6] = [ "Unrecognized option", ]; -#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, TS)] +#[ts(export, export_to = "playout_config.d.ts")] #[serde(rename_all = "lowercase")] pub enum OutputMode { Desktop, @@ -103,7 +105,8 @@ impl fmt::Display for OutputMode { } } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq, TS)] +#[ts(export, export_to = "playout_config.d.ts")] #[serde(rename_all = "lowercase")] pub enum ProcessMode { Folder, @@ -141,14 +144,16 @@ impl FromStr for ProcessMode { } } -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)] pub struct Template { pub sources: Vec, } -#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)] pub struct Source { + #[ts(type = "string")] pub start: NaiveTime, + #[ts(type = "string")] pub duration: NaiveTime, pub shuffle: bool, pub paths: Vec, @@ -157,10 +162,14 @@ pub struct Source { /// Channel Config /// /// This we init ones, when ffplayout is starting and use them globally in the hole program. -#[derive(Debug, Default, Clone, Deserialize, Serialize)] + +#[derive(Debug, Default, Clone, Deserialize, Serialize, TS)] +#[ts(export, export_to = "playout_config.d.ts")] pub struct PlayoutConfig { + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub channel: Channel, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub advanced: AdvancedConfig, pub general: General, @@ -176,7 +185,7 @@ pub struct PlayoutConfig { pub output: Output, } -#[derive(Debug, Default, Clone, Deserialize, Serialize)] +#[derive(Debug, Default, Clone, Deserialize, Serialize, TS)] pub struct Channel { pub logs: PathBuf, pub public: PathBuf, @@ -197,23 +206,32 @@ impl Channel { } } -#[derive(Debug, Default, Clone, Deserialize, Serialize)] +#[derive(Debug, Default, Clone, Deserialize, Serialize, TS)] +#[ts(export, export_to = "playout_config.d.ts")] pub struct General { + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub id: i32, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub channel_id: i32, pub stop_threshold: f64, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub generate: Option>, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub ffmpeg_filters: Vec, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub ffmpeg_libs: Vec, + #[ts(skip)] #[serde(skip_serializing, skip_deserializing)] pub template: Option