save and serialize only relative paths

This commit is contained in:
jb-alvarado 2024-09-11 09:02:40 +02:00
parent dffe68637e
commit 060b6c48d0
11 changed files with 76 additions and 51 deletions

View File

@ -10,7 +10,7 @@
/// `{id}` represent the channel id, and at default is 1.
use std::{
env,
path::PathBuf,
path::{Path, PathBuf},
sync::{atomic::Ordering, Arc, Mutex},
};
@ -659,14 +659,24 @@ async fn get_playout_config(
async fn update_playout_config(
pool: web::Data<Pool<Sqlite>>,
id: web::Path<i32>,
data: web::Json<PlayoutConfig>,
mut data: web::Json<PlayoutConfig>,
controllers: web::Data<Mutex<ChannelController>>,
role: AuthDetails<Role>,
user: web::ReqData<UserMeta>,
) -> Result<impl Responder, ServiceError> {
let manager = controllers.lock().unwrap().get(*id).unwrap();
let p = manager.channel.lock().unwrap().storage_path.clone();
let storage_path = Path::new(&p);
let config_id = manager.config.lock().unwrap().general.id;
let (_, _, logo) = norm_abs_path(&storage_path, &data.processing.logo)?;
let (_, _, filler) = norm_abs_path(&storage_path, &data.storage.filler)?;
let (_, _, font) = norm_abs_path(&storage_path, &data.text.font)?;
data.processing.logo = logo;
data.storage.filler = filler;
data.text.font = font;
handles::update_configuration(&pool, config_id, data.clone()).await?;
let new_config = get_config(&pool, *id).await?;

View File

@ -252,12 +252,12 @@ pub async fn update_configuration(
.bind(config.playlist.day_start)
.bind(config.playlist.length)
.bind(config.playlist.infinit)
.bind(config.storage.filler.to_string_lossy().to_string())
.bind(config.storage.filler)
.bind(config.storage.extensions.join(";"))
.bind(config.storage.shuffle)
.bind(config.text.add_text)
.bind(config.text.text_from_filename)
.bind(config.text.fontfile)
.bind(config.text.font)
.bind(config.text.style)
.bind(config.text.regex)
.bind(config.task.enable)

View File

@ -384,12 +384,12 @@ impl Configuration {
playlist_length: config.playlist.length,
playlist_infinit: config.playlist.infinit,
storage_help: config.storage.help_text,
storage_filler: config.storage.filler.to_string_lossy().to_string(),
storage_filler: config.storage.filler,
storage_extensions: config.storage.extensions.join(";"),
storage_shuffle: config.storage.shuffle,
text_help: config.text.help_text,
text_add: config.text.add_text,
text_font: config.text.fontfile,
text_font: config.text.font,
text_from_filename: config.text.text_from_filename,
text_style: config.text.style,
text_regex: config.text.regex,

View File

@ -355,14 +355,14 @@ fn fade(
fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
if config.processing.add_logo
&& Path::new(&config.processing.logo).is_file()
&& Path::new(&config.processing.logo_path).is_file()
&& &node.category != "advertisement"
{
let mut logo_chain = format!(
"null[v];movie={}:loop=0,setpts=N/(FRAME_RATE*TB),format=rgba,colorchannelmixer=aa={}",
config
.processing
.logo
.logo_path
.replace('\\', "/")
.replace(':', "\\\\:"),
config.processing.logo_opacity,

View File

@ -20,8 +20,8 @@ pub fn filter_node(
let mut filter = String::new();
let mut font = String::new();
if Path::new(&config.text.fontfile).is_file() {
font = format!(":fontfile='{}'", config.text.fontfile)
if Path::new(&config.text.font_path).is_file() {
font = format!(":fontfile='{}'", config.text.font_path)
}
let zmq_socket = match node.map(|n| n.unit) {

View File

@ -669,7 +669,7 @@ pub fn gen_source(
// Set list_init to true, to stay in sync.
manager.list_init.store(true, Ordering::SeqCst);
if config.storage.filler.is_dir() && !fillers.is_empty() {
if config.storage.filler_path.is_dir() && !fillers.is_empty() {
let index = manager.filler_index.fetch_add(1, Ordering::SeqCst);
let mut filler_media = fillers[index].clone();
@ -697,11 +697,11 @@ pub fn gen_source(
node.cmd = Some(loop_filler(&node));
node.probe = filler_media.probe;
} else {
match MediaProbe::new(&config.storage.filler.to_string_lossy()) {
match MediaProbe::new(&config.storage.filler_path.to_string_lossy()) {
Ok(probe) => {
if config
.storage
.filler
.filler_path
.to_string_lossy()
.to_string()
.rsplit_once('.')
@ -709,7 +709,12 @@ pub fn gen_source(
.filter(|c| IMAGE_FORMAT.contains(&c.as_str()))
.is_some()
{
node.source = config.storage.filler.clone().to_string_lossy().to_string();
node.source = config
.storage
.filler_path
.clone()
.to_string_lossy()
.to_string();
node.cmd = Some(loop_image(&node));
node.probe = Some(probe);
} else if let Some(filler_duration) = probe
@ -725,7 +730,12 @@ pub fn gen_source(
filler_out = duration;
}
node.source = config.storage.filler.clone().to_string_lossy().to_string();
node.source = config
.storage
.filler_path
.clone()
.to_string_lossy()
.to_string();
node.seek = 0.0;
node.out = filler_out;
node.duration = filler_duration;

View File

@ -174,10 +174,10 @@ pub fn fill_filler_list(
) -> Vec<Media> {
let id = config.general.channel_id;
let mut filler_list = vec![];
let filler_path = &config.storage.filler;
let filler_path = &config.storage.filler_path;
if filler_path.is_dir() {
for (index, entry) in WalkDir::new(&config.storage.filler)
for (index, entry) in WalkDir::new(&config.storage.filler_path)
.into_iter()
.flat_map(|e| e.ok())
.filter(|f| f.path().is_file())
@ -211,7 +211,7 @@ pub fn fill_filler_list(
f.lock().unwrap().clone_from(&filler_list);
}
} else if filler_path.is_file() {
let mut media = Media::new(0, &config.storage.filler.to_string_lossy(), false);
let mut media = Media::new(0, &config.storage.filler_path.to_string_lossy(), false);
if fillers.is_none() {
if let Err(e) = media.add_probe(false) {

View File

@ -317,6 +317,8 @@ pub struct Processing {
pub fps: f64,
pub add_logo: bool,
pub logo: String,
#[serde(skip_serializing, skip_deserializing)]
pub logo_path: String,
pub logo_scale: String,
pub logo_opacity: f64,
pub logo_position: String,
@ -345,6 +347,7 @@ impl Processing {
fps: config.processing_fps,
add_logo: config.processing_add_logo,
logo: config.processing_logo.clone(),
logo_path: config.processing_logo.clone(),
logo_scale: config.processing_logo_scale.clone(),
logo_opacity: config.processing_logo_opacity,
logo_position: config.processing_logo_position.clone(),
@ -411,7 +414,9 @@ pub struct Storage {
pub path: PathBuf,
#[serde(skip_serializing, skip_deserializing)]
pub paths: Vec<PathBuf>,
pub filler: PathBuf,
pub filler: String,
#[serde(skip_serializing, skip_deserializing)]
pub filler_path: PathBuf,
pub extensions: Vec<String>,
pub shuffle: bool,
#[serde(skip_serializing, skip_deserializing)]
@ -424,7 +429,8 @@ impl Storage {
help_text: config.storage_help.clone(),
path,
paths: vec![],
filler: PathBuf::from(config.storage_filler.clone()),
filler: config.storage_filler.clone(),
filler_path: PathBuf::from(config.storage_filler.clone()),
extensions: config
.storage_extensions
.split(';')
@ -446,7 +452,9 @@ pub struct Text {
pub zmq_stream_socket: Option<String>,
#[serde(skip_serializing, skip_deserializing)]
pub zmq_server_socket: Option<String>,
pub fontfile: String,
pub font: String,
#[serde(skip_serializing, skip_deserializing)]
pub font_path: String,
pub text_from_filename: bool,
pub style: String,
pub regex: String,
@ -460,7 +468,8 @@ impl Text {
node_pos: None,
zmq_stream_socket: None,
zmq_server_socket: None,
fontfile: config.text_font.clone(),
font: config.text_font.clone(),
font_path: config.text_font.clone(),
text_from_filename: config.text_from_filename,
style: config.text_style.clone(),
regex: config.text_regex.clone(),
@ -591,9 +600,11 @@ impl PlayoutConfig {
tokio::fs::create_dir_all(&channel.logging_path).await?;
}
let (filler_path, _, _) = norm_abs_path(&channel.storage_path, &config.storage_filler)?;
let (filler_path, _, filler) =
norm_abs_path(&channel.storage_path, &config.storage_filler)?;
storage.filler = filler_path;
storage.filler = filler;
storage.filler_path = filler_path;
playlist.start_sec = Some(time_to_sec(&playlist.day_start));
@ -603,13 +614,14 @@ impl PlayoutConfig {
playlist.length_sec = Some(86400.0);
}
let (logo_path, _, _) = norm_abs_path(&channel.storage_path, &processing.logo)?;
let (logo_path, _, logo) = norm_abs_path(&channel.storage_path, &processing.logo)?;
if processing.add_logo && !logo_path.is_file() {
processing.add_logo = false;
}
processing.logo = logo_path.to_string_lossy().to_string();
processing.logo = logo;
processing.logo_path = logo_path.to_string_lossy().to_string();
if processing.audio_tracks < 1 {
processing.audio_tracks = 1
@ -715,8 +727,9 @@ impl PlayoutConfig {
text.node_pos = None;
}
let (text_path, _, _) = norm_abs_path(&channel.storage_path, &text.fontfile)?;
text.fontfile = text_path.to_string_lossy().to_string();
let (font_path, _, font) = norm_abs_path(&channel.storage_path, &text.font)?;
text.font = font;
text.font_path = font_path.to_string_lossy().to_string();
Ok(Self {
channel,
@ -735,15 +748,7 @@ impl PlayoutConfig {
}
pub async fn dump(pool: &Pool<Sqlite>, id: i32) -> Result<(), ServiceError> {
let mut config = Self::new(pool, id).await?;
config.storage.filler.clone_from(
&config
.storage
.filler
.strip_prefix(config.channel.storage_path.clone())
.unwrap_or(&config.storage.filler)
.to_path_buf(),
);
let config = Self::new(pool, id).await?;
let toml_string = toml_edit::ser::to_string_pretty(&config)?;
tokio::fs::write(&format!("ffplayout_{id}.toml"), toml_string).await?;

View File

@ -65,15 +65,15 @@ pub fn norm_abs_path(
.normalize()
.to_string()
.replace("../", "");
let mut source_relative = RelativePath::new(input_path)
.normalize()
.to_string()
.replace("../", "");
let path_suffix = root_path
.file_name()
.unwrap_or_default()
.to_string_lossy()
.to_string();
let mut source_relative = RelativePath::new(input_path)
.normalize()
.to_string()
.replace("../", "");
if input_path.starts_with(&*root_path.to_string_lossy())
|| source_relative.starts_with(&path_relative)

@ -1 +1 @@
Subproject commit bb7446850c683c3a4465c336e348476d3c8bb49c
Subproject commit e7afc85243980e060f9d5806f98ea88eff0a17ab

View File

@ -49,7 +49,7 @@ fn video_audio_input() {
config.output.mode = Stream;
config.processing.add_logo = true;
let logo_path = fs::canonicalize("./assets/logo.png").unwrap();
config.processing.logo = logo_path.to_string_lossy().to_string();
config.processing.logo_path = logo_path.to_string_lossy().to_string();
let media_obj = Media::new(0, "./assets/media_mix/with_audio.mp4", true);
let media = gen_source(&config, media_obj, &manager, 1);
@ -57,7 +57,7 @@ fn video_audio_input() {
let test_filter_cmd =
vec_strings![
"-filter_complex",
format!("[0:v:0]scale=1024:576,null[v];movie={}:loop=0,setpts=N/(FRAME_RATE*TB),format=rgba,colorchannelmixer=aa=0.7[l];[v][l]overlay=W-w-12:12:shortest=1[vout0];[0:a:0]anull[aout0]", config.processing.logo)
format!("[0:v:0]scale=1024:576,null[v];movie={}:loop=0,setpts=N/(FRAME_RATE*TB),format=rgba,colorchannelmixer=aa=0.7[l];[v][l]overlay=W-w-12:12:shortest=1[vout0];[0:a:0]anull[aout0]", config.processing.logo_path)
];
let test_filter_map = vec_strings!["-map", "[vout0]", "-map", "[aout0]"];
@ -383,7 +383,7 @@ fn video_audio_filter2_stream() {
config.output.mode = Stream;
config.processing.add_logo = false;
config.text.add_text = true;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_filter = Some("[0:v]gblur=2[vout0];[0:a]volume=0.2[aout0]".to_string());
config.output.output_cmd = Some(vec_strings![
"-map",
@ -467,7 +467,7 @@ fn video_audio_filter3_stream() {
config.output.mode = Stream;
config.processing.add_logo = false;
config.text.add_text = true;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_filter = Some(
"[0:v]null[o];movie=/path/to/lower_third.png[l];[o][l]overlay=shortest=1[vout0]"
.to_string(),
@ -554,7 +554,7 @@ fn video_audio_filter4_stream() {
config.output.mode = Stream;
config.processing.add_logo = false;
config.text.add_text = true;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_filter = Some(
"[0:v]null[o];movie=/path/to/lower_third.png[l];[o][l]overlay=shortest=1[vout0];[0:a:0]volume=0.2[aout0]"
.to_string(),
@ -713,7 +713,7 @@ fn video_dual_audio_filter_stream() {
config.output.mode = Stream;
config.processing.add_logo = false;
config.processing.audio_tracks = 2;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_cmd = Some(vec_strings![
"-c:v",
"libx264",
@ -999,7 +999,7 @@ fn video_audio_text_multi_stream() {
config.output.mode = Stream;
config.processing.add_logo = false;
config.text.add_text = true;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_count = 2;
config.output.output_cmd = Some(vec_strings![
"-c:v",
@ -1114,7 +1114,7 @@ fn video_dual_audio_multi_filter_stream() {
config.processing.add_logo = false;
config.processing.audio_tracks = 2;
config.output.output_count = 2;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_cmd = Some(vec_strings![
"-map",
"0:v",
@ -1244,7 +1244,7 @@ fn video_audio_text_filter_stream() {
config.processing.add_logo = false;
config.processing.audio_tracks = 1;
config.text.add_text = true;
config.text.fontfile = String::new();
config.text.font_path = String::new();
config.output.output_count = 2;
config.output.output_cmd = Some(vec_strings![
"-map",