commit
64b59c5f50
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -991,7 +991,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-api"
|
||||
version = "0.9.0-beta3"
|
||||
version = "0.17.0-beta3"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-multipart",
|
||||
@ -2805,7 +2805,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tests"
|
||||
version = "0.1.1"
|
||||
version = "0.17.0-beta3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
|
@ -2,6 +2,13 @@
|
||||
members = ["ffplayout-api", "ffplayout-engine", "lib", "tests"]
|
||||
default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.17.0-beta3"
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/ffplayout/ffplayout"
|
||||
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
strip = true
|
||||
|
17
README.md
17
README.md
@ -5,9 +5,9 @@
|
||||
|
||||
## **ffplayout-engine (ffplayout)**
|
||||
|
||||
[ffplayout](/ffplayout-engine/README.md) is a 24/7 broadcasting solution. It can playout a folder with containing video clips, or play for every day a *JSON* playlist, while keeping the current playlist editable.
|
||||
[ffplayout](/ffplayout-engine/README.md) is a 24/7 broadcasting solution. It can playout a folder containing audio or video clips, or play a *JSON* playlist for each day, keeping the current playlist editable.
|
||||
|
||||
The ffplayout apps are mostly made to run on Linux as system services. But in general they should run on all platforms which are supported by Rust.
|
||||
The ffplayout applications are mostly designed to run as system services on Linux. But in general they should run on any platform supported by Rust.
|
||||
|
||||
Check the [releases](https://github.com/ffplayout/ffplayout/releases/latest) for pre compiled version.
|
||||
|
||||
@ -29,7 +29,7 @@ Check the [releases](https://github.com/ffplayout/ffplayout/releases/latest) for
|
||||
- normal system requirements and no special tools
|
||||
- no GPU power is needed
|
||||
- stream to server or play on desktop
|
||||
- logging to files, or colored output to console
|
||||
- log to files or color output to console
|
||||
- add filters to input, if is necessary to match output stream:
|
||||
- **yadif** (deinterlacing)
|
||||
- **pad** (letterbox or pillarbox to fit aspect)
|
||||
@ -43,17 +43,18 @@ Check the [releases](https://github.com/ffplayout/ffplayout/releases/latest) for
|
||||
- **desktop**
|
||||
- **HLS**
|
||||
- **null** (for debugging)
|
||||
- JSON RPC server, for getting infos about current playing and controlling
|
||||
- JSON RPC server, to get information about what is playing and to control it
|
||||
- [live ingest](/docs/live_ingest.md)
|
||||
- image source (will loop until out duration is reached)
|
||||
- extra audio source (experimental *) (has priority over audio from video source)
|
||||
- [multiple audio tracks](/docs/multi_audio.md) (experimental *)
|
||||
- [custom filter](/docs/custom_filters.md) globally in config, or in playlist for specific clips
|
||||
- [custom filters](/docs/custom_filters.md) globally in config, or in playlist for specific clips
|
||||
- import playlist from text or m3u file, with CLI or frontend
|
||||
- audio only, for radio mode (experimental *)
|
||||
|
||||
For preview stream, read: [/docs/preview_stream.md](/docs/preview_stream.md)
|
||||
|
||||
**\* Experimental functions do not guarantee the same stability, also they can fail in unusual circumstances. The code and configuration options may change in the future.**
|
||||
**\* Experimental features do not guarantee the same stability and may fail under unusual circumstances. Code and configuration options may change in the future.**
|
||||
|
||||
## **ffplayout-api (ffpapi)**
|
||||
|
||||
@ -118,7 +119,7 @@ Check [install](docs/install.md) for details about how to install ffplayout.
|
||||
|
||||
## **Warning**
|
||||
|
||||
(Endless) streaming over multiple days will only work when config have **day_start** value and the **length** value is **24 hours**. If you need only some hours for every day, use a *cron* job, or something similar.
|
||||
(Endless) streaming over multiple days will only work if config has a **day_start** value and the **length** value is **24 hours**. If you only need a few hours for each day, use a *cron* job or something similar.
|
||||
|
||||
-----
|
||||
|
||||
@ -192,4 +193,4 @@ Output from `{"media":"current"}` show:
|
||||
}
|
||||
```
|
||||
|
||||
When you are in playlist mode and jumping forward or backwards in time, the time shift will be saved so the playlist is still in sync. But have in mind, that then maybe your playlist gets to short. When you are not resetting the state, it will reset on the next day automatically.
|
||||
If you are in playlist mode and move backwards or forwards in time, the time shift is saved so the playlist is still in sync. Bear in mind, however, that this may make your playlist too short. If you do not reset it, it will automatically reset the next day.
|
||||
|
@ -1,11 +1,12 @@
|
||||
[package]
|
||||
name = "ffplayout-api"
|
||||
description = "Rest API for ffplayout"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Jonathan Baecker jonbae77@gmail.com"]
|
||||
readme = "README.md"
|
||||
version = "0.9.0-beta3"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
ffplayout-lib = { path = "../lib" }
|
||||
@ -33,10 +34,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.8"
|
||||
simplelog = { version = "^0.12", features = ["paris"] }
|
||||
sqlx = { version = "0.6", features = [
|
||||
"runtime-actix-native-tls",
|
||||
"sqlite"
|
||||
] }
|
||||
sqlx = { version = "0.6", features = ["runtime-actix-native-tls", "sqlite"] }
|
||||
|
||||
[[bin]]
|
||||
name = "ffpapi"
|
||||
|
@ -1,11 +1,13 @@
|
||||
[package]
|
||||
name = "ffplayout"
|
||||
description = "24/7 playout based on rust and ffmpeg"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Jonathan Baecker jonbae77@gmail.com"]
|
||||
readme = "README.md"
|
||||
version = "0.17.0-beta3"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
default-run = "ffplayout"
|
||||
|
||||
[dependencies]
|
||||
@ -23,7 +25,7 @@ serde_json = "1.0"
|
||||
simplelog = { version = "^0.12", features = ["paris"] }
|
||||
zeromq = { git = "https://github.com/zeromq/zmq.rs.git", default-features = false, features = [
|
||||
"async-std-runtime",
|
||||
"tcp-transport"
|
||||
"tcp-transport",
|
||||
] }
|
||||
|
||||
[target.x86_64-unknown-linux-musl.dependencies]
|
||||
@ -45,48 +47,152 @@ 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/", "755"],
|
||||
[
|
||||
"../target/x86_64-unknown-linux-musl/release/ffpapi",
|
||||
"/usr/bin/",
|
||||
"755",
|
||||
],
|
||||
[
|
||||
"../target/x86_64-unknown-linux-musl/release/ffplayout",
|
||||
"/usr/bin/",
|
||||
"755"
|
||||
"755",
|
||||
],
|
||||
[
|
||||
"../assets/ffpapi.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout@.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/11-ffplayout",
|
||||
"/etc/sudoers.d/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.yml",
|
||||
"/etc/ffplayout/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/logo.png",
|
||||
"/usr/share/ffplayout/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.yml",
|
||||
"/usr/share/ffplayout/ffplayout.yml.orig",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.conf",
|
||||
"/usr/share/ffplayout/ffplayout.conf.example",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../README.md",
|
||||
"/usr/share/doc/ffplayout/README",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffpapi.1.gz",
|
||||
"/usr/share/man/man1/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.1.gz",
|
||||
"/usr/share/man/man1/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../public/**/*",
|
||||
"/usr/share/ffplayout/public/",
|
||||
"644",
|
||||
],
|
||||
["../assets/ffpapi.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/ffplayout.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/ffplayout@.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/11-ffplayout", "/etc/sudoers.d/", "644"],
|
||||
["../assets/ffplayout.yml", "/etc/ffplayout/", "644"],
|
||||
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
|
||||
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
|
||||
["../assets/ffplayout.conf", "/usr/share/ffplayout/ffplayout.conf.example", "644"],
|
||||
["../README.md", "/usr/share/doc/ffplayout/README", "644"],
|
||||
["../assets/ffpapi.1.gz", "/usr/share/man/man1/", "644"],
|
||||
["../assets/ffplayout.1.gz", "/usr/share/man/man1/", "644"],
|
||||
["../public/**/*", "/usr/share/ffplayout/public/", "644"],
|
||||
]
|
||||
maintainer-scripts = "../debian/"
|
||||
systemd-units = { enable = false, unit-scripts = "../assets" }
|
||||
|
||||
[package.metadata.deb.variants.arm64]
|
||||
assets = [
|
||||
["../target/aarch64-unknown-linux-gnu/release/ffpapi", "/usr/bin/", "755"],
|
||||
[
|
||||
"../target/aarch64-unknown-linux-gnu/release/ffpapi",
|
||||
"/usr/bin/",
|
||||
"755",
|
||||
],
|
||||
[
|
||||
"../target/aarch64-unknown-linux-gnu/release/ffplayout",
|
||||
"/usr/bin/",
|
||||
"755"
|
||||
"755",
|
||||
],
|
||||
[
|
||||
"../assets/ffpapi.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout@.service",
|
||||
"/lib/systemd/system/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/11-ffplayout",
|
||||
"/etc/sudoers.d/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.yml",
|
||||
"/etc/ffplayout/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/logo.png",
|
||||
"/usr/share/ffplayout/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.yml",
|
||||
"/usr/share/ffplayout/ffplayout.yml.orig",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.conf",
|
||||
"/usr/share/ffplayout/ffplayout.conf.example",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../README.md",
|
||||
"/usr/share/doc/ffplayout/README",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffpapi.1.gz",
|
||||
"/usr/share/man/man1/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../assets/ffplayout.1.gz",
|
||||
"/usr/share/man/man1/",
|
||||
"644",
|
||||
],
|
||||
[
|
||||
"../public/**/*",
|
||||
"/usr/share/ffplayout/public/",
|
||||
"644",
|
||||
],
|
||||
["../assets/ffpapi.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/ffplayout.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/ffplayout@.service", "/lib/systemd/system/", "644"],
|
||||
["../assets/11-ffplayout", "/etc/sudoers.d/", "644"],
|
||||
["../assets/ffplayout.yml", "/etc/ffplayout/", "644"],
|
||||
["../assets/logo.png", "/usr/share/ffplayout/", "644"],
|
||||
["../assets/ffplayout.yml", "/usr/share/ffplayout/ffplayout.yml.orig", "644"],
|
||||
["../assets/ffplayout.conf", "/usr/share/ffplayout/ffplayout.conf.example", "644"],
|
||||
["../README.md", "/usr/share/doc/ffplayout/README", "644"],
|
||||
["../assets/ffpapi.1.gz", "/usr/share/man/man1/", "644"],
|
||||
["../assets/ffplayout.1.gz", "/usr/share/man/man1/", "644"],
|
||||
["../public/**/*", "/usr/share/ffplayout/public/", "644"],
|
||||
]
|
||||
|
||||
# REHL RPM PACKAGE
|
||||
|
@ -1,11 +1,12 @@
|
||||
[package]
|
||||
name = "ffplayout-lib"
|
||||
description = "Library for ffplayout"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Jonathan Baecker jonbae77@gmail.com"]
|
||||
readme = "README.md"
|
||||
version = "0.17.0-beta3"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4"
|
||||
@ -29,11 +30,7 @@ walkdir = "2"
|
||||
|
||||
[target."cfg(windows)".dependencies.winapi]
|
||||
version = "0.3"
|
||||
features = [
|
||||
"shlobj",
|
||||
"std",
|
||||
"winerror",
|
||||
]
|
||||
features = ["shlobj", "std", "winerror"]
|
||||
|
||||
[target.x86_64-unknown-linux-musl.dependencies]
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
|
@ -3,7 +3,7 @@ use simplelog::*;
|
||||
|
||||
/// Apply custom filters
|
||||
pub fn filter_node(filter: &str) -> (String, String) {
|
||||
let re = Regex::new(r"^;?(\[[^\[]+\])?|\[[^\[]+\]$").unwrap(); // match start/end link;
|
||||
let re = Regex::new(r"^;?(\[[0-9]:[^\[]+\])?|\[[^\[]+\]$").unwrap(); // match start/end link
|
||||
let mut video_filter = String::new();
|
||||
let mut audio_filter = String::new();
|
||||
|
||||
@ -35,9 +35,5 @@ pub fn filter_node(filter: &str) -> (String, String) {
|
||||
error!("Custom filter is not well formatted, use correct out link names (\"[c_v_out]\" and/or \"[c_a_out]\"). Filter skipped!")
|
||||
}
|
||||
|
||||
if filter.starts_with("[v_in]") {
|
||||
video_filter = format!("[v_in]{video_filter}");
|
||||
}
|
||||
|
||||
(video_filter, audio_filter)
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
[package]
|
||||
name = "tests"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
edition.workspace = true
|
||||
publish = false
|
||||
|
||||
[dev-dependencies]
|
||||
@ -39,4 +42,3 @@ path = "src/engine_playlist.rs"
|
||||
[[test]]
|
||||
name = "engine_cmd"
|
||||
path = "src/engine_cmd.rs"
|
||||
|
||||
|
@ -85,6 +85,32 @@ fn video_audio_custom_filter2_input() {
|
||||
assert_eq!(media.filter.unwrap().map(), test_filter_map);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn video_audio_custom_filter3_input() {
|
||||
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
|
||||
config.out.mode = Stream;
|
||||
config.processing.add_logo = false;
|
||||
config.processing.custom_filter =
|
||||
"[v_in];movie=logo.png[l];[v_in][l]overlay[c_v_out];[0:a]volume=0.2[c_a_out]".to_string();
|
||||
|
||||
let media_obj = Media::new(0, "./assets/with_audio.mp4", true);
|
||||
let media = gen_source(&config, media_obj, &None);
|
||||
|
||||
let test_filter_cmd = vec_strings![
|
||||
"-filter_complex",
|
||||
"[0:v:0]scale=1024:576[v_in];movie=logo.png[l];[v_in][l]overlay[vout0];[0:a:0]anull,volume=0.2[aout0]"
|
||||
];
|
||||
|
||||
let test_filter_map = vec_strings!["-map", "[vout0]", "-map", "[aout0]"];
|
||||
|
||||
assert_eq!(
|
||||
media.cmd,
|
||||
Some(vec_strings!["-i", "./assets/with_audio.mp4"])
|
||||
);
|
||||
assert_eq!(media.filter.clone().unwrap().cmd(), test_filter_cmd);
|
||||
assert_eq!(media.filter.unwrap().map(), test_filter_map);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dual_audio_aevalsrc_input() {
|
||||
let mut config = PlayoutConfig::new(Some("../assets/ffplayout.yml".to_string()));
|
||||
|
Loading…
Reference in New Issue
Block a user