Merge pull request #520 from jb-alvarado/master
support looping clips, fix #507
This commit is contained in:
commit
577b5fc045
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1210,7 +1210,7 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout"
|
||||
version = "0.20.4-beta1"
|
||||
version = "0.20.4-beta2"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@ -1232,7 +1232,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-api"
|
||||
version = "0.20.4-beta1"
|
||||
version = "0.20.4-beta2"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-multipart",
|
||||
@ -1271,7 +1271,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-lib"
|
||||
version = "0.20.4-beta1"
|
||||
version = "0.20.4-beta2"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
@ -3436,7 +3436,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tests"
|
||||
version = "0.20.4-beta1"
|
||||
version = "0.20.4-beta2"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
|
@ -4,7 +4,7 @@ default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.20.4-beta1"
|
||||
version = "0.20.4-beta2"
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/ffplayout/ffplayout"
|
||||
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
||||
|
@ -59,7 +59,8 @@ impl CurrentProgram {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if playlist file got updated, and when yes we reload it and setup everything in place.
|
||||
// Check if there is no current playlist or file got updated,
|
||||
// and when is so load/reload it.
|
||||
fn load_or_update_playlist(&mut self, seek: bool) {
|
||||
let mut get_current = false;
|
||||
let mut reload = false;
|
||||
@ -235,7 +236,7 @@ impl CurrentProgram {
|
||||
.current_list
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if item.begin.unwrap() + item.out - item.seek > time_sec {
|
||||
@ -267,12 +268,12 @@ impl CurrentProgram {
|
||||
|
||||
trace!("Clip from init: {}", node_clone.source);
|
||||
|
||||
// Important! When no manual drop is happen here, lock is still active in handle_list_init
|
||||
drop(nodes);
|
||||
|
||||
node_clone.seek += time_sec
|
||||
- (node_clone.begin.unwrap() - *self.playout_stat.time_shift.lock().unwrap());
|
||||
|
||||
// Important! When no manual drop is happen here, lock is still active in handle_list_init
|
||||
drop(nodes);
|
||||
|
||||
self.current_node = handle_list_init(
|
||||
&self.config,
|
||||
node_clone,
|
||||
@ -285,6 +286,7 @@ impl CurrentProgram {
|
||||
.current_node
|
||||
.source
|
||||
.contains(&self.config.storage.path.to_string_lossy().to_string())
|
||||
|| self.current_node.source.contains("color=c=#121212")
|
||||
{
|
||||
is_filler = true;
|
||||
}
|
||||
@ -392,6 +394,7 @@ impl Iterator for CurrentProgram {
|
||||
let node_list = self.player_control.current_list.lock().unwrap();
|
||||
let node = node_list[index].clone();
|
||||
let last_index = node_list.len() - 1;
|
||||
|
||||
drop(node_list);
|
||||
|
||||
if index == last_index {
|
||||
@ -519,6 +522,39 @@ fn timed_source(
|
||||
new_node
|
||||
}
|
||||
|
||||
fn duplicate_for_seek_and_loop(node: &mut Media, player_control: &PlayerControl) {
|
||||
warn!("Clip loops and has seek value: duplicate clip to separate loop and seek.");
|
||||
let mut nodes = player_control.current_list.lock().unwrap();
|
||||
let index = node.index.unwrap_or_default();
|
||||
|
||||
let mut node_duplicate = node.clone();
|
||||
node_duplicate.seek = 0.0;
|
||||
let orig_seek = node.seek;
|
||||
node.out = node.duration;
|
||||
|
||||
if node.seek > node.duration {
|
||||
node.seek %= node.duration;
|
||||
|
||||
node_duplicate.out = node_duplicate.out - orig_seek - (node.out - node.seek);
|
||||
} else {
|
||||
node_duplicate.out -= node_duplicate.duration;
|
||||
}
|
||||
|
||||
if node.seek == node.out {
|
||||
node.seek = node_duplicate.seek;
|
||||
node.out = node_duplicate.out;
|
||||
} else if node_duplicate.out - node_duplicate.seek > 1.2 {
|
||||
node_duplicate.begin =
|
||||
Some(node_duplicate.begin.unwrap_or_default() + (node.out - node.seek));
|
||||
|
||||
nodes.insert(index + 1, node_duplicate);
|
||||
|
||||
for (i, item) in nodes.iter_mut().enumerate() {
|
||||
item.index = Some(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the source CMD, or when clip not exist, get a dummy.
|
||||
pub fn gen_source(
|
||||
config: &PlayoutConfig,
|
||||
@ -536,9 +572,9 @@ pub fn gen_source(
|
||||
duration = 1.2;
|
||||
|
||||
if node.seek > 1.0 {
|
||||
node.seek -= 1.0;
|
||||
node.seek -= 1.2;
|
||||
} else {
|
||||
node.out += 1.0;
|
||||
node.out = 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,6 +599,10 @@ pub fn gen_source(
|
||||
{
|
||||
node.cmd = Some(loop_image(&node));
|
||||
} else {
|
||||
if node.seek > 0.0 && node.out > node.duration {
|
||||
duplicate_for_seek_and_loop(&mut node, player_control);
|
||||
}
|
||||
|
||||
node.cmd = Some(seek_and_length(&mut node));
|
||||
}
|
||||
} else {
|
||||
@ -580,16 +620,17 @@ pub fn gen_source(
|
||||
Err(e) => error!("Lock filler list error: {e}"),
|
||||
}
|
||||
|
||||
// Set list_init to true, to stay in sync.
|
||||
playout_stat.list_init.store(true, Ordering::SeqCst);
|
||||
|
||||
if config.storage.filler.is_dir() && !filler_list.is_empty() {
|
||||
let filler_index = player_control.filler_index.fetch_add(1, Ordering::SeqCst);
|
||||
let mut filler_media = filler_list[filler_index].clone();
|
||||
|
||||
trace!("take filler: {}", filler_media.source);
|
||||
|
||||
// Set list_init to true, to stay in sync.
|
||||
playout_stat.list_init.store(true, Ordering::SeqCst);
|
||||
|
||||
if filler_index == filler_list.len() - 1 {
|
||||
// reset index for next round
|
||||
player_control.filler_index.store(0, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
@ -700,14 +741,11 @@ fn handle_list_init(
|
||||
) -> Media {
|
||||
debug!("Playlist init");
|
||||
let (_, total_delta) = get_delta(config, &node.begin.unwrap());
|
||||
let mut out = node.out;
|
||||
|
||||
if node.out - node.seek > total_delta {
|
||||
out = total_delta + node.seek;
|
||||
node.out = total_delta + node.seek;
|
||||
}
|
||||
|
||||
node.out = out;
|
||||
|
||||
gen_source(config, node, playout_stat, player_control, last_index)
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
|
||||
}) {
|
||||
enc_cmd.append(&mut cmd);
|
||||
} else {
|
||||
warn!("ffplay does not support given output parameters, they are skipped!");
|
||||
warn!("ffplay doesn't support given output parameters, they will be skipped!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,6 +529,7 @@ pub fn loop_filler(node: &Media) -> Vec<String> {
|
||||
|
||||
/// Set clip seek in and length value.
|
||||
pub fn seek_and_length(node: &mut Media) -> Vec<String> {
|
||||
let loop_count = (node.out / node.duration).ceil() as i32;
|
||||
let mut source_cmd = vec![];
|
||||
let mut cut_audio = false;
|
||||
let mut loop_audio = false;
|
||||
@ -541,9 +542,15 @@ pub fn seek_and_length(node: &mut Media) -> Vec<String> {
|
||||
source_cmd.append(&mut vec_strings!["-ss", node.seek])
|
||||
}
|
||||
|
||||
if loop_count > 1 {
|
||||
info!("Loop <b><magenta>{}</></b> <yellow>{loop_count}</> times, total duration: <yellow>{:.2}</>", node.source, node.out);
|
||||
|
||||
source_cmd.append(&mut vec_strings!["-stream_loop", loop_count]);
|
||||
}
|
||||
|
||||
source_cmd.append(&mut vec_strings!["-i", node.source.clone()]);
|
||||
|
||||
if node.duration > node.out || remote_source {
|
||||
if node.duration > node.out || remote_source || loop_count > 1 {
|
||||
source_cmd.append(&mut vec_strings!["-t", node.out - node.seek]);
|
||||
}
|
||||
|
||||
@ -552,9 +559,9 @@ pub fn seek_and_length(node: &mut Media) -> Vec<String> {
|
||||
source_cmd.append(&mut vec_strings!["-ss", node.seek]);
|
||||
}
|
||||
|
||||
if node.duration_audio > node.duration {
|
||||
if node.duration_audio > node.out {
|
||||
cut_audio = true;
|
||||
} else if node.duration_audio < node.duration {
|
||||
} else if node.duration_audio < node.out {
|
||||
source_cmd.append(&mut vec_strings!["-stream_loop", -1]);
|
||||
loop_audio = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user