From 07b1bd30aea640a5db3e7c868bbcfd23b4481b6b Mon Sep 17 00:00:00 2001 From: jb-alvarado Date: Tue, 21 Jun 2022 23:10:38 +0200 Subject: [PATCH] refractor code --- Cargo.lock | 91 +++++++++++---- Cargo.toml | 108 +----------------- build_all.sh | 100 ++++++++++++++++ cross_compile_all.sh | 56 --------- ffplayout-api/Cargo.toml | 76 ++++++++++++ ffplayout-api/README.md | 2 + {debian => ffplayout-api/debian}/.gitkeep | 0 .../ffpapi.rs => ffplayout-api/src/main.rs | 27 ++--- .../src/utils}/args_parse.rs | 4 +- {src/api => ffplayout-api/src/utils}/auth.rs | 2 +- .../src/utils}/control.rs | 2 +- .../api => ffplayout-api/src/utils}/errors.rs | 0 {src/api => ffplayout-api/src/utils}/files.rs | 4 +- .../src/utils}/handles.rs | 6 +- .../src/utils/mod.rs | 14 ++- .../api => ffplayout-api/src/utils}/models.rs | 0 .../src/utils}/playlist.rs | 4 +- .../api => ffplayout-api/src/utils}/routes.rs | 26 ++--- {assets => ffplayout-api/unit}/ffpapi.service | 0 ffplayout-engine/Cargo.toml | 79 +++++++++++++ ffplayout-engine/README.md | 2 + ffplayout-engine/src/input/folder.rs | 76 ++++++++++++ {src => ffplayout-engine/src}/input/ingest.rs | 6 +- {src => ffplayout-engine/src}/input/mod.rs | 6 +- .../src}/input/playlist.rs | 2 +- {src => ffplayout-engine/src}/main.rs | 22 +++- .../src}/output/desktop.rs | 6 +- {src => ffplayout-engine/src}/output/hls.rs | 6 +- {src => ffplayout-engine/src}/output/mod.rs | 4 +- .../src}/output/stream.rs | 6 +- {src => ffplayout-engine/src}/rpc/mod.rs | 2 +- {src => ffplayout-engine/src}/rpc/zmq_cmd.rs | 0 {src => ffplayout-engine/src}/tests/mod.rs | 4 +- .../src}/utils/arg_parse.rs | 0 ffplayout-engine/src/utils/mod.rs | 64 +++++++++++ .../unit/ffplayout.service | 0 lib/Cargo.toml | 34 ++++++ {src => lib/src}/filter/a_loudnorm.rs | 0 {src => lib/src}/filter/ingest_filter.rs | 0 {src => lib/src}/filter/mod.rs | 0 {src => lib/src}/filter/v_drawtext.rs | 0 {src => lib/src}/filter/v_overlay.rs | 0 {src => lib/src}/lib.rs | 7 +- {src => lib/src}/macros/mod.rs | 0 {src/tests/utils => lib/src/tests}/mod.rs | 0 {src => lib/src}/utils/config.rs | 61 +--------- {src => lib/src}/utils/controller.rs | 0 {src/input => lib/src/utils}/folder.rs | 67 +---------- {src => lib/src}/utils/generator.rs | 2 +- {src => lib/src}/utils/json_serializer.rs | 0 {src => lib/src}/utils/json_validate.rs | 0 {src => lib/src}/utils/logging.rs | 0 {src => lib/src}/utils/mod.rs | 3 +- src/api/mod.rs | 10 -- 54 files changed, 603 insertions(+), 388 deletions(-) create mode 100755 build_all.sh delete mode 100755 cross_compile_all.sh create mode 100644 ffplayout-api/Cargo.toml create mode 100644 ffplayout-api/README.md rename {debian => ffplayout-api/debian}/.gitkeep (100%) rename src/bin/ffpapi.rs => ffplayout-api/src/main.rs (84%) rename {src/api => ffplayout-api/src/utils}/args_parse.rs (87%) rename {src/api => ffplayout-api/src/utils}/auth.rs (97%) rename {src/api => ffplayout-api/src/utils}/control.rs (97%) rename {src/api => ffplayout-api/src/utils}/errors.rs (100%) rename {src/api => ffplayout-api/src/utils}/files.rs (94%) rename {src/api => ffplayout-api/src/utils}/handles.rs (99%) rename src/api/utils.rs => ffplayout-api/src/utils/mod.rs (93%) rename {src/api => ffplayout-api/src/utils}/models.rs (100%) rename {src/api => ffplayout-api/src/utils}/playlist.rs (95%) rename {src/api => ffplayout-api/src/utils}/routes.rs (96%) rename {assets => ffplayout-api/unit}/ffpapi.service (100%) create mode 100644 ffplayout-engine/Cargo.toml create mode 100644 ffplayout-engine/README.md create mode 100644 ffplayout-engine/src/input/folder.rs rename {src => ffplayout-engine/src}/input/ingest.rs (96%) rename {src => ffplayout-engine/src}/input/mod.rs (92%) rename {src => ffplayout-engine/src}/input/playlist.rs (99%) rename {src => ffplayout-engine/src}/main.rs (90%) rename {src => ffplayout-engine/src}/output/desktop.rs (92%) rename {src => ffplayout-engine/src}/output/hls.rs (98%) rename {src => ffplayout-engine/src}/output/mod.rs (99%) rename {src => ffplayout-engine/src}/output/stream.rs (92%) rename {src => ffplayout-engine/src}/rpc/mod.rs (99%) rename {src => ffplayout-engine/src}/rpc/zmq_cmd.rs (100%) rename {src => ffplayout-engine/src}/tests/mod.rs (98%) rename {src => ffplayout-engine/src}/utils/arg_parse.rs (100%) create mode 100644 ffplayout-engine/src/utils/mod.rs rename assets/ffplayout-engine.service => ffplayout-engine/unit/ffplayout.service (100%) create mode 100644 lib/Cargo.toml rename {src => lib/src}/filter/a_loudnorm.rs (100%) rename {src => lib/src}/filter/ingest_filter.rs (100%) rename {src => lib/src}/filter/mod.rs (100%) rename {src => lib/src}/filter/v_drawtext.rs (100%) rename {src => lib/src}/filter/v_overlay.rs (100%) rename {src => lib/src}/lib.rs (66%) rename {src => lib/src}/macros/mod.rs (100%) rename {src/tests/utils => lib/src/tests}/mod.rs (100%) rename {src => lib/src}/utils/config.rs (80%) rename {src => lib/src}/utils/controller.rs (100%) rename {src/input => lib/src/utils}/folder.rs (63%) rename {src => lib/src}/utils/generator.rs (99%) rename {src => lib/src}/utils/json_serializer.rs (100%) rename {src => lib/src}/utils/json_validate.rs (100%) rename {src => lib/src}/utils/logging.rs (100%) rename {src => lib/src}/utils/mod.rs (99%) delete mode 100644 src/api/mod.rs diff --git a/Cargo.lock b/Cargo.lock index cd9a6dce..ca8d56a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,9 +315,9 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8b508d585e01084059b60f06ade4cb7415cd2e4084b71dd1cb44e7d3fb9880" +checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" dependencies = [ "async-channel", "async-executor", @@ -325,6 +325,7 @@ dependencies = [ "async-lock", "blocking", "futures-lite", + "num_cpus", "once_cell", ] @@ -588,6 +589,7 @@ dependencies = [ "libc", "num-integer", "num-traits", + "time 0.1.44", "winapi 0.3.9", ] @@ -605,9 +607,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.5" +version = "3.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7" +checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a" dependencies = [ "atty", "bitflags", @@ -622,9 +624,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.5" +version = "3.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9" +checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a" dependencies = [ "heck", "proc-macro-error", @@ -635,9 +637,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" +checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" dependencies = [ "os_str_bytes", ] @@ -977,26 +979,21 @@ dependencies = [ ] [[package]] -name = "ffplayout-engine" -version = "0.9.9" +name = "ffplayout-api" +version = "0.3.0" dependencies = [ "actix-web", "actix-web-grants", "actix-web-httpauth", "argon2", - "chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)", + "chrono 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "clap", - "crossbeam-channel 0.5.5", "derive_more", "faccess", + "ffplayout-lib", "ffprobe", - "file-rotate", - "futures", - "jsonrpc-http-server", "jsonwebtoken", - "lettre", "log", - "notify", "once_cell", "openssl", "rand 0.8.5", @@ -1007,14 +1004,68 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "shlex", "simplelog", "sqlx", +] + +[[package]] +name = "ffplayout-engine" +version = "0.9.9" +dependencies = [ + "chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)", + "clap", + "crossbeam-channel 0.5.5", + "faccess", + "ffplayout-lib", + "ffprobe", + "file-rotate", + "futures", + "jsonrpc-http-server", + "lettre", + "log", + "notify", + "openssl", + "rand 0.8.5", + "regex", + "reqwest", + "serde", + "serde_json", + "serde_yaml", + "shlex", + "simplelog", "time 0.3.10", "walkdir", "zeromq", ] +[[package]] +name = "ffplayout-lib" +version = "0.9.9" +dependencies = [ + "chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)", + "crossbeam-channel 0.5.5", + "faccess", + "ffprobe", + "file-rotate", + "futures", + "jsonrpc-http-server", + "lettre", + "log", + "notify", + "once_cell", + "openssl", + "rand 0.8.5", + "regex", + "reqwest", + "serde", + "serde_json", + "serde_yaml", + "shlex", + "simplelog", + "time 0.3.10", + "walkdir", +] + [[package]] name = "ffprobe" version = "0.3.2" @@ -1474,9 +1525,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg", "hashbrown 0.12.1", diff --git a/Cargo.toml b/Cargo.toml index 68c2645c..77e2c4b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,108 +1,12 @@ -[package] -name = "ffplayout-engine" -description = "24/7 playout based on rust and ffmpeg" -license = "GPL-3.0" -authors = ["Jonathan Baecker jonbae77@gmail.com"] -readme = "README.md" -version = "0.9.9" -edition = "2021" -default-run = "ffplayout" +[workspace] -[dependencies] -actix-web = "4" -actix-web-grants = "3" -actix-web-httpauth = "0.6" -argon2 = "0.4" -chrono = { git = "https://github.com/sbrocket/chrono", branch = "parse-error-kind-public" } -clap = { version = "3.2", features = ["derive"] } -crossbeam-channel = "0.5" -derive_more = "0.99" -faccess = "0.2" -ffprobe = "0.3" -file-rotate = { git = "https://github.com/Ploppz/file-rotate.git", branch = "timestamp-parse-fix" } -futures = "0.3" -jsonrpc-http-server = "18.0" -jsonwebtoken = "8" -lettre = "0.10.0-rc.7" -log = "0.4" -notify = "4.0" -once_cell = "1.10" -rand = "0.8" -rand_core = { version = "0.6", features = ["std"] } -relative-path = "1.6" -regex = "1" -reqwest = { version = "0.11", features = ["blocking", "json"] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -serde_yaml = "0.8" -shlex = "1.1" -simplelog = { version = "^0.12", features = ["paris"] } -sqlx = { version = "0.5", features = [ - "chrono", - "runtime-actix-native-tls", - "sqlite" -] } -time = { version = "0.3", features = ["formatting", "macros"] } -walkdir = "2" -zeromq = { git = "https://github.com/zeromq/zmq.rs.git", default-features = false, features = [ - "async-std-runtime", - "tcp-transport" -] } - -[target.x86_64-unknown-linux-musl.dependencies] -openssl = { version = "0.10", features = ["vendored"] } - -[[bin]] -name = "ffplayout" -path = "src/main.rs" - -[[bin]] -name = "ffpapi" -path = "src/bin/ffpapi.rs" +members = [ + "ffplayout-api", + "ffplayout-engine", + "lib", +] [profile.release] opt-level = 3 strip = true lto = true - -# DEBIAN DEB PACKAGE -[package.metadata.deb] -name = "ffplayout-engine" -priority = "optional" -section = "net" -license-file = ["LICENSE", "0"] -depends = "" -suggests = "ffmpeg" -copyright = "Copyright (c) 2022, Jonathan Baecker. All rights reserved." -conf-files = ["/etc/ffplayout/ffplayout.yml"] -assets = [ - [ - "target/x86_64-unknown-linux-musl/release/ffplayout", - "/usr/bin/ffplayout", - "755" - ], - [ - "target/x86_64-unknown-linux-musl/release/ffpapi", - "/usr/bin/ffpapi", - "755" - ], - ["assets/ffplayout.yml", "/etc/ffplayout/ffplayout.yml", "644"], - ["assets/logo.png", "/usr/share/ffplayout/logo.png", "644"], - ["README.md", "/usr/share/doc/ffplayout-engine/README", "644"], -] -maintainer-scripts = "debian/" -systemd-units = { enable = false, unit-scripts = "assets" } - -# REHL RPM PACKAGE -[package.metadata.generate-rpm] -name = "ffplayout-engine" -license = "GPL-3.0" -assets = [ - { source = "target/x86_64-unknown-linux-musl/release/ffplayout", dest = "/usr/bin/ffplayout", mode = "755" }, - { source = "target/x86_64-unknown-linux-musl/release/ffpapi", dest = "/usr/bin/ffpapi", mode = "755" }, - { source = "assets/ffplayout.yml", dest = "/etc/ffplayout/ffplayout.yml", mode = "644", config = true }, - { source = "assets/ffplayout-engine.service", dest = "/lib/systemd/system/ffplayout-engine.service", mode = "644" }, - { source = "README.md", dest = "/usr/share/doc/ffplayout-engine/README", mode = "644", doc = true }, - { source = "LICENSE", dest = "/usr/share/doc/ffplayout-engine/LICENSE", mode = "644" }, - { source = "assets/logo.png", dest = "/usr/share/ffplayout/logo.png", mode = "644" }, -] diff --git a/build_all.sh b/build_all.sh new file mode 100755 index 00000000..9052828b --- /dev/null +++ b/build_all.sh @@ -0,0 +1,100 @@ +#!/usr/bin/bash + + +targets=("x86_64-unknown-linux-musl" "x86_64-pc-windows-gnu" "x86_64-apple-darwin" "aarch64-apple-darwin") + +IFS="= " +while read -r name value; do + if [[ $name == "version" ]]; then + version=${value//\"/} + fi +done < ffplayout-engine/Cargo.toml + +echo "Compile ffplayout-engine version is: \"$version\"" +echo "" + +for target in "${targets[@]}"; do + echo "compile static for $target" + echo "" + + cargo build --release --target=$target --bin ffplayout + + if [[ $target == "x86_64-pc-windows-gnu" ]]; then + if [[ -f "ffplayout-engine-v${version}_${target}.zip" ]]; then + rm -f "ffplayout-engine-v${version}_${target}.zip" + fi + + cp ./target/${target}/release/ffplayout.exe . + zip -r "ffplayout-engine-v${version}_${target}.zip" assets docs LICENSE README.md ffplayout.exe -x *.db + rm -f ffplayout.exe + elif [[ $target == "x86_64-apple-darwin" ]] || [[ $target == "aarch64-apple-darwin" ]]; then + if [[ -f "ffplayout-engine-v${version}_${target}.tar.gz" ]]; then + rm -f "ffplayout-engine-v${version}_${target}.tar.gz" + fi + + cp ./target/${target}/release/ffplayout . + tar -czvf "ffplayout-engine-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffplayout + rm -f ffplayout + else + if [[ -f "ffplayout-engine-v${version}_${target}.tar.gz" ]]; then + rm -f "ffplayout-engine-v${version}_${target}.tar.gz" + fi + + cp ./target/${target}/release/ffplayout . + tar -czvf "ffplayout-engine-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffplayout + rm -f ffplayout + fi + + echo "" +done + +cargo deb --target=x86_64-unknown-linux-musl -p ffplayout-engine +mv ./target/x86_64-unknown-linux-musl/debian/ffplayout-engine_${version}_amd64.deb . + +cargo generate-rpm --target=x86_64-unknown-linux-musl -p ffplayout-engine +mv ./target/x86_64-unknown-linux-musl/generate-rpm/ffplayout-engine-${version}-1.x86_64.rpm . + +IFS="= " +while read -r name value; do + if [[ $name == "version" ]]; then + version=${value//\"/} + fi +done < ffplayout-api/Cargo.toml + +echo "Compile ffplayout-api version is: \"$version\"" +echo "" + +for target in "${targets[@]}"; do + echo "compile static for $target" + echo "" + + if [[ $target == "x86_64-pc-windows-gnu" ]]; then + if [[ -f "ffplayout-api-v${version}_${target}.zip" ]]; then + rm -f "ffplayout-api-v${version}_${target}.zip" + fi + + cargo build --release --target=$target --bin ffpapi + + cp ./target/${target}/release/ffpapi.exe . + zip -r "ffplayout-api-v${version}_${target}.zip" assets docs LICENSE README.md ffpapi.exe -x *.db + rm -f ffpapi.exe + elif [[ $target == "x86_64-unknown-linux-musl" ]]; then + if [[ -f "ffplayout-api-v${version}_${target}.tar.gz" ]]; then + rm -f "ffplayout-api-v${version}_${target}.tar.gz" + fi + + cargo build --release --target=$target --bin ffpapi + + cp ./target/${target}/release/ffpapi . + tar -czvf "ffplayout-api-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffpapi + rm -f ffpapi + fi + + echo "" +done + +cargo deb --target=x86_64-unknown-linux-musl -p ffplayout-api +mv ./target/x86_64-unknown-linux-musl/debian/ffplayout-api_${version}_amd64.deb . + +cargo generate-rpm --target=x86_64-unknown-linux-musl -p ffplayout-api +mv ./target/x86_64-unknown-linux-musl/generate-rpm/ffplayout-api-${version}-1.x86_64.rpm . diff --git a/cross_compile_all.sh b/cross_compile_all.sh deleted file mode 100755 index 957d4852..00000000 --- a/cross_compile_all.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/bash - - -targets=("x86_64-unknown-linux-musl" "x86_64-pc-windows-gnu" "x86_64-apple-darwin" "aarch64-apple-darwin") - -IFS="= " -while read -r name value; do - if [[ $name == "version" ]]; then - version=${value//\"/} - fi -done < Cargo.toml - -echo "Compile ffplayout-engine version is: \"$version\"" -echo "" - -for target in "${targets[@]}"; do - echo "compile static for $target" - echo "" - - cargo build --release --target=$target - - if [[ $target == "x86_64-pc-windows-gnu" ]]; then - if [[ -f "ffplayout-engine-v${version}_${target}.zip" ]]; then - rm -f "ffplayout-engine-v${version}_${target}.zip" - fi - - cp ./target/${target}/release/ffplayout.exe . - cp ./target/${target}/release/ffpapi.exe . - zip -r "ffplayout-engine-v${version}_${target}.zip" assets docs LICENSE README.md ffplayout.exe ffpapi.exe -x *.db - rm -f ffplayout.exe ffpapi.exe - else - if [[ -f "ffplayout-engine-v${version}_${target}.tar.gz" ]]; then - rm -f "ffplayout-engine-v${version}_${target}.tar.gz" - fi - - cp ./target/${target}/release/ffplayout . - cp ./target/${target}/release/ffpapi . - tar -czvf "ffplayout-engine-v${version}_${target}.tar.gz" --exclude='*.db' assets docs LICENSE README.md ffplayout ffpapi - rm -f ffplayout ffpapi - fi - - echo "" -done - -echo "Create debian package" -echo "" - -cargo deb --target=x86_64-unknown-linux-musl -mv ./target/x86_64-unknown-linux-musl/debian/ffplayout-engine_${version}_amd64.deb . - -echo "" -echo "Create rhel package" -echo "" - -cargo generate-rpm --target=x86_64-unknown-linux-musl -mv ./target/x86_64-unknown-linux-musl/generate-rpm/ffplayout-engine-${version}-1.x86_64.rpm . diff --git a/ffplayout-api/Cargo.toml b/ffplayout-api/Cargo.toml new file mode 100644 index 00000000..c4183d13 --- /dev/null +++ b/ffplayout-api/Cargo.toml @@ -0,0 +1,76 @@ +[package] +name = "ffplayout-api" +description = "Rest API for ffplayout" +license = "GPL-3.0" +authors = ["Jonathan Baecker jonbae77@gmail.com"] +readme = "README.md" +version = "0.3.0" +edition = "2021" + +[dependencies] +ffplayout-lib = { path = "../lib" } +actix-web = "4" +actix-web-grants = "3" +actix-web-httpauth = "0.6" +argon2 = "0.4" +chrono = "0.4" +clap = { version = "3.2", features = ["derive"] } +derive_more = "0.99" +faccess = "0.2" +ffprobe = "0.3" +jsonwebtoken = "8" +log = "0.4" +once_cell = "1.10" +rand = "0.8" +rand_core = { version = "0.6", features = ["std"] } +relative-path = "1.6" +regex = "1" +reqwest = { version = "0.11", features = ["blocking", "json"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.8" +simplelog = { version = "^0.12", features = ["paris"] } +sqlx = { version = "0.5", features = [ + "chrono", + "runtime-actix-native-tls", + "sqlite" +] } + +[target.x86_64-unknown-linux-musl.dependencies] +openssl = { version = "0.10", features = ["vendored"] } + +[[bin]] +name = "ffpapi" +path = "src/main.rs" + +# DEBIAN DEB PACKAGE +[package.metadata.deb] +name = "ffplayout-api" +priority = "optional" +section = "net" +license-file = ["../LICENSE", "0"] +depends = "" +suggests = "ffmpeg" +copyright = "Copyright (c) 2022, Jonathan Baecker. All rights reserved." +conf-files = ["/etc/ffplayout/ffplayout.yml"] +assets = [ + [ + "../target/x86_64-unknown-linux-musl/release/ffpapi", + "/usr/bin/ffpapi", + "755" + ], + ["README.md", "/usr/share/doc/ffplayout/README", "644"], +] +maintainer-scripts = "debian/" +systemd-units = { enable = false, unit-scripts = "unit" } + +# REHL RPM PACKAGE +[package.metadata.generate-rpm] +name = "ffplayout-api" +license = "GPL-3.0" +assets = [ + { source = "../target/x86_64-unknown-linux-musl/release/ffpapi", dest = "/usr/bin/ffpapi", mode = "755" }, + { source = "unit/ffpapi.service", dest = "/lib/systemd/system/ffpapi.service", mode = "644" }, + { source = "README.md", dest = "/usr/share/doc/ffplayout/README", mode = "644", doc = true }, + { source = "../LICENSE", dest = "/usr/share/doc/ffplayout/LICENSE", mode = "644" }, +] diff --git a/ffplayout-api/README.md b/ffplayout-api/README.md new file mode 100644 index 00000000..c247225c --- /dev/null +++ b/ffplayout-api/README.md @@ -0,0 +1,2 @@ +**ffplayout-api** +================ diff --git a/debian/.gitkeep b/ffplayout-api/debian/.gitkeep similarity index 100% rename from debian/.gitkeep rename to ffplayout-api/debian/.gitkeep diff --git a/src/bin/ffpapi.rs b/ffplayout-api/src/main.rs similarity index 84% rename from src/bin/ffpapi.rs rename to ffplayout-api/src/main.rs index fd1c0db4..fc1ec396 100644 --- a/src/bin/ffpapi.rs +++ b/ffplayout-api/src/main.rs @@ -8,22 +8,23 @@ use actix_web_httpauth::middleware::HttpAuthentication; use clap::Parser; use simplelog::*; -use ffplayout_engine::{ - api::{ - args_parse::Args, - auth, - models::LoginUser, - routes::{ - add_preset, add_user, del_playlist, file_browser, gen_playlist, get_playlist, - get_playout_config, get_presets, get_settings, jump_to_last, jump_to_next, login, - media_current, media_last, media_next, patch_settings, reset_playout, save_playlist, - send_text_message, update_playout_config, update_preset, update_user, - }, - utils::{db_path, init_config, run_args, Role}, +pub mod utils; + +use utils::{ + args_parse::Args, + auth, db_path, init_config, + models::LoginUser, + routes::{ + add_preset, add_user, del_playlist, file_browser, gen_playlist, get_playlist, + get_playout_config, get_presets, get_settings, jump_to_last, jump_to_next, login, + media_current, media_last, media_next, patch_settings, reset_playout, save_playlist, + send_text_message, update_playout_config, update_preset, update_user, }, - utils::{init_logging, PlayoutConfig}, + run_args, Role, }; +use ffplayout_lib::utils::{init_logging, PlayoutConfig}; + async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result { // We just get permissions from JWT let claims = auth::decode_jwt(credentials.token()).await?; diff --git a/src/api/args_parse.rs b/ffplayout-api/src/utils/args_parse.rs similarity index 87% rename from src/api/args_parse.rs rename to ffplayout-api/src/utils/args_parse.rs index 74b7e234..84d8efa5 100644 --- a/src/api/args_parse.rs +++ b/ffplayout-api/src/utils/args_parse.rs @@ -2,9 +2,7 @@ use clap::Parser; #[derive(Parser, Debug, Clone)] #[clap(version, - name = "ffpapi", - version = "0.3.0", - about = "ffplayout REST API", + about = "REST API for ffplayout", long_about = None)] pub struct Args { #[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8080")] diff --git a/src/api/auth.rs b/ffplayout-api/src/utils/auth.rs similarity index 97% rename from src/api/auth.rs rename to ffplayout-api/src/utils/auth.rs index ba34919e..76351923 100644 --- a/src/api/auth.rs +++ b/ffplayout-api/src/utils/auth.rs @@ -4,7 +4,7 @@ use chrono::{Duration, Utc}; use jsonwebtoken::{self, DecodingKey, EncodingKey, Header, Validation}; use serde::{Deserialize, Serialize}; -use crate::api::utils::GlobalSettings; +use crate::utils::GlobalSettings; // Token lifetime const JWT_EXPIRATION_DAYS: i64 = 7; diff --git a/src/api/control.rs b/ffplayout-api/src/utils/control.rs similarity index 97% rename from src/api/control.rs rename to ffplayout-api/src/utils/control.rs index 42a9ba10..44804d85 100644 --- a/src/api/control.rs +++ b/ffplayout-api/src/utils/control.rs @@ -7,7 +7,7 @@ use reqwest::{ use serde::{Deserialize, Serialize}; use simplelog::*; -use crate::api::{errors::ServiceError, utils::playout_config}; +use crate::utils::{errors::ServiceError, playout_config}; #[derive(Debug, Deserialize, Serialize, Clone)] struct RpcObj { diff --git a/src/api/errors.rs b/ffplayout-api/src/utils/errors.rs similarity index 100% rename from src/api/errors.rs rename to ffplayout-api/src/utils/errors.rs diff --git a/src/api/files.rs b/ffplayout-api/src/utils/files.rs similarity index 94% rename from src/api/files.rs rename to ffplayout-api/src/utils/files.rs index e60daa19..4343d4ef 100644 --- a/src/api/files.rs +++ b/ffplayout-api/src/utils/files.rs @@ -4,8 +4,8 @@ use std::{fs, path::PathBuf}; use simplelog::*; -use crate::api::{errors::ServiceError, utils::playout_config}; -use crate::utils::file_extension; +use crate::utils::{errors::ServiceError, playout_config}; +use ffplayout_lib::utils::file_extension; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct PathObject { diff --git a/src/api/handles.rs b/ffplayout-api/src/utils/handles.rs similarity index 99% rename from src/api/handles.rs rename to ffplayout-api/src/utils/handles.rs index 5a88a184..9ee0f1f3 100644 --- a/src/api/handles.rs +++ b/ffplayout-api/src/utils/handles.rs @@ -7,10 +7,10 @@ use rand::{distributions::Alphanumeric, Rng}; use simplelog::*; use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Pool, Sqlite, SqlitePool}; -use crate::api::utils::GlobalSettings; -use crate::api::{ +use crate::utils::{ + db_path, models::{Settings, TextPreset, User}, - utils::db_path, + GlobalSettings, }; #[derive(Debug, sqlx::FromRow)] diff --git a/src/api/utils.rs b/ffplayout-api/src/utils/mod.rs similarity index 93% rename from src/api/utils.rs rename to ffplayout-api/src/utils/mod.rs index aedc1ee4..b3561173 100644 --- a/src/api/utils.rs +++ b/ffplayout-api/src/utils/mod.rs @@ -4,13 +4,23 @@ use faccess::PathExt; use once_cell::sync::OnceCell; use simplelog::*; -use crate::api::{ +pub mod args_parse; +pub mod auth; +pub mod control; +pub mod errors; +pub mod files; +pub mod handles; +pub mod models; +pub mod playlist; +pub mod routes; + +use crate::utils::{ args_parse::Args, errors::ServiceError, handles::{db_add_user, db_get_settings, db_global, db_init}, models::{Settings, User}, }; -use crate::utils::PlayoutConfig; +use ffplayout_lib::utils::PlayoutConfig; #[derive(PartialEq, Clone)] pub enum Role { diff --git a/src/api/models.rs b/ffplayout-api/src/utils/models.rs similarity index 100% rename from src/api/models.rs rename to ffplayout-api/src/utils/models.rs diff --git a/src/api/playlist.rs b/ffplayout-api/src/utils/playlist.rs similarity index 95% rename from src/api/playlist.rs rename to ffplayout-api/src/utils/playlist.rs index 6ee5c11b..9f828024 100644 --- a/src/api/playlist.rs +++ b/ffplayout-api/src/utils/playlist.rs @@ -6,8 +6,8 @@ use std::{ use simplelog::*; -use crate::api::{errors::ServiceError, utils::playout_config}; -use crate::utils::{generate_playlist as playlist_generator, JsonPlaylist}; +use crate::utils::{errors::ServiceError, playout_config}; +use ffplayout_lib::utils::{generate_playlist as playlist_generator, JsonPlaylist}; fn json_reader(path: &PathBuf) -> Result { let f = File::options().read(true).write(false).open(&path)?; diff --git a/src/api/routes.rs b/ffplayout-api/src/utils/routes.rs similarity index 96% rename from src/api/routes.rs rename to ffplayout-api/src/utils/routes.rs index 60622b64..3c98ba09 100644 --- a/src/api/routes.rs +++ b/ffplayout-api/src/utils/routes.rs @@ -9,22 +9,20 @@ use argon2::{ use serde::Serialize; use simplelog::*; -use crate::{ - api::{ - auth::{create_jwt, Claims}, - control::{control_state, media_info, send_message}, - errors::ServiceError, - files::{browser, PathObject}, - handles::{ - db_add_preset, db_add_user, db_get_presets, db_get_settings, db_login, db_role, - db_update_preset, db_update_settings, db_update_user, - }, - models::{LoginUser, Settings, TextPreset, User}, - playlist::{delete_playlist, generate_playlist, read_playlist, write_playlist}, - utils::{read_playout_config, Role}, +use crate::utils::{ + auth::{create_jwt, Claims}, + control::{control_state, media_info, send_message}, + errors::ServiceError, + files::{browser, PathObject}, + handles::{ + db_add_preset, db_add_user, db_get_presets, db_get_settings, db_login, db_role, + db_update_preset, db_update_settings, db_update_user, }, - utils::{JsonPlaylist, PlayoutConfig}, + models::{LoginUser, Settings, TextPreset, User}, + playlist::{delete_playlist, generate_playlist, read_playlist, write_playlist}, + read_playout_config, Role, }; +use ffplayout_lib::utils::{JsonPlaylist, PlayoutConfig}; #[derive(Serialize)] struct ResponseObj { diff --git a/assets/ffpapi.service b/ffplayout-api/unit/ffpapi.service similarity index 100% rename from assets/ffpapi.service rename to ffplayout-api/unit/ffpapi.service diff --git a/ffplayout-engine/Cargo.toml b/ffplayout-engine/Cargo.toml new file mode 100644 index 00000000..7b2cac32 --- /dev/null +++ b/ffplayout-engine/Cargo.toml @@ -0,0 +1,79 @@ +[package] +name = "ffplayout-engine" +description = "24/7 playout based on rust and ffmpeg" +license = "GPL-3.0" +authors = ["Jonathan Baecker jonbae77@gmail.com"] +readme = "README.md" +version = "0.9.9" +edition = "2021" + +[dependencies] +ffplayout-lib = { path = "../lib" } +chrono = { git = "https://github.com/sbrocket/chrono", branch = "parse-error-kind-public" } +clap = { version = "3.2", features = ["derive"] } +crossbeam-channel = "0.5" +faccess = "0.2" +ffprobe = "0.3" +file-rotate = { git = "https://github.com/Ploppz/file-rotate.git", branch = "timestamp-parse-fix" } +futures = "0.3" +jsonrpc-http-server = "18.0" +lettre = "0.10.0-rc.7" +log = "0.4" +notify = "4.0" +rand = "0.8" +regex = "1" +reqwest = { version = "0.11", features = ["blocking", "json"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.8" +shlex = "1.1" +simplelog = { version = "^0.12", features = ["paris"] } +time = { version = "0.3", features = ["formatting", "macros"] } +walkdir = "2" +zeromq = { git = "https://github.com/zeromq/zmq.rs.git", default-features = false, features = [ + "async-std-runtime", + "tcp-transport" +] } + +[target.x86_64-unknown-linux-musl.dependencies] +openssl = { version = "0.10", features = ["vendored"] } + +[[bin]] +name = "ffplayout" +path = "src/main.rs" + +# DEBIAN DEB PACKAGE +[package.metadata.deb] +name = "ffplayout-engine" +priority = "optional" +section = "net" +license-file = ["../LICENSE", "0"] +depends = "" +suggests = "ffmpeg" +copyright = "Copyright (c) 2022, Jonathan Baecker. All rights reserved." +conf-files = ["/etc/ffplayout/ffplayout.yml"] +assets = [ + [ + "../target/x86_64-unknown-linux-musl/release/ffplayout", + "/usr/bin/ffplayout", + "755" + ], + ["../assets/ffplayout.yml", "/etc/ffplayout/ffplayout.yml", "644"], + ["../assets/logo.png", "/usr/share/ffplayout/logo.png", "644"], + ["../README.md", "/usr/share/doc/ffplayout/README", "644"], +] +maintainer-scripts = "debian/" +systemd-units = { enable = false, unit-scripts = "unit" } + +# REHL RPM PACKAGE +[package.metadata.generate-rpm] +name = "ffplayout-engine" +license = "GPL-3.0" +assets = [ + { source = "../target/x86_64-unknown-linux-musl/release/ffplayout", dest = "/usr/bin/ffplayout", mode = "755" }, + { source = "../assets/ffplayout.yml", dest = "/etc/ffplayout/ffplayout.yml", mode = "644", config = true }, + { source = "unit/ffplayout.service", dest = "/lib/systemd/system/ffplayout.service", mode = "644" }, + { source = "../README.md", dest = "/usr/share/doc/ffplayout/README", mode = "644", doc = true }, + { source = "../LICENSE", dest = "/usr/share/doc/ffplayout/LICENSE", mode = "644" }, + { source = "../assets/logo.png", dest = "/usr/share/ffplayout/logo.png", mode = "644" }, +] diff --git a/ffplayout-engine/README.md b/ffplayout-engine/README.md new file mode 100644 index 00000000..29590fe5 --- /dev/null +++ b/ffplayout-engine/README.md @@ -0,0 +1,2 @@ +**ffplayout-engine** +================ diff --git a/ffplayout-engine/src/input/folder.rs b/ffplayout-engine/src/input/folder.rs new file mode 100644 index 00000000..f7809434 --- /dev/null +++ b/ffplayout-engine/src/input/folder.rs @@ -0,0 +1,76 @@ +use std::{ + path::Path, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::channel, + {Arc, Mutex}, + }, + thread::sleep, + time::Duration, +}; + +use notify::{ + DebouncedEvent::{Create, Remove, Rename}, + {watcher, RecursiveMode, Watcher}, +}; +use simplelog::*; + +use ffplayout_lib::utils::{Media, PlayoutConfig}; + +/// Create a watcher, which monitor file changes. +/// When a change is register, update the current file list. +/// This makes it possible, to play infinitely and and always new files to it. +pub fn watchman( + config: PlayoutConfig, + is_terminated: Arc, + sources: Arc>>, +) { + let (tx, rx) = channel(); + + let path = config.storage.path; + + if !Path::new(&path).exists() { + error!("Folder path not exists: '{path}'"); + panic!("Folder path not exists: '{path}'"); + } + + let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); + watcher.watch(path, RecursiveMode::Recursive).unwrap(); + + while !is_terminated.load(Ordering::SeqCst) { + if let Ok(res) = rx.try_recv() { + match res { + Create(new_path) => { + let index = sources.lock().unwrap().len(); + let media = Media::new(index, new_path.display().to_string(), false); + + sources.lock().unwrap().push(media); + info!("Create new file: {new_path:?}"); + } + Remove(old_path) => { + sources + .lock() + .unwrap() + .retain(|x| x.source != old_path.display().to_string()); + info!("Remove file: {old_path:?}"); + } + Rename(old_path, new_path) => { + let index = sources + .lock() + .unwrap() + .iter() + .position(|x| *x.source == old_path.display().to_string()) + .unwrap(); + + let media = Media::new(index, new_path.display().to_string(), false); + sources.lock().unwrap()[index] = media; + + info!("Rename file: {old_path:?} to {new_path:?}"); + } + _ => (), + } + } + + sleep(Duration::from_secs(5)); + } +} diff --git a/src/input/ingest.rs b/ffplayout-engine/src/input/ingest.rs similarity index 96% rename from src/input/ingest.rs rename to ffplayout-engine/src/input/ingest.rs index a5cd4c28..cc316a30 100644 --- a/src/input/ingest.rs +++ b/ffplayout-engine/src/input/ingest.rs @@ -8,9 +8,9 @@ use std::{ use crossbeam_channel::Sender; use simplelog::*; -use crate::filter::ingest_filter::filter_cmd; -use crate::utils::{format_log_line, Ingest, PlayoutConfig, ProcessControl}; -use crate::vec_strings; +use ffplayout_lib::filter::ingest_filter::filter_cmd; +use ffplayout_lib::utils::{format_log_line, Ingest, PlayoutConfig, ProcessControl}; +use ffplayout_lib::vec_strings; pub fn log_line(line: String, level: &str) { if line.contains("[info]") && level.to_lowercase() == "info" { diff --git a/src/input/mod.rs b/ffplayout-engine/src/input/mod.rs similarity index 92% rename from src/input/mod.rs rename to ffplayout-engine/src/input/mod.rs index 9c1ffc6e..5fcaea62 100644 --- a/src/input/mod.rs +++ b/ffplayout-engine/src/input/mod.rs @@ -9,16 +9,18 @@ use std::{ use simplelog::*; -use crate::utils::{Media, PlayoutConfig, PlayoutStatus}; +use ffplayout_lib::utils::{Media, PlayoutConfig, PlayoutStatus}; pub mod folder; pub mod ingest; pub mod playlist; -pub use folder::{watchman, FolderSource}; +pub use folder::watchman; pub use ingest::ingest_server; pub use playlist::CurrentProgram; +use ffplayout_lib::utils::folder::FolderSource; + /// Create a source iterator from playlist, or from folder. pub fn source_generator( config: PlayoutConfig, diff --git a/src/input/playlist.rs b/ffplayout-engine/src/input/playlist.rs similarity index 99% rename from src/input/playlist.rs rename to ffplayout-engine/src/input/playlist.rs index e6384822..ab8da117 100644 --- a/src/input/playlist.rs +++ b/ffplayout-engine/src/input/playlist.rs @@ -10,7 +10,7 @@ use std::{ use serde_json::json; use simplelog::*; -use crate::utils::{ +use ffplayout_lib::utils::{ check_sync, gen_dummy, get_delta, get_sec, is_close, is_remote, json_serializer::read_json, modified_time, seek_and_length, valid_source, Media, PlayoutConfig, PlayoutStatus, DUMMY_LEN, }; diff --git a/src/main.rs b/ffplayout-engine/src/main.rs similarity index 90% rename from src/main.rs rename to ffplayout-engine/src/main.rs index 1d7394f2..c2db334d 100644 --- a/src/main.rs +++ b/ffplayout-engine/src/main.rs @@ -10,13 +10,23 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use simplelog::*; -use ffplayout_engine::{ +pub mod input; +pub mod output; +pub mod rpc; +// #[cfg(test)] +// mod tests; +pub mod utils; + +use utils::{arg_parse::get_args, get_config}; + +use crate::{ output::{player, write_hls}, rpc::json_rpc_server, - utils::{ - generate_playlist, get_args, init_logging, send_mail, validate_ffmpeg, PlayerControl, - PlayoutConfig, PlayoutStatus, ProcessControl, - }, +}; + +use ffplayout_lib::utils::{ + generate_playlist, init_logging, send_mail, validate_ffmpeg, PlayerControl, PlayoutStatus, + ProcessControl, }; #[derive(Serialize, Deserialize)] @@ -59,7 +69,7 @@ fn status_file(stat_file: &str, playout_stat: &PlayoutStatus) { fn main() { let args = get_args(); - let config = PlayoutConfig::new(Some(args)); + let config = get_config(args); let config_clone = config.clone(); let play_control = PlayerControl::new(); let playout_stat = PlayoutStatus::new(); diff --git a/src/output/desktop.rs b/ffplayout-engine/src/output/desktop.rs similarity index 92% rename from src/output/desktop.rs rename to ffplayout-engine/src/output/desktop.rs index 8ff89ba3..7c88bc06 100644 --- a/src/output/desktop.rs +++ b/ffplayout-engine/src/output/desktop.rs @@ -2,9 +2,9 @@ use std::process::{self, Command, Stdio}; use simplelog::*; -use crate::filter::v_drawtext; -use crate::utils::{Media, PlayoutConfig}; -use crate::vec_strings; +use ffplayout_lib::filter::v_drawtext; +use ffplayout_lib::utils::{Media, PlayoutConfig}; +use ffplayout_lib::vec_strings; /// Desktop Output /// diff --git a/src/output/hls.rs b/ffplayout-engine/src/output/hls.rs similarity index 98% rename from src/output/hls.rs rename to ffplayout-engine/src/output/hls.rs index 4373bfd9..c583625d 100644 --- a/src/output/hls.rs +++ b/ffplayout-engine/src/output/hls.rs @@ -27,13 +27,13 @@ use std::{ use simplelog::*; -use crate::filter::ingest_filter::filter_cmd; use crate::input::{ingest::log_line, source_generator}; -use crate::utils::{ +use ffplayout_lib::filter::ingest_filter::filter_cmd; +use ffplayout_lib::utils::{ prepare_output_cmd, sec_to_time, stderr_reader, Decoder, Ingest, PlayerControl, PlayoutConfig, PlayoutStatus, ProcessControl, }; -use crate::vec_strings; +use ffplayout_lib::vec_strings; /// Ingest Server for HLS fn ingest_to_hls_server( diff --git a/src/output/mod.rs b/ffplayout-engine/src/output/mod.rs similarity index 99% rename from src/output/mod.rs rename to ffplayout-engine/src/output/mod.rs index d2e18f68..337753a1 100644 --- a/src/output/mod.rs +++ b/ffplayout-engine/src/output/mod.rs @@ -16,11 +16,11 @@ mod stream; pub use hls::write_hls; use crate::input::{ingest_server, source_generator}; -use crate::utils::{ +use ffplayout_lib::utils::{ sec_to_time, stderr_reader, Decoder, PlayerControl, PlayoutConfig, PlayoutStatus, ProcessControl, }; -use crate::vec_strings; +use ffplayout_lib::vec_strings; /// Player /// diff --git a/src/output/stream.rs b/ffplayout-engine/src/output/stream.rs similarity index 92% rename from src/output/stream.rs rename to ffplayout-engine/src/output/stream.rs index b61af29b..ae4eec74 100644 --- a/src/output/stream.rs +++ b/ffplayout-engine/src/output/stream.rs @@ -2,9 +2,9 @@ use std::process::{self, Command, Stdio}; use simplelog::*; -use crate::filter::v_drawtext; -use crate::utils::{prepare_output_cmd, Media, PlayoutConfig}; -use crate::vec_strings; +use ffplayout_lib::filter::v_drawtext; +use ffplayout_lib::utils::{prepare_output_cmd, Media, PlayoutConfig}; +use ffplayout_lib::vec_strings; /// Streaming Output /// diff --git a/src/rpc/mod.rs b/ffplayout-engine/src/rpc/mod.rs similarity index 99% rename from src/rpc/mod.rs rename to ffplayout-engine/src/rpc/mod.rs index c96adeaf..9e85bedd 100644 --- a/src/rpc/mod.rs +++ b/ffplayout-engine/src/rpc/mod.rs @@ -11,7 +11,7 @@ use jsonrpc_http_server::{ use serde_json::{json, Map}; use simplelog::*; -use crate::utils::{ +use ffplayout_lib::utils::{ get_delta, get_filter_from_json, get_sec, sec_to_time, write_status, Media, PlayerControl, PlayoutConfig, PlayoutStatus, ProcessControl, }; diff --git a/src/rpc/zmq_cmd.rs b/ffplayout-engine/src/rpc/zmq_cmd.rs similarity index 100% rename from src/rpc/zmq_cmd.rs rename to ffplayout-engine/src/rpc/zmq_cmd.rs diff --git a/src/tests/mod.rs b/ffplayout-engine/src/tests/mod.rs similarity index 98% rename from src/tests/mod.rs rename to ffplayout-engine/src/tests/mod.rs index f629ede5..76b97867 100644 --- a/src/tests/mod.rs +++ b/ffplayout-engine/src/tests/mod.rs @@ -3,12 +3,10 @@ use std::{ time::Duration, }; -mod utils; - #[cfg(test)] use crate::output::player; #[cfg(test)] -use crate::utils::*; +use ffplayout_lib::utils::*; #[cfg(test)] use simplelog::*; diff --git a/src/utils/arg_parse.rs b/ffplayout-engine/src/utils/arg_parse.rs similarity index 100% rename from src/utils/arg_parse.rs rename to ffplayout-engine/src/utils/arg_parse.rs diff --git a/ffplayout-engine/src/utils/mod.rs b/ffplayout-engine/src/utils/mod.rs new file mode 100644 index 00000000..2aa9d0d7 --- /dev/null +++ b/ffplayout-engine/src/utils/mod.rs @@ -0,0 +1,64 @@ +use std::path::Path; + +pub mod arg_parse; + +pub use arg_parse::Args; +use ffplayout_lib::utils::{time_to_sec, PlayoutConfig}; + +pub fn get_config(args: Args) -> PlayoutConfig { + let mut config = PlayoutConfig::new(args.config); + + if let Some(gen) = args.generate { + config.general.generate = Some(gen); + } + + if let Some(log_path) = args.log { + if Path::new(&log_path).is_dir() { + config.logging.log_to_file = true; + } + config.logging.log_path = log_path; + } + + if let Some(playlist) = args.playlist { + config.playlist.path = playlist; + } + + if let Some(mode) = args.play_mode { + config.processing.mode = mode; + } + + if let Some(folder) = args.folder { + config.storage.path = folder; + config.processing.mode = "folder".into(); + } + + if let Some(start) = args.start { + config.playlist.day_start = start.clone(); + config.playlist.start_sec = Some(time_to_sec(&start)); + } + + if let Some(length) = args.length { + config.playlist.length = length.clone(); + + if length.contains(':') { + config.playlist.length_sec = Some(time_to_sec(&length)); + } else { + config.playlist.length_sec = Some(86400.0); + } + } + + if args.infinit { + config.playlist.infinit = args.infinit; + } + + if let Some(output) = args.output { + config.out.mode = output; + } + + if let Some(volume) = args.volume { + config.processing.volume = volume; + } + + config +} +// Read command line arguments, and override the config with them. diff --git a/assets/ffplayout-engine.service b/ffplayout-engine/unit/ffplayout.service similarity index 100% rename from assets/ffplayout-engine.service rename to ffplayout-engine/unit/ffplayout.service diff --git a/lib/Cargo.toml b/lib/Cargo.toml new file mode 100644 index 00000000..c5b76e0d --- /dev/null +++ b/lib/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "ffplayout-lib" +description = "Library for ffplayout" +license = "GPL-3.0" +authors = ["Jonathan Baecker jonbae77@gmail.com"] +readme = "README.md" +version = "0.9.9" +edition = "2021" + +[dependencies] +chrono = { git = "https://github.com/sbrocket/chrono", branch = "parse-error-kind-public" } +crossbeam-channel = "0.5" +faccess = "0.2" +ffprobe = "0.3" +file-rotate = { git = "https://github.com/Ploppz/file-rotate.git", branch = "timestamp-parse-fix" } +futures = "0.3" +jsonrpc-http-server = "18.0" +lettre = "0.10.0-rc.7" +log = "0.4" +notify = "4.0" +once_cell = "1.10" +rand = "0.8" +regex = "1" +reqwest = { version = "0.11", features = ["blocking", "json"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.8" +shlex = "1.1" +simplelog = { version = "^0.12", features = ["paris"] } +time = { version = "0.3", features = ["formatting", "macros"] } +walkdir = "2" + +[target.x86_64-unknown-linux-musl.dependencies] +openssl = { version = "0.10", features = ["vendored"] } diff --git a/src/filter/a_loudnorm.rs b/lib/src/filter/a_loudnorm.rs similarity index 100% rename from src/filter/a_loudnorm.rs rename to lib/src/filter/a_loudnorm.rs diff --git a/src/filter/ingest_filter.rs b/lib/src/filter/ingest_filter.rs similarity index 100% rename from src/filter/ingest_filter.rs rename to lib/src/filter/ingest_filter.rs diff --git a/src/filter/mod.rs b/lib/src/filter/mod.rs similarity index 100% rename from src/filter/mod.rs rename to lib/src/filter/mod.rs diff --git a/src/filter/v_drawtext.rs b/lib/src/filter/v_drawtext.rs similarity index 100% rename from src/filter/v_drawtext.rs rename to lib/src/filter/v_drawtext.rs diff --git a/src/filter/v_overlay.rs b/lib/src/filter/v_overlay.rs similarity index 100% rename from src/filter/v_overlay.rs rename to lib/src/filter/v_overlay.rs diff --git a/src/lib.rs b/lib/src/lib.rs similarity index 66% rename from src/lib.rs rename to lib/src/lib.rs index 89174366..da112113 100644 --- a/src/lib.rs +++ b/lib/src/lib.rs @@ -1,12 +1,9 @@ extern crate log; extern crate simplelog; -pub mod api; pub mod filter; -pub mod input; pub mod macros; -pub mod output; -pub mod rpc; +pub mod utils; + #[cfg(test)] mod tests; -pub mod utils; diff --git a/src/macros/mod.rs b/lib/src/macros/mod.rs similarity index 100% rename from src/macros/mod.rs rename to lib/src/macros/mod.rs diff --git a/src/tests/utils/mod.rs b/lib/src/tests/mod.rs similarity index 100% rename from src/tests/utils/mod.rs rename to lib/src/tests/mod.rs diff --git a/src/utils/config.rs b/lib/src/utils/config.rs similarity index 80% rename from src/utils/config.rs rename to lib/src/utils/config.rs index 9ad00436..5371bca9 100644 --- a/src/utils/config.rs +++ b/lib/src/utils/config.rs @@ -8,7 +8,7 @@ use std::{ use serde::{Deserialize, Serialize}; use shlex::split; -use crate::utils::{free_tcp_socket, time_to_sec, Args}; +use crate::utils::{free_tcp_socket, time_to_sec}; use crate::vec_strings; /// Global Config @@ -168,10 +168,10 @@ pub struct Out { impl PlayoutConfig { /// Read config from YAML file, and set some extra config values. - pub fn new(args: Option) -> Self { + pub fn new(cfg_path: Option) -> Self { let mut config_path = PathBuf::from("/etc/ffplayout/ffplayout.yml"); - if let Some(cfg) = args.clone().and_then(|a| a.config) { + if let Some(cfg) = cfg_path { config_path = PathBuf::from(cfg); } @@ -259,61 +259,6 @@ impl PlayoutConfig { config.text.node_pos = None; } - // Read command line arguments, and override the config with them. - - if let Some(arg) = args { - if let Some(gen) = arg.generate { - config.general.generate = Some(gen); - } - - if let Some(log_path) = arg.log { - if Path::new(&log_path).is_dir() { - config.logging.log_to_file = true; - } - config.logging.log_path = log_path; - } - - if let Some(playlist) = arg.playlist { - config.playlist.path = playlist; - } - - if let Some(mode) = arg.play_mode { - config.processing.mode = mode; - } - - if let Some(folder) = arg.folder { - config.storage.path = folder; - config.processing.mode = "folder".into(); - } - - if let Some(start) = arg.start { - config.playlist.day_start = start.clone(); - config.playlist.start_sec = Some(time_to_sec(&start)); - } - - if let Some(length) = arg.length { - config.playlist.length = length.clone(); - - if length.contains(':') { - config.playlist.length_sec = Some(time_to_sec(&length)); - } else { - config.playlist.length_sec = Some(86400.0); - } - } - - if arg.infinit { - config.playlist.infinit = arg.infinit; - } - - if let Some(output) = arg.output { - config.out.mode = output; - } - - if let Some(volume) = arg.volume { - config.processing.volume = volume; - } - } - config } } diff --git a/src/utils/controller.rs b/lib/src/utils/controller.rs similarity index 100% rename from src/utils/controller.rs rename to lib/src/utils/controller.rs diff --git a/src/input/folder.rs b/lib/src/utils/folder.rs similarity index 63% rename from src/input/folder.rs rename to lib/src/utils/folder.rs index a1b10ce6..0aa569f4 100644 --- a/src/input/folder.rs +++ b/lib/src/utils/folder.rs @@ -2,18 +2,11 @@ use std::{ path::Path, process::exit, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, - mpsc::channel, + atomic::{AtomicUsize, Ordering}, {Arc, Mutex}, }, - thread::sleep, - time::Duration, }; -use notify::{ - DebouncedEvent::{Create, Remove, Rename}, - {watcher, RecursiveMode, Watcher}, -}; use rand::{seq::SliceRandom, thread_rng}; use simplelog::*; use walkdir::WalkDir; @@ -153,61 +146,3 @@ impl Iterator for FolderSource { } } } - -/// Create a watcher, which monitor file changes. -/// When a change is register, update the current file list. -/// This makes it possible, to play infinitely and and always new files to it. -pub fn watchman( - config: PlayoutConfig, - is_terminated: Arc, - sources: Arc>>, -) { - let (tx, rx) = channel(); - - let path = config.storage.path; - - if !Path::new(&path).exists() { - error!("Folder path not exists: '{path}'"); - panic!("Folder path not exists: '{path}'"); - } - - let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); - watcher.watch(path, RecursiveMode::Recursive).unwrap(); - - while !is_terminated.load(Ordering::SeqCst) { - if let Ok(res) = rx.try_recv() { - match res { - Create(new_path) => { - let index = sources.lock().unwrap().len(); - let media = Media::new(index, new_path.display().to_string(), false); - - sources.lock().unwrap().push(media); - info!("Create new file: {new_path:?}"); - } - Remove(old_path) => { - sources - .lock() - .unwrap() - .retain(|x| x.source != old_path.display().to_string()); - info!("Remove file: {old_path:?}"); - } - Rename(old_path, new_path) => { - let index = sources - .lock() - .unwrap() - .iter() - .position(|x| *x.source == old_path.display().to_string()) - .unwrap(); - - let media = Media::new(index, new_path.display().to_string(), false); - sources.lock().unwrap()[index] = media; - - info!("Rename file: {old_path:?} to {new_path:?}"); - } - _ => (), - } - } - - sleep(Duration::from_secs(5)); - } -} diff --git a/src/utils/generator.rs b/lib/src/utils/generator.rs similarity index 99% rename from src/utils/generator.rs rename to lib/src/utils/generator.rs index 643decc7..c81bcb20 100644 --- a/src/utils/generator.rs +++ b/lib/src/utils/generator.rs @@ -17,7 +17,7 @@ use std::{ use chrono::{Duration, NaiveDate}; use simplelog::*; -use crate::input::FolderSource; +use super::folder::FolderSource; use crate::utils::{json_serializer::JsonPlaylist, time_to_sec, Media, PlayoutConfig}; /// Generate a vector with dates, from given range. diff --git a/src/utils/json_serializer.rs b/lib/src/utils/json_serializer.rs similarity index 100% rename from src/utils/json_serializer.rs rename to lib/src/utils/json_serializer.rs diff --git a/src/utils/json_validate.rs b/lib/src/utils/json_validate.rs similarity index 100% rename from src/utils/json_validate.rs rename to lib/src/utils/json_validate.rs diff --git a/src/utils/logging.rs b/lib/src/utils/logging.rs similarity index 100% rename from src/utils/logging.rs rename to lib/src/utils/logging.rs diff --git a/src/utils/mod.rs b/lib/src/utils/mod.rs similarity index 99% rename from src/utils/mod.rs rename to lib/src/utils/mod.rs index 38ed54e4..3cbc0881 100644 --- a/src/utils/mod.rs +++ b/lib/src/utils/mod.rs @@ -18,15 +18,14 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use simplelog::*; -mod arg_parse; pub mod config; pub mod controller; +pub mod folder; mod generator; pub mod json_serializer; mod json_validate; mod logging; -pub use arg_parse::{get_args, Args}; pub use config::{self as playout_config, PlayoutConfig}; pub use controller::{PlayerControl, PlayoutStatus, ProcessControl, ProcessUnit::*}; pub use generator::generate_playlist; diff --git a/src/api/mod.rs b/src/api/mod.rs deleted file mode 100644 index 78826bad..00000000 --- a/src/api/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod args_parse; -pub mod auth; -pub mod control; -pub mod errors; -pub mod files; -pub mod handles; -pub mod models; -pub mod playlist; -pub mod routes; -pub mod utils;