add doc for advanced settings, add separate fade filter for audio, support advanced parameter for stream mode
This commit is contained in:
parent
4dee46857c
commit
b85be0cb82
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1217,7 +1217,7 @@ checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout"
|
||||
version = "0.21.0-beta2"
|
||||
version = "0.21.0-beta3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@ -1239,7 +1239,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-api"
|
||||
version = "0.21.0-beta2"
|
||||
version = "0.21.0-beta3"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-multipart",
|
||||
@ -1278,7 +1278,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-lib"
|
||||
version = "0.21.0-beta2"
|
||||
version = "0.21.0-beta3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
@ -3458,7 +3458,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tests"
|
||||
version = "0.21.0-beta2"
|
||||
version = "0.21.0-beta3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
|
@ -4,7 +4,7 @@ default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.21.0-beta2"
|
||||
version = "0.21.0-beta3"
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/ffplayout/ffplayout"
|
||||
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
||||
|
@ -48,3 +48,5 @@ Control the engine, playlist and config with a ~REST API
|
||||
### **[Stream Copy](/docs/stream_copy.md)**
|
||||
|
||||
Copy audio and or video stream
|
||||
|
||||
### **[Advanced Settings](/docs/advanced_settings.md)**
|
||||
|
57
docs/advanced_settings.md
Normal file
57
docs/advanced_settings.md
Normal file
@ -0,0 +1,57 @@
|
||||
## Advanced settings
|
||||
|
||||
Within **/etc/ffplayout/advanced.yml** you can control all ffmpeg inputs/decoder output and filters.
|
||||
|
||||
> **_Note:_** Changing these settings is for advanced users only! There will be no support or guarantee that it will work and be stable after changing them!
|
||||
|
||||
For changing this settings you need to have knowledge about hardware encoding with ffmpeg. Good starting points are:
|
||||
|
||||
- [HWAccelIntro](https://trac.ffmpeg.org/wiki/HWAccelIntro)
|
||||
- [VAAPI](https://trac.ffmpeg.org/wiki/Hardware/VAAPI)
|
||||
- [QuickSync](https://trac.ffmpeg.org/wiki/Hardware/QuickSync)
|
||||
|
||||
### Example config
|
||||
|
||||
Here an example with Intel QuickSync:
|
||||
|
||||
```YAML
|
||||
help: Changing these settings is for advanced users only! There will be no support or guarantee that ffplayout will be stable after changing them.
|
||||
decoder:
|
||||
input_param: -hwaccel qsv -init_hw_device qsv=hw -filter_hw_device hw -hwaccel_output_format qsv
|
||||
# output_param get also applied to ingest instance.
|
||||
output_param: -c:v mpeg2_qsv -g 1 -b:v 50000k -minrate 50000k -maxrate 50000k -bufsize 25000k -c:a s302m -strict -2 -sample_fmt s16 -ar 48000 -ac 2
|
||||
filters:
|
||||
deinterlace: deinterlace_qsv
|
||||
pad_scale_w: scale_qsv={}:-1,
|
||||
pad_scale_h: scale_qsv=-1:{},
|
||||
pad_video: 'null' # 'pad=max(iw\\,ih*({0}/{1})):ow/({0}/{1}):(ow-iw)/2:(oh-ih)/2'
|
||||
fps: vpp_qsv=framerate=25
|
||||
scale: scale_qsv={}:{}
|
||||
set_dar: 'null' # setdar=dar={}
|
||||
fade_in: 'null' # fade=in:st=0:d=0.5
|
||||
fade_out: 'null' # fade=out:st={}:d=1.0
|
||||
overlay_logo_scale: 'scale_qsv={}'
|
||||
overlay_logo: null[v];movie={}:loop=0,setpts=N/(FRAME_RATE*TB),format=rgba,colorchannelmixer=aa={}{},hwupload=extra_hw_frames=64,format=qsv[l];[v][l]overlay_qsv={}:shortest=1
|
||||
overlay_logo_fade_in: 'null' # ',fade=in:st=0:d=1.0:alpha=1'
|
||||
overlay_logo_fade_out: 'null' # ',fade=out:st={}:d=1.0:alpha=1'
|
||||
tpad: 'null' # tpad=stop_mode=add:stop_duration={}
|
||||
drawtext_from_file: hwdownload,format=nv12,drawtext=text='{}':{}{} # drawtext=text='{}':{}{}
|
||||
drawtext_from_zmq: hwdownload,format=nv12,zmq=b=tcp\\://'{}',drawtext@dyntext={} # zmq=b=tcp\\\\://'{}',drawtext@dyntext={}
|
||||
aevalsrc: # aevalsrc=0:channel_layout=stereo:duration={}:sample_rate=48000
|
||||
afade_in: # afade=in:st=0:d=0.5
|
||||
afade_out: # afade=out:st={}:d=1.0
|
||||
apad: # apad=whole_dur={}
|
||||
volume: # volume={}
|
||||
split: # split={}{}
|
||||
encoder:
|
||||
# use `-hwaccel vulkan` when output mode is desktop
|
||||
input_param: -hwaccel qsv -init_hw_device qsv=hw -filter_hw_device hw -hwaccel_output_format qsv
|
||||
ingest:
|
||||
input_param: -hwaccel qsv -init_hw_device qsv=hw -filter_hw_device hw -hwaccel_output_format qsv
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**At the moment this function is _experimental_, if you think you found a bug: check full decoder/encoder/ingest command with ffmpeg in terminal. When there the command works you can open a bug report issue.**
|
||||
|
||||
Please don't open issues for general command line helps!
|
@ -1,4 +1,4 @@
|
||||
### Possible endpoints
|
||||
## Possible endpoints
|
||||
|
||||
Run the API thru the systemd service, or like:
|
||||
|
||||
|
@ -5,7 +5,7 @@ use simplelog::*;
|
||||
use crate::utils::prepare_output_cmd;
|
||||
use ffplayout_lib::{
|
||||
utils::{Media, PlayoutConfig, ProcessUnit::*},
|
||||
vec_strings,
|
||||
vec_strings, ADVANCED_CONFIG,
|
||||
};
|
||||
|
||||
/// Streaming Output
|
||||
@ -16,15 +16,13 @@ pub fn output(config: &PlayoutConfig, log_format: &str) -> process::Child {
|
||||
media.unit = Encoder;
|
||||
media.add_filter(config, &None);
|
||||
|
||||
let enc_prefix = vec_strings![
|
||||
"-hide_banner",
|
||||
"-nostats",
|
||||
"-v",
|
||||
log_format,
|
||||
"-re",
|
||||
"-i",
|
||||
"pipe:0"
|
||||
];
|
||||
let mut enc_prefix = vec_strings!["-hide_banner", "-nostats", "-v", log_format];
|
||||
|
||||
if let Some(input_cmd) = &ADVANCED_CONFIG.encoder.input_cmd {
|
||||
enc_prefix.append(&mut input_cmd.clone());
|
||||
}
|
||||
|
||||
enc_prefix.append(&mut vec_strings!["-re", "-i", "pipe:0"]);
|
||||
|
||||
let enc_cmd = prepare_output_cmd(config, enc_prefix, &media.filter);
|
||||
|
||||
|
@ -216,9 +216,8 @@ fn pad(aspect: f64, chain: &mut Filters, v_stream: &ffprobe::Stream, config: &Pl
|
||||
|
||||
let pad = match &ADVANCED_CONFIG.decoder.filters.pad_video {
|
||||
Some(pad_video) => custom_format(
|
||||
pad_video,
|
||||
&format!("{scale}{pad_video}"),
|
||||
&[
|
||||
&scale,
|
||||
&config.processing.width.to_string(),
|
||||
&config.processing.height.to_string(),
|
||||
],
|
||||
@ -313,21 +312,28 @@ fn fade(node: &mut Media, chain: &mut Filters, nr: i32, filter_type: FilterType)
|
||||
}
|
||||
|
||||
if node.seek > 0.0 || node.unit == Ingest {
|
||||
let fade_in = match &ADVANCED_CONFIG.decoder.filters.fade_in {
|
||||
Some(fade) => custom_format(&format!("{t}{fade}"), &[t]),
|
||||
None => format!("{t}fade=in:st=0:d=0.5"),
|
||||
let mut fade_in = format!("{t}fade=in:st=0:d=0.5");
|
||||
|
||||
if t == "a" {
|
||||
if let Some(fade) = &ADVANCED_CONFIG.decoder.filters.afade_in {
|
||||
fade_in = custom_format(fade, &[t]);
|
||||
}
|
||||
} else if let Some(fade) = &ADVANCED_CONFIG.decoder.filters.fade_in {
|
||||
fade_in = custom_format(fade, &[t]);
|
||||
};
|
||||
|
||||
chain.add_filter(&fade_in, nr, filter_type);
|
||||
}
|
||||
|
||||
if (node.out != node.duration && node.out - node.seek > 1.0) || fade_audio {
|
||||
let fade_out = match &ADVANCED_CONFIG.decoder.filters.fade_out {
|
||||
Some(fade) => custom_format(
|
||||
&format!("{t}{fade}"),
|
||||
&[t, &(node.out - node.seek - 1.0).to_string()],
|
||||
),
|
||||
None => format!("{t}fade=out:st={}:d=1.0", (node.out - node.seek - 1.0)),
|
||||
let mut fade_out = format!("{t}fade=out:st={}:d=1.0", (node.out - node.seek - 1.0));
|
||||
|
||||
if t == "a" {
|
||||
if let Some(fade) = &ADVANCED_CONFIG.decoder.filters.afade_out {
|
||||
fade_out = custom_format(fade, &[t]);
|
||||
}
|
||||
} else if let Some(fade) = &ADVANCED_CONFIG.decoder.filters.fade_out {
|
||||
fade_out = custom_format(fade, &[t]);
|
||||
};
|
||||
|
||||
chain.add_filter(&fade_out, nr, filter_type);
|
||||
@ -343,7 +349,9 @@ fn overlay(node: &mut Media, chain: &mut Filters, config: &PlayoutConfig) {
|
||||
|
||||
if !config.processing.logo_scale.is_empty() {
|
||||
scale = match &ADVANCED_CONFIG.decoder.filters.overlay_logo_scale {
|
||||
Some(logo_scale) => custom_format(logo_scale, &[&config.processing.logo_scale]),
|
||||
Some(logo_scale) => {
|
||||
custom_format(&format!(",{logo_scale}"), &[&config.processing.logo_scale])
|
||||
}
|
||||
None => format!(",scale={}", config.processing.logo_scale),
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ pub struct Filters {
|
||||
pub drawtext_from_file: Option<String>,
|
||||
pub drawtext_from_zmq: Option<String>,
|
||||
pub aevalsrc: Option<String>,
|
||||
pub afade_in: Option<String>,
|
||||
pub afade_out: Option<String>,
|
||||
pub apad: Option<String>,
|
||||
pub volume: Option<String>,
|
||||
pub split: Option<String>,
|
||||
|
Loading…
Reference in New Issue
Block a user