Skip to content

Commit

Permalink
integrate webvtt subtitles
Browse files Browse the repository at this point in the history
  • Loading branch information
jb-alvarado committed Sep 25, 2024
1 parent 1d4cdfa commit 5061f21
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@
"canonicalize",
"ffpengine",
"flexi",
"httpauth",
"lettre",
"libc",
"neli",
"nuxt",
"paris",
"Referer",
"reqwest",
"rsplit",
"rustls",
Expand Down
12 changes: 12 additions & 0 deletions engine/src/player/input/ingest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,30 @@ pub fn ingest_server(
dummy_media.add_filter(&config, &None);
let is_terminated = channel_mgr.is_terminated.clone();
let ingest_is_running = channel_mgr.ingest_is_running.clone();
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if let Some(ingest_input_cmd) = config.advanced.ingest.input_cmd {
server_cmd.append(&mut ingest_input_cmd.clone());
}

server_cmd.append(&mut stream_input.clone());

if config.processing.vtt_enable && vtt_dummy.is_file() {
server_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}

if let Some(mut filter) = dummy_media.filter {
server_cmd.append(&mut filter.cmd());
server_cmd.append(&mut filter.map());
}

if config.processing.vtt_enable && vtt_dummy.is_file() {
server_cmd.append(&mut vec_strings!("-map", "1:s"));
}

if let Some(mut cmd) = config.processing.cmd {
server_cmd.append(&mut cmd);
}
Expand Down
10 changes: 5 additions & 5 deletions engine/src/player/input/playlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,14 +640,14 @@ pub fn gen_source(
.filter(|c| IMAGE_FORMAT.contains(&c.as_str()))
.is_some()
{
node.cmd = Some(loop_image(&node));
node.cmd = Some(loop_image(&config, &node));
} else {
if node.seek > 0.0 && node.out > node.duration {
warn!(target: Target::file_mail(), channel = config.general.channel_id; "Clip loops and has seek value: duplicate clip to separate loop and seek.");
duplicate_for_seek_and_loop(&mut node, &manager.current_list);
}

node.cmd = Some(seek_and_length(&mut node));
node.cmd = Some(seek_and_length(&config, &mut node));
}
} else {
trace!("clip index: {node_index} | last index: {last_index}");
Expand Down Expand Up @@ -694,7 +694,7 @@ pub fn gen_source(
node.seek = 0.0;
node.out = filler_media.out;
node.duration = filler_media.duration;
node.cmd = Some(loop_filler(&node));
node.cmd = Some(loop_filler(&config, &node));
node.probe = filler_media.probe;
} else {
match MediaProbe::new(&config.storage.filler_path.to_string_lossy()) {
Expand All @@ -715,7 +715,7 @@ pub fn gen_source(
.clone()
.to_string_lossy()
.to_string();
node.cmd = Some(loop_image(&node));
node.cmd = Some(loop_image(&config, &node));
node.probe = Some(probe);
} else if let Some(filler_duration) = probe
.clone()
Expand All @@ -739,7 +739,7 @@ pub fn gen_source(
node.seek = 0.0;
node.out = filler_out;
node.duration = filler_duration;
node.cmd = Some(loop_filler(&node));
node.cmd = Some(loop_filler(&config, &node));
node.probe = Some(probe);
} else {
// Create colored placeholder.
Expand Down
11 changes: 11 additions & 0 deletions engine/src/player/output/hls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ fn ingest_to_hls_server(manager: ChannelManager) -> Result<(), ProcessError> {

server_prefix.append(&mut stream_input.clone());

if config.processing.vtt_enable {
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if vtt_dummy.is_file() {
server_prefix.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}
}

let mut is_running;

if let Some(url) = stream_input.iter().find(|s| s.contains("://")) {
Expand Down
8 changes: 8 additions & 0 deletions engine/src/player/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ pub fn player(manager: ChannelManager) -> Result<(), ProcessError> {
dec_cmd.append(&mut filter.map());
}

if config.processing.vtt_enable && dec_cmd.iter().any(|s| s.ends_with(".vtt")) {
let mut i = dec_cmd.iter().filter(|&n| &*n == "-i").count();
if i > 0 {
i -= 1
}
dec_cmd.append(&mut vec_strings!("-map", format!("{i}:s"), "-c:s", "copy"));
}

if let Some(mut cmd) = config.processing.cmd.clone() {
dec_cmd.append(&mut cmd);
}
Expand Down
4 changes: 2 additions & 2 deletions engine/src/player/utils/json_validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ fn check_media(
.filter(|c| IMAGE_FORMAT.contains(&c.as_str()))
.is_some()
{
node.cmd = Some(loop_image(&node));
node.cmd = Some(loop_image(&config, &node));
} else {
node.cmd = Some(seek_and_length(&mut node));
node.cmd = Some(seek_and_length(&config, &mut node));
}

node.add_filter(&config, &None);
Expand Down
98 changes: 93 additions & 5 deletions engine/src/player/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ pub fn prepare_output_cmd(
let mut new_params = vec![];
let mut count = 0;
let re_v = Regex::new(r"\[?0:v(:0)?\]?").unwrap();
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if let Some(mut filter) = filters.clone() {
for (i, param) in output_params.iter().enumerate() {
Expand Down Expand Up @@ -119,6 +123,15 @@ pub fn prepare_output_cmd(
}
}

if config.processing.vtt_enable && vtt_dummy.is_file() {
let mut i = cmd.iter().filter(|&n| &*n == "-i").count();
if i > 0 {
i -= 1
}

cmd.append(&mut vec_strings!("-map", format!("{i}:s?")));
}

cmd.append(&mut output_params);

cmd
Expand Down Expand Up @@ -589,7 +602,7 @@ pub fn get_delta(config: &PlayoutConfig, begin: &f64) -> (f64, f64) {
}

/// Loop image until target duration is reached.
pub fn loop_image(node: &Media) -> Vec<String> {
pub fn loop_image(config: &PlayoutConfig, node: &Media) -> Vec<String> {
let duration = node.out - node.seek;
let mut source_cmd: Vec<String> = vec_strings!["-loop", "1", "-i", node.source.clone()];

Expand All @@ -608,11 +621,30 @@ pub fn loop_image(node: &Media) -> Vec<String> {

source_cmd.append(&mut vec_strings!["-t", duration]);

if config.processing.vtt_enable {
let vtt_file = Path::new(&node.source).with_extension("vtt");
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if vtt_file.is_file() {
source_cmd.append(&mut vec_strings![
"-i",
vtt_file.to_string_lossy(),
"-t",
node.out
]);
} else if vtt_dummy.is_file() {
source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}
}

source_cmd
}

/// Loop filler until target duration is reached.
pub fn loop_filler(node: &Media) -> Vec<String> {
pub fn loop_filler(config: &PlayoutConfig, node: &Media) -> Vec<String> {
let loop_count = (node.out / node.duration).ceil() as i32;
let mut source_cmd = vec![];

Expand All @@ -624,11 +656,34 @@ pub fn loop_filler(node: &Media) -> Vec<String> {

source_cmd.append(&mut vec_strings!["-i", node.source, "-t", node.out]);

if config.processing.vtt_enable {
let vtt_file = Path::new(&node.source).with_extension("vtt");
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if vtt_file.is_file() {
if loop_count > 1 {
source_cmd.append(&mut vec_strings!["-stream_loop", loop_count]);
}

source_cmd.append(&mut vec_strings![
"-i",
vtt_file.to_string_lossy(),
"-t",
node.out
]);
} else if vtt_dummy.is_file() {
source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}
}

source_cmd
}

/// Set clip seek in and length value.
pub fn seek_and_length(node: &mut Media) -> Vec<String> {
pub fn seek_and_length(config: &PlayoutConfig, 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;
Expand Down Expand Up @@ -673,6 +728,28 @@ pub fn seek_and_length(node: &mut Media) -> Vec<String> {
}
}

if config.processing.vtt_enable {
let vtt_file = Path::new(&node.source).with_extension("vtt");
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if vtt_file.is_file() {
if loop_count > 1 {
source_cmd.append(&mut vec_strings!["-stream_loop", loop_count]);
}

source_cmd.append(&mut vec_strings!["-i", vtt_file.to_string_lossy()]);

if node.duration > node.out || remote_source || loop_count > 1 {
source_cmd.append(&mut vec_strings!["-t", node.out - node.seek]);
}
} else if vtt_dummy.is_file() {
source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}
}

source_cmd
}

Expand All @@ -683,7 +760,7 @@ pub fn gen_dummy(config: &PlayoutConfig, duration: f64) -> (String, Vec<String>)
"color=c={color}:s={}x{}:d={duration}",
config.processing.width, config.processing.height
);
let cmd: Vec<String> = vec_strings![
let mut source_cmd: Vec<String> = vec_strings![
"-f",
"lavfi",
"-i",
Expand All @@ -697,7 +774,18 @@ pub fn gen_dummy(config: &PlayoutConfig, duration: f64) -> (String, Vec<String>)
format!("anoisesrc=d={duration}:c=pink:r=48000:a=0.3")
];

(source, cmd)
if config.processing.vtt_enable {
let vtt_dummy = config
.channel
.storage_path
.join(&config.processing.vtt_dummy.clone().unwrap_or_default());

if vtt_dummy.is_file() {
source_cmd.append(&mut vec_strings!["-i", vtt_dummy.to_string_lossy()]);
}
}

(source, source_cmd)
}

// fn get_output_count(cmd: &[String]) -> i32 {
Expand Down

0 comments on commit 5061f21

Please sign in to comment.