Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6fbde92f6b | ||
|
813e48fd54 | ||
|
943cf90e15 | ||
|
53aebc779b | ||
|
b96e765f0b | ||
|
05ab9aac71 | ||
|
0808fb29ab |
1037
Cargo.lock
generated
1037
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,10 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["ffplayout-api", "ffplayout-engine", "lib", "tests"]
|
members = ["ffplayout-api", "ffplayout-engine", "lib", "tests"]
|
||||||
default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.19.0"
|
version = "0.19.1"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
repository = "https://github.com/ffplayout/ffplayout"
|
repository = "https://github.com/ffplayout/ffplayout"
|
||||||
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
||||||
|
@ -27,7 +27,7 @@ once_cell = "1.10"
|
|||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
relative-path = "1.6"
|
relative-path = "1.6"
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||||
rpassword = "6.0"
|
rpassword = "6.0"
|
||||||
sanitize-filename = "0.3"
|
sanitize-filename = "0.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
@ -296,38 +296,12 @@ pub async fn media_info(
|
|||||||
post_request(conn, id, json_obj).await
|
post_request(conn, id, json_obj).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn control_service(
|
async fn execute_systemd(
|
||||||
conn: &Pool<Sqlite>,
|
conn: &Pool<Sqlite>,
|
||||||
id: i32,
|
id: i32,
|
||||||
command: &ServiceCmd,
|
command: &ServiceCmd,
|
||||||
engine: Option<web::Data<ProcessControl>>,
|
|
||||||
) -> Result<String, ServiceError> {
|
) -> Result<String, ServiceError> {
|
||||||
if engine.is_some() && engine.as_ref().unwrap().piggyback.load(Ordering::SeqCst) {
|
|
||||||
match command {
|
|
||||||
ServiceCmd::Start => engine.unwrap().start().await,
|
|
||||||
ServiceCmd::Stop => {
|
|
||||||
if control_state(conn, id, "stop_all").await.is_ok() {
|
|
||||||
engine.unwrap().stop().await
|
|
||||||
} else {
|
|
||||||
Err(ServiceError::NoContent("Nothing to stop".to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServiceCmd::Restart => {
|
|
||||||
if control_state(conn, id, "stop_all").await.is_ok() {
|
|
||||||
engine.unwrap().restart().await
|
|
||||||
} else {
|
|
||||||
Err(ServiceError::NoContent("Nothing to stop".to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServiceCmd::Status => engine.unwrap().status(),
|
|
||||||
_ => Err(ServiceError::Conflict(
|
|
||||||
"Engine runs in piggyback mode, in this mode this command is not allowed."
|
|
||||||
.to_string(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let system_d = SystemD::new(conn, id).await?;
|
let system_d = SystemD::new(conn, id).await?;
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
ServiceCmd::Enable => system_d.enable(),
|
ServiceCmd::Enable => system_d.enable(),
|
||||||
ServiceCmd::Disable => system_d.disable(),
|
ServiceCmd::Disable => system_d.disable(),
|
||||||
@ -336,5 +310,42 @@ pub async fn control_service(
|
|||||||
ServiceCmd::Restart => system_d.restart(),
|
ServiceCmd::Restart => system_d.restart(),
|
||||||
ServiceCmd::Status => system_d.status().await,
|
ServiceCmd::Status => system_d.status().await,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn control_service(
|
||||||
|
conn: &Pool<Sqlite>,
|
||||||
|
id: i32,
|
||||||
|
command: &ServiceCmd,
|
||||||
|
engine: Option<web::Data<ProcessControl>>,
|
||||||
|
) -> Result<String, ServiceError> {
|
||||||
|
if let Some(en) = engine {
|
||||||
|
if en.piggyback.load(Ordering::SeqCst) {
|
||||||
|
match command {
|
||||||
|
ServiceCmd::Start => en.start().await,
|
||||||
|
ServiceCmd::Stop => {
|
||||||
|
if control_state(conn, id, "stop_all").await.is_ok() {
|
||||||
|
en.stop().await
|
||||||
|
} else {
|
||||||
|
Err(ServiceError::NoContent("Nothing to stop".to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ServiceCmd::Restart => {
|
||||||
|
if control_state(conn, id, "stop_all").await.is_ok() {
|
||||||
|
en.restart().await
|
||||||
|
} else {
|
||||||
|
Err(ServiceError::NoContent("Nothing to restart".to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ServiceCmd::Status => en.status(),
|
||||||
|
_ => Err(ServiceError::Conflict(
|
||||||
|
"Engine runs in piggyback mode, in this mode this command is not allowed."
|
||||||
|
.to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
execute_systemd(conn, id, command).await
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
execute_systemd(conn, id, command).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ futures = "0.3"
|
|||||||
notify = "6.0"
|
notify = "6.0"
|
||||||
notify-debouncer-full = { version = "*", default-features = false }
|
notify-debouncer-full = { version = "*", default-features = false }
|
||||||
regex = "1"
|
regex = "1"
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
simplelog = { version = "^0.12", features = ["paris"] }
|
simplelog = { version = "^0.12", features = ["paris"] }
|
||||||
@ -29,9 +29,6 @@ zeromq = { git = "https://github.com/zeromq/zmq.rs.git", default-features = fals
|
|||||||
"tcp-transport",
|
"tcp-transport",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
[target.x86_64-unknown-linux-musl.dependencies]
|
|
||||||
openssl = { version = "0.10", features = ["vendored"] }
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ffplayout"
|
name = "ffplayout"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
@ -509,17 +509,17 @@ pub fn gen_source(
|
|||||||
|
|
||||||
warn!("Generate filler with <yellow>{duration:.2}</> seconds length!");
|
warn!("Generate filler with <yellow>{duration:.2}</> seconds length!");
|
||||||
|
|
||||||
let probe = MediaProbe::new(&config.storage.filler_clip);
|
let probe = MediaProbe::new(&config.storage.filler);
|
||||||
|
|
||||||
if config
|
if config
|
||||||
.storage
|
.storage
|
||||||
.filler_clip
|
.filler
|
||||||
.rsplit_once('.')
|
.rsplit_once('.')
|
||||||
.map(|(_, e)| e.to_lowercase())
|
.map(|(_, e)| e.to_lowercase())
|
||||||
.filter(|c| IMAGE_FORMAT.contains(&c.as_str()))
|
.filter(|c| IMAGE_FORMAT.contains(&c.as_str()))
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
node.source = config.storage.filler_clip.clone();
|
node.source = config.storage.filler.clone();
|
||||||
node.cmd = Some(loop_image(&node));
|
node.cmd = Some(loop_image(&node));
|
||||||
node.probe = Some(probe);
|
node.probe = Some(probe);
|
||||||
} else if let Some(length) = probe
|
} else if let Some(length) = probe
|
||||||
@ -529,7 +529,7 @@ pub fn gen_source(
|
|||||||
.and_then(|d| d.parse::<f64>().ok())
|
.and_then(|d| d.parse::<f64>().ok())
|
||||||
{
|
{
|
||||||
// create placeholder from config filler.
|
// create placeholder from config filler.
|
||||||
node.source = config.storage.filler_clip.clone();
|
node.source = config.storage.filler.clone();
|
||||||
node.duration = length;
|
node.duration = length;
|
||||||
node.out = duration;
|
node.out = duration;
|
||||||
node.cmd = Some(loop_filler(&node));
|
node.cmd = Some(loop_filler(&node));
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 3333aa8992e6d571bccf6da4beefc3fbb86c56ff
|
Subproject commit 2f3234221a0aef8e70d9e2b5e9bbfb1fe51921fc
|
@ -13,11 +13,11 @@ chrono = { version = "0.4", default-features = false, features = ["clock", "std"
|
|||||||
crossbeam-channel = "0.5"
|
crossbeam-channel = "0.5"
|
||||||
ffprobe = "0.3"
|
ffprobe = "0.3"
|
||||||
file-rotate = "0.7.0"
|
file-rotate = "0.7.0"
|
||||||
lettre = "0.10"
|
lettre = { version = "0.10", features = ["builder", "rustls-tls", "smtp-transport"], default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
@ -29,6 +29,3 @@ walkdir = "2"
|
|||||||
[target."cfg(windows)".dependencies.winapi]
|
[target."cfg(windows)".dependencies.winapi]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
features = ["shlobj", "std", "winerror"]
|
features = ["shlobj", "std", "winerror"]
|
||||||
|
|
||||||
[target.x86_64-unknown-linux-musl.dependencies]
|
|
||||||
openssl = { version = "0.10", features = ["vendored"] }
|
|
||||||
|
@ -267,7 +267,8 @@ pub struct Storage {
|
|||||||
pub path: String,
|
pub path: String,
|
||||||
#[serde(skip_serializing, skip_deserializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub paths: Vec<String>,
|
pub paths: Vec<String>,
|
||||||
pub filler_clip: String,
|
#[serde(alias = "filler_clip")]
|
||||||
|
pub filler: String,
|
||||||
pub extensions: Vec<String>,
|
pub extensions: Vec<String>,
|
||||||
pub shuffle: bool,
|
pub shuffle: bool,
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ pub fn generate_playlist(
|
|||||||
playlist_file.display()
|
playlist_file.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut filler = Media::new(0, &config.storage.filler_clip, true);
|
let mut filler = Media::new(0, &config.storage.filler, true);
|
||||||
let filler_length = filler.duration;
|
let filler_length = filler.duration;
|
||||||
let mut length = 0.0;
|
let mut length = 0.0;
|
||||||
let mut round = 0;
|
let mut round = 0;
|
||||||
|
@ -13,7 +13,7 @@ use std::{
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use chrono::{prelude::*, Duration};
|
use chrono::{prelude::*, Duration};
|
||||||
use ffprobe::{ffprobe, Format, Stream};
|
use ffprobe::{ffprobe, Format, Stream as FFStream};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::header;
|
use reqwest::header;
|
||||||
@ -205,8 +205,8 @@ fn is_empty_string(st: &String) -> bool {
|
|||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
pub struct MediaProbe {
|
pub struct MediaProbe {
|
||||||
pub format: Option<Format>,
|
pub format: Option<Format>,
|
||||||
pub audio_streams: Vec<Stream>,
|
pub audio_streams: Vec<FFStream>,
|
||||||
pub video_streams: Vec<Stream>,
|
pub video_streams: Vec<FFStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MediaProbe {
|
impl MediaProbe {
|
||||||
|
@ -31,7 +31,7 @@ fn playlist_change_at_midnight() {
|
|||||||
config.playlist.length = "24:00:00".into();
|
config.playlist.length = "24:00:00".into();
|
||||||
config.playlist.length_sec = Some(86400.0);
|
config.playlist.length_sec = Some(86400.0);
|
||||||
config.playlist.path = "assets/playlists".into();
|
config.playlist.path = "assets/playlists".into();
|
||||||
config.storage.filler_clip = "assets/with_audio.mp4".into();
|
config.storage.filler = "assets/with_audio.mp4".into();
|
||||||
config.logging.log_to_file = false;
|
config.logging.log_to_file = false;
|
||||||
config.logging.timestamp = false;
|
config.logging.timestamp = false;
|
||||||
config.out.mode = Null;
|
config.out.mode = Null;
|
||||||
@ -72,7 +72,7 @@ fn playlist_change_at_six() {
|
|||||||
config.playlist.length = "24:00:00".into();
|
config.playlist.length = "24:00:00".into();
|
||||||
config.playlist.length_sec = Some(86400.0);
|
config.playlist.length_sec = Some(86400.0);
|
||||||
config.playlist.path = "assets/playlists".into();
|
config.playlist.path = "assets/playlists".into();
|
||||||
config.storage.filler_clip = "assets/with_audio.mp4".into();
|
config.storage.filler = "assets/with_audio.mp4".into();
|
||||||
config.logging.log_to_file = false;
|
config.logging.log_to_file = false;
|
||||||
config.logging.timestamp = false;
|
config.logging.timestamp = false;
|
||||||
config.out.mode = Null;
|
config.out.mode = Null;
|
||||||
|
Loading…
Reference in New Issue
Block a user