set internal random port for zmq
This commit is contained in:
parent
c6f81fa8a3
commit
efa6dfa5ea
@ -105,14 +105,10 @@ text:
|
||||
help_text: Overlay text in combination with libzmq for remote text manipulation.
|
||||
On windows fontfile path need to be like this 'C\:/WINDOWS/fonts/DejaVuSans.ttf'.
|
||||
In a standard environment the filter drawtext node is Parsed_drawtext_2.
|
||||
'over_pre' if True text will be overlay in pre processing. Continue same text
|
||||
over multiple files is in that mode not possible. 'text_from_filename' activate the
|
||||
extraction from text of a filename. With 'style' you can define the drawtext
|
||||
parameters like position, color, etc. Post Text over API will override this.
|
||||
With 'regex' you can format file names, to get a title from it.
|
||||
'text_from_filename' activate the extraction from text of a filename. With 'style'
|
||||
you can define the drawtext parameters like position, color, etc. Post Text over
|
||||
API will override this. With 'regex' you can format file names, to get a title from it.
|
||||
add_text: false
|
||||
over_pre: false
|
||||
bind_address: "127.0.0.1:5555"
|
||||
fontfile: "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
|
||||
text_from_filename: false
|
||||
style: "x=(w-tw)/2:y=(h-line_h)*0.9:fontsize=24:fontcolor=#ffffff:box=1:boxcolor=#000000:boxborderw=4"
|
||||
|
@ -184,7 +184,9 @@ fn extend_video(node: &mut Media, chain: &mut Filters) {
|
||||
|
||||
/// add drawtext filter for lower thirds messages
|
||||
fn add_text(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
||||
if config.text.add_text && config.text.over_pre {
|
||||
if config.text.add_text
|
||||
&& (config.text.text_from_filename || config.out.mode.to_lowercase() == "hls")
|
||||
{
|
||||
let filter = v_drawtext::filter_node(config, node);
|
||||
|
||||
chain.add_filter(&filter, "video");
|
||||
|
@ -4,7 +4,7 @@ use regex::Regex;
|
||||
|
||||
use crate::utils::{Media, PlayoutConfig};
|
||||
|
||||
pub fn filter_node(config: &PlayoutConfig, node: &mut Media) -> String {
|
||||
pub fn filter_node(config: &PlayoutConfig, node: &Media) -> String {
|
||||
let mut filter = String::new();
|
||||
let mut font = String::new();
|
||||
|
||||
@ -13,7 +13,7 @@ pub fn filter_node(config: &PlayoutConfig, node: &mut Media) -> String {
|
||||
font = format!(":fontfile='{}'", config.text.fontfile)
|
||||
}
|
||||
|
||||
if config.text.over_pre && config.text.text_from_filename {
|
||||
if config.text.text_from_filename {
|
||||
let source = node.source.clone();
|
||||
let regex: Regex = Regex::new(&config.text.regex).unwrap();
|
||||
|
||||
@ -27,10 +27,10 @@ pub fn filter_node(config: &PlayoutConfig, node: &mut Media) -> String {
|
||||
.replace('%', "\\\\\\%")
|
||||
.replace(':', "\\:");
|
||||
filter = format!("drawtext=text='{escape}':{}{font}", config.text.style)
|
||||
} else {
|
||||
} else if let Some(socket) = config.text.bind_address.clone() {
|
||||
filter = format!(
|
||||
"zmq=b=tcp\\\\://'{}',drawtext=text=''{font}",
|
||||
config.text.bind_address.replace(':', "\\:")
|
||||
socket.replace(':', "\\:")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -14,17 +14,19 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
|
||||
|
||||
let mut enc_cmd = vec_strings!["-hide_banner", "-nostats", "-v", log_format, "-i", "pipe:0"];
|
||||
|
||||
if config.text.add_text && !config.text.over_pre {
|
||||
info!(
|
||||
"Using drawtext filter, listening on address: <yellow>{}</>",
|
||||
config.text.bind_address
|
||||
);
|
||||
if config.text.add_text && !config.text.text_from_filename {
|
||||
if let Some(socket) = config.text.bind_address.clone() {
|
||||
debug!(
|
||||
"Using drawtext filter, listening on address: <yellow>{}</>",
|
||||
socket
|
||||
);
|
||||
|
||||
let mut filter: String = "null,".to_string();
|
||||
filter.push_str(
|
||||
v_drawtext::filter_node(config, &mut Media::new(0, String::new(), false)).as_str(),
|
||||
);
|
||||
enc_filter = vec!["-vf".to_string(), filter];
|
||||
let mut filter: String = "null,".to_string();
|
||||
filter.push_str(
|
||||
v_drawtext::filter_node(config, &Media::new(0, String::new(), false)).as_str(),
|
||||
);
|
||||
enc_filter = vec!["-vf".to_string(), filter];
|
||||
}
|
||||
}
|
||||
|
||||
enc_cmd.append(&mut enc_filter);
|
||||
|
@ -13,7 +13,7 @@ out:
|
||||
-hls_time 6
|
||||
-hls_list_size 600
|
||||
-hls_flags append_list+delete_segments+omit_endlist+program_date_time
|
||||
-hls_segment_filename /var/www/html/live/stream-%09d.ts /var/www/html/live/stream.m3u8
|
||||
-hls_segment_filename /var/www/html/live/stream-%d.ts /var/www/html/live/stream.m3u8
|
||||
|
||||
*/
|
||||
|
||||
|
@ -25,19 +25,21 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
|
||||
"pipe:0"
|
||||
];
|
||||
|
||||
if config.text.add_text && !config.text.over_pre {
|
||||
info!(
|
||||
"Using drawtext filter, listening on address: <yellow>{}</>",
|
||||
config.text.bind_address
|
||||
);
|
||||
if config.text.add_text && !config.text.text_from_filename {
|
||||
if let Some(socket) = config.text.bind_address.clone() {
|
||||
debug!(
|
||||
"Using drawtext filter, listening on address: <yellow>{}</>",
|
||||
socket
|
||||
);
|
||||
|
||||
let mut filter = "[0:v]null,".to_string();
|
||||
let mut filter = "[0:v]null,".to_string();
|
||||
|
||||
filter.push_str(
|
||||
v_drawtext::filter_node(config, &mut Media::new(0, String::new(), false)).as_str(),
|
||||
);
|
||||
filter.push_str(
|
||||
v_drawtext::filter_node(config, &Media::new(0, String::new(), false)).as_str(),
|
||||
);
|
||||
|
||||
enc_filter = vec!["-filter_complex".to_string(), filter];
|
||||
enc_filter = vec!["-filter_complex".to_string(), filter];
|
||||
}
|
||||
}
|
||||
|
||||
if config.out.preview {
|
||||
|
@ -8,7 +8,7 @@ use std::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shlex::split;
|
||||
|
||||
use crate::utils::{time_to_sec, Args};
|
||||
use crate::utils::{free_tcp_socket, time_to_sec, Args};
|
||||
use crate::vec_strings;
|
||||
|
||||
/// Global Config
|
||||
@ -137,8 +137,13 @@ pub struct Storage {
|
||||
pub struct Text {
|
||||
pub help_text: String,
|
||||
pub add_text: bool,
|
||||
pub over_pre: bool,
|
||||
pub bind_address: String,
|
||||
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
pub bind_address: Option<String>,
|
||||
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
pub node_pos: Option<usize>,
|
||||
|
||||
pub fontfile: String,
|
||||
pub text_from_filename: bool,
|
||||
pub style: String,
|
||||
@ -243,6 +248,17 @@ impl PlayoutConfig {
|
||||
config.out.preview_cmd = split(config.out.preview_param.as_str());
|
||||
config.out.output_cmd = split(config.out.output_param.as_str());
|
||||
|
||||
// when text overlay without text_from_filename is on, turn also the RPC server on,
|
||||
// to get text messages from it
|
||||
if config.text.add_text && !config.text.text_from_filename {
|
||||
config.rpc_server.enable = true;
|
||||
config.text.bind_address = free_tcp_socket();
|
||||
config.text.node_pos = Some(2);
|
||||
} else {
|
||||
config.text.bind_address = None;
|
||||
config.text.node_pos = None;
|
||||
}
|
||||
|
||||
// Read command line arguments, and override the config with them.
|
||||
|
||||
if let Some(arg) = args {
|
||||
|
@ -142,7 +142,7 @@ pub fn read_json(
|
||||
return set_defaults(playlist, current_file, start_sec);
|
||||
}
|
||||
|
||||
error!("Read playlist error, on: <b><magenta>{current_file}</></b>!");
|
||||
error!("Read playlist error, on: <b><magenta>{current_file}</></b>");
|
||||
|
||||
JsonPlaylist::new(date, start_sec)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
fs::{self, metadata},
|
||||
io::{BufRead, BufReader, Error},
|
||||
net::TcpListener,
|
||||
path::Path,
|
||||
process::{exit, ChildStderr, Command, Stdio},
|
||||
time::{self, UNIX_EPOCH},
|
||||
@ -9,6 +10,7 @@ use std::{
|
||||
use chrono::{prelude::*, Duration};
|
||||
use ffprobe::{ffprobe, Format, Stream};
|
||||
use jsonrpc_http_server::hyper::HeaderMap;
|
||||
use rand::prelude::*;
|
||||
use regex::Regex;
|
||||
use reqwest::header;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -596,6 +598,19 @@ pub fn validate_ffmpeg(config: &PlayoutConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
/// get a free tcp socket
|
||||
pub fn free_tcp_socket() -> Option<String> {
|
||||
for _ in 0..100 {
|
||||
let port = rand::thread_rng().gen_range(45321..54268);
|
||||
|
||||
if TcpListener::bind(("127.0.0.1", port)).is_ok() {
|
||||
return Some(format!("127.0.0.1:{port}"));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Get system time, in non test case.
|
||||
#[cfg(not(test))]
|
||||
pub fn time_now() -> DateTime<Local> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user