Merge pull request #747 from jb-alvarado/master
save and serialize only relative paths
This commit is contained in:
commit
3e206a84cb
@ -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?;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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?;
|
||||
|
@ -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)
|
||||
|
2
frontend
2
frontend
@ -1 +1 @@
|
||||
Subproject commit bb7446850c683c3a4465c336e348476d3c8bb49c
|
||||
Subproject commit e7afc85243980e060f9d5806f98ea88eff0a17ab
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user