From 7b021883bce96d42b796cf09c273c949486574d4 Mon Sep 17 00:00:00 2001 From: Jonathan Baecker Date: Sun, 29 Sep 2024 16:56:19 +0200 Subject: [PATCH 1/6] set channel active on start --- engine/src/api/routes.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/src/api/routes.rs b/engine/src/api/routes.rs index f3bfbdf7..ee41cf55 100644 --- a/engine/src/api/routes.rs +++ b/engine/src/api/routes.rs @@ -955,6 +955,7 @@ pub async fn process_control( } } ProcessCtl::Start => { + manager.channel.lock().unwrap().active = true; manager.async_start().await; } ProcessCtl::Stop => { From baf25c20932c58736d9e931e9e89151c69629595 Mon Sep 17 00:00:00 2001 From: Jonathan Baecker Date: Sun, 29 Sep 2024 16:56:48 +0200 Subject: [PATCH 2/6] delete also vtt files --- engine/src/player/controller.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/engine/src/player/controller.rs b/engine/src/player/controller.rs index 3faa1667..17c1db8c 100644 --- a/engine/src/player/controller.rs +++ b/engine/src/player/controller.rs @@ -392,7 +392,11 @@ fn delete_ts + Clone + std::fmt::Debug>( ) -> io::Result<()> { let ts_file = params .iter() - .filter(|f| f.to_lowercase().ends_with(".ts") || f.to_lowercase().ends_with(".m3u8")) + .filter(|f| { + f.to_lowercase().ends_with(".ts") + || f.to_lowercase().ends_with(".m3u8") + || f.to_lowercase().ends_with(".vtt") + }) .collect::>(); for entry in WalkDir::new(path.clone()) From fc9ffd149b5955f44d537a982f3fcc5fd5e5b146 Mon Sep 17 00:00:00 2001 From: Jonathan Baecker Date: Sun, 29 Sep 2024 16:57:28 +0200 Subject: [PATCH 3/6] add more error messages to know whats happen --- engine/src/player/input/ingest.rs | 1 + engine/src/player/utils/mod.rs | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/engine/src/player/input/ingest.rs b/engine/src/player/input/ingest.rs index 2b1649aa..d3d0a191 100644 --- a/engine/src/player/input/ingest.rs +++ b/engine/src/player/input/ingest.rs @@ -47,6 +47,7 @@ fn server_monitor( .iter() .any(|i| line.contains(*i)) { + error!(target: Target::file_mail(), channel = id; "Hit unrecoverable error!"); channel_mgr.channel.lock().unwrap().active = false; channel_mgr.stop_all(); } diff --git a/engine/src/player/utils/mod.rs b/engine/src/player/utils/mod.rs index ae16356e..b17adfac 100644 --- a/engine/src/player/utils/mod.rs +++ b/engine/src/player/utils/mod.rs @@ -638,6 +638,8 @@ pub fn loop_image(config: &PlayoutConfig, node: &Media) -> Vec { ]); } else if vtt_dummy.is_file() { source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]); + } else { + error!("WebVTT enabled, but no vtt or dummy file found!"); } } @@ -677,6 +679,8 @@ pub fn loop_filler(config: &PlayoutConfig, node: &Media) -> Vec { ]); } else if vtt_dummy.is_file() { source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]); + } else { + error!("WebVTT enabled, but no vtt or dummy file found!"); } } @@ -789,6 +793,8 @@ pub fn gen_dummy(config: &PlayoutConfig, duration: f64) -> (String, Vec) if vtt_dummy.is_file() { source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]); + } else { + error!("WebVTT enabled, but no vtt or dummy file found!"); } } @@ -906,6 +912,7 @@ pub fn stderr_reader( || (line.contains("No such file or directory") && !line.contains("failed to delete old segment")) { + error!(target: Target::file_mail(), channel = id; "Hit unrecoverable error!"); manager.channel.lock().unwrap().active = false; manager.stop_all(); } From 57310cd0a3f04d98b855e5e95d3cb15aa3b41d7b Mon Sep 17 00:00:00 2001 From: Jonathan Baecker Date: Sun, 29 Sep 2024 16:58:36 +0200 Subject: [PATCH 4/6] reorder process stop to prevent out of sync, fix #735 --- engine/src/utils/control.rs | 86 +++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/engine/src/utils/control.rs b/engine/src/utils/control.rs index 3fafc859..70cb39cb 100644 --- a/engine/src/utils/control.rs +++ b/engine/src/utils/control.rs @@ -145,6 +145,22 @@ pub async fn control_state( match command { "back" => { if index > 1 && current_list.len() > 1 { + let mut data_map = Map::new(); + let mut media = current_list[index - 2].clone(); + let (delta, _) = get_delta(&config, &media.begin.unwrap_or(0.0)); + + info!(target: Target::file_mail(), channel = id; "Move to last clip"); + + manager.current_index.fetch_sub(2, Ordering::SeqCst); + + if let Err(e) = media.add_probe(false) { + error!(target: Target::file_mail(), channel = id; "{e:?}"); + }; + + manager.channel.lock().unwrap().time_shift = delta; + date.clone_from(¤t_date); + handles::update_stat(conn, config.general.channel_id, current_date, delta).await?; + if let Some(proc) = manager.decoder.lock().unwrap().as_mut() { if let Err(e) = proc.kill() { error!(target: Target::file_mail(), channel = id; "Decoder {e:?}") @@ -157,20 +173,6 @@ pub async fn control_state( return Err(ServiceError::InternalServerError); } - info!(target: Target::file_mail(), channel = id; "Move to last clip"); - let mut data_map = Map::new(); - let mut media = current_list[index - 2].clone(); - manager.current_index.fetch_sub(2, Ordering::SeqCst); - - if let Err(e) = media.add_probe(false) { - error!(target: Target::file_mail(), channel = id; "{e:?}"); - }; - - let (delta, _) = get_delta(&config, &media.begin.unwrap_or(0.0)); - manager.channel.lock().unwrap().time_shift = delta; - date.clone_from(¤t_date); - handles::update_stat(conn, config.general.channel_id, current_date, delta).await?; - data_map.insert("operation".to_string(), json!("move_to_last")); data_map.insert("shifted_seconds".to_string(), json!(delta)); data_map.insert("media".to_string(), get_media_map(media)); @@ -181,6 +183,20 @@ pub async fn control_state( "next" => { if index < current_list.len() { + let mut data_map = Map::new(); + let mut media = current_list[index].clone(); + let (delta, _) = get_delta(&config, &media.begin.unwrap_or(0.0)); + + info!(target: Target::file_mail(), channel = id; "Move to next clip"); + + if let Err(e) = media.add_probe(false) { + error!(target: Target::file_mail(), channel = id; "{e:?}"); + }; + + manager.channel.lock().unwrap().time_shift = delta; + date.clone_from(¤t_date); + handles::update_stat(conn, config.general.channel_id, current_date, delta).await?; + if let Some(proc) = manager.decoder.lock().unwrap().as_mut() { if let Err(e) = proc.kill() { error!(target: Target::file_mail(), channel = id; "Decoder {e:?}") @@ -193,20 +209,6 @@ pub async fn control_state( return Err(ServiceError::InternalServerError); } - info!(target: Target::file_mail(), channel = id; "Move to next clip"); - - let mut data_map = Map::new(); - let mut media = current_list[index].clone(); - - if let Err(e) = media.add_probe(false) { - error!(target: Target::file_mail(), channel = id; "{e:?}"); - }; - - let (delta, _) = get_delta(&config, &media.begin.unwrap_or(0.0)); - manager.channel.lock().unwrap().time_shift = delta; - date.clone_from(¤t_date); - handles::update_stat(conn, config.general.channel_id, current_date, delta).await?; - data_map.insert("operation".to_string(), json!("move_to_next")); data_map.insert("shifted_seconds".to_string(), json!(delta)); data_map.insert("media".to_string(), get_media_map(media)); @@ -216,6 +218,16 @@ pub async fn control_state( } "reset" => { + let mut data_map = Map::new(); + + info!(target: Target::file_mail(), channel = id; "Reset playout to original state"); + + manager.channel.lock().unwrap().time_shift = 0.0; + date.clone_from(¤t_date); + manager.list_init.store(true, Ordering::SeqCst); + + handles::update_stat(conn, config.general.channel_id, current_date, 0.0).await?; + if let Some(proc) = manager.decoder.lock().unwrap().as_mut() { if let Err(e) = proc.kill() { error!(target: Target::file_mail(), channel = id; "Decoder {e:?}") @@ -228,29 +240,11 @@ pub async fn control_state( return Err(ServiceError::InternalServerError); } - info!(target: Target::file_mail(), channel = id; "Reset playout to original state"); - let mut data_map = Map::new(); - manager.channel.lock().unwrap().time_shift = 0.0; - date.clone_from(¤t_date); - manager.list_init.store(true, Ordering::SeqCst); - - handles::update_stat(conn, config.general.channel_id, current_date, 0.0).await?; - data_map.insert("operation".to_string(), json!("reset_playout_state")); return Ok(data_map); } - "stop_all" => { - manager.channel.lock().unwrap().active = false; - manager.stop_all(); - - let mut data_map = Map::new(); - data_map.insert("message".to_string(), json!("Stop playout!")); - - return Ok(data_map); - } - _ => { return Err(ServiceError::ServiceUnavailable( "Command not found!".to_string(), From 230a31b045fca776f3417e9f210d675ca7e7c522 Mon Sep 17 00:00:00 2001 From: Jonathan Baecker Date: Sun, 29 Sep 2024 16:59:09 +0200 Subject: [PATCH 5/6] scroll only config div, cleanup classes --- frontend/components/PlaylistTable.vue | 18 ++++++++-------- frontend/pages/configure.vue | 30 ++++++++++++++------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/frontend/components/PlaylistTable.vue b/frontend/components/PlaylistTable.vue index 6eb3c7c3..a546a7fa 100644 --- a/frontend/components/PlaylistTable.vue +++ b/frontend/components/PlaylistTable.vue @@ -11,47 +11,47 @@ -
+
{{ t('player.start') }}
-
+
{{ t('player.file') }}
-
+
{{ t('player.play') }}
-
+
{{ t('player.duration') }}
-
+
{{ t('player.in') }}
-
+
{{ t('player.out') }}
-
+
{{ t('player.ad') }}
-
+
{{ t('player.edit') }}
-
+
{{ t('player.delete') }}
diff --git a/frontend/pages/configure.vue b/frontend/pages/configure.vue index 9ab7d618..120be6f4 100644 --- a/frontend/pages/configure.vue +++ b/frontend/pages/configure.vue @@ -1,5 +1,5 @@