Merge branch 'main' of github.com:ffplayout/ffplayout-rs

This commit is contained in:
jb-alvarado 2022-03-17 19:57:10 +01:00
commit d206967975
7 changed files with 162 additions and 15 deletions

19
Cargo.lock generated
View File

@ -143,7 +143,7 @@ dependencies = [
[[package]]
name = "ffplayout-rs"
version = "0.1.0"
version = "0.4.0"
dependencies = [
"chrono",
"clap",
@ -449,9 +449,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.120"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09"
[[package]]
name = "linked-hash-map"
@ -582,13 +582,12 @@ dependencies = [
[[package]]
name = "nom"
version = "7.1.0"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
dependencies = [
"memchr",
"minimal-lexical",
"version_check",
]
[[package]]
@ -666,9 +665,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
version = "111.17.0+1.1.1m"
version = "111.18.0+1.1.1n"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d6a336abd10814198f66e2a91ccd7336611f30334119ca8ce300536666fcf4"
checksum = "7897a926e1e8d00219127dc020130eca4292e5ca666dd592480d72c3eca2ff6c"
dependencies = [
"cc",
]
@ -956,9 +955,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.86"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54"
dependencies = [
"proc-macro2",
"quote",

View File

@ -1,8 +1,6 @@
# cargo-features = ["strip"]
[package]
name = "ffplayout-rs"
version = "0.1.0"
version = "0.4.0"
edition = "2021"
[dependencies]
@ -31,5 +29,6 @@ name = "ffplayout"
path = "src/main.rs"
[profile.release]
# strip = true
opt-level = 3
strip = true
lto = true

129
README.md
View File

@ -5,10 +5,137 @@
Next generation 24/7 playout, based on [Rust](https://www.rust-lang.org/).
**At the moment this is only a playground and not ready for production!**
**At the moment this project is in beta state, testing and feedback are welcome.**
**No feature requests please!**
If you search right now a working solution, try [ffplayout_engine](https://github.com/ffplayout/ffplayout_engine).
The main purpose of ffplayout is to provide a 24/7 broadcasting solution that plays a *json* playlist for every day, while keeping the current playlist editable.
**Check [ffplayout-frontend](https://github.com/ffplayout/ffplayout-frontend): web-based GUI for ffplayout**
**Features**
-----
- have all values in a separate config file
- dynamic playlist
- replace missing playlist or clip with a dummy clip
- playing clips from [watched folder](https://github.com/ffplayout/ffplayout_engine/wiki/Watch-Folder)
- send emails with error message
- overlay a logo
- overlay text, controllable through [messenger](https://github.com/ffplayout/messenger) or [ffplayout-frontend](https://github.com/ffplayout/ffplayout-frontend) (needs ffmpeg with libzmq)
- **EBU R128 loudness** normalization (single pass) (experimental)
- loop playlist infinitely
- trim and fade the last clip, to get full 24 hours
- when playlist is not 24 hours long, loop filler clip until time is full
- set custom day start, so you can have playlist for example: from 6am to 6am, instate of 0am to 12pm
- 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
- add filters to input, if is necessary to match output stream:
- **yadif** (deinterlacing)
- **pad** (letterbox or pillarbox to fit aspect)
- **fps** (change fps)
- **scale** (fit target resolution)
- **aevalsrc** (if video have no audio)
- **apad** (add silence if audio duration is to short)
- **tpad** (add black frames if video duration is to short)
output):
- **stream**
- **desktop**
Requirements
-----
- RAM and CPU depends on video resolution, minimum 4 threads and 3GB RAM for 720p are recommend
JSON Playlist Example
-----
```json
{
"channel": "Test 1",
"date": "2019-03-05",
"program": [{
"in": 0,
"out": 647.68,
"duration": 647.68,
"source": "/Media/clip1.mp4"
}, {
"in": 0,
"out": 149,
"duration": 149,
"source": "/Media/clip2.mp4"
}, {
"in": 0,
"out": 114.72,
"duration": 114.72,
"source": "/Media/clip3.mp4",
"category": "advertisement"
}, {
"in": 0,
"out": 2531.36,
"duration": 2531.36,
"source": "/Media/clip4.mp4",
"category": ""
}
]
}
```
**If you need a simple playlist generator check:** [playlist-generator](https://github.com/ffplayout/playlist-generator)
**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.
Remote source from URL
-----
You can use sources from remote URL in that way:
```json
{
"in": 0,
"out": 149,
"duration": 149,
"source": "https://example.org/big_buck_bunny.webm"
}
```
But be careful with it, better test it multiple times!
More informations in [Wiki](https://github.com/ffplayout/ffplayout_engine/wiki/Remote-URL-Source)
Installation
-----
Copy the binary to `/usr/local/bin/`
Start with Arguments
-----
ffplayout also allows the passing of parameters:
- `-c, --config <CONFIG>` file path to ffplayout.conf
- `-f, --folder <FOLDER>` play folder content
- `-h, --help` Print help information
- `-i, --infinit` loop playlist infinitely
- `-l, --log <LOG>` file path for logging
- `-m, --play-mode <PLAY_MODE>` playing mode: folder, playlist
- `-o, --output <OUTPUT>` set output mode: desktop, hls, stream
- `-p, --playlist <PLAYLIST>` path from playlist
- `-s, --start <START>` start time in 'hh:mm:ss', 'now' for start with first
- `-t, --length <LENGTH>` set length in 'hh:mm:ss', 'none' for no length check
- `-v, --volume <VOLUME>` set audio volume
- `-V, --version` Print version information
You can run the command like:
```SHELL
./ffplayout.py -l none -p ~/playlist.json -o desktop
```

View File

@ -28,6 +28,7 @@ logging:
log_to_file: false
backup_count: 7
local_time: true
timestamp: true
log_path: "/var/log/ffplayout/"
log_level: "DEBUG"
ffmpeg_level: "error"

View File

@ -0,0 +1,14 @@
[Unit]
Description=python and ffmpeg based playout
After=network.target
[Service]
ExecStart= /usr/local/bin/ffplayout
ExecReload=/bin/kill -1 $MAINPID
Restart=always
RestartSec=1
User=www-data
Group=www-data
[Install]
WantedBy=multi-user.target

View File

@ -44,6 +44,7 @@ pub struct Logging {
pub log_to_file: bool,
pub backup_count: usize,
pub local_time: bool,
pub timestamp: bool,
pub log_path: String,
pub log_level: String,
pub ffmpeg_level: String,

View File

@ -103,13 +103,19 @@ async fn send_mail(msg: String) {
pub fn init_logging(rt_handle: Handle) -> Vec<Box<dyn SharedLogger>> {
let config = GlobalConfig::global();
let app_config = config.logging.clone();
let mut time_level = LevelFilter::Off;
let mut app_logger: Vec<Box<dyn SharedLogger>> = vec![];
if app_config.timestamp {
time_level = LevelFilter::Error;
}
let log_config = simplelog::ConfigBuilder::new()
.set_thread_level(LevelFilter::Off)
.set_target_level(LevelFilter::Off)
.set_level_padding(LevelPadding::Left)
.set_time_to_local(app_config.local_time)
.set_time_level(time_level)
.clone();
if app_config.log_to_file {