Merge pull request #144 from jb-alvarado/master

better support for HLS multiple resolutions
This commit is contained in:
jb-alvarado 2022-06-30 09:42:37 +02:00 committed by GitHub
commit 6df3f69c99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 35 deletions

28
Cargo.lock generated
View File

@ -287,9 +287,9 @@ dependencies = [
[[package]]
name = "argon2"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a27e27b63e4a34caee411ade944981136fdfa535522dc9944d6700196cbd899f"
checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73"
dependencies = [
"base64ct",
"blake2",
@ -636,9 +636,9 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.6"
version = "3.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a"
checksum = "5b7b16274bb247b45177db843202209b12191b631a14a9d06e41b3777d6ecf14"
dependencies = [
"atty",
"bitflags",
@ -653,9 +653,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "3.2.6"
version = "3.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed6db9e867166a43a53f7199b5e4d1f522a1e5bd626654be263c999ce59df39a"
checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902"
dependencies = [
"heck",
"proc-macro-error",
@ -666,9 +666,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
@ -1009,7 +1009,7 @@ dependencies = [
[[package]]
name = "ffplayout"
version = "0.10.1"
version = "0.10.2"
dependencies = [
"clap",
"crossbeam-channel 0.5.5",
@ -1056,7 +1056,7 @@ dependencies = [
[[package]]
name = "ffplayout-lib"
version = "0.10.1"
version = "0.10.2"
dependencies = [
"chrono 0.4.20-beta.1",
"crossbeam-channel 0.5.5",
@ -2150,9 +2150,9 @@ dependencies = [
[[package]]
name = "password-hash"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core 0.6.3",
@ -2542,9 +2542,9 @@ dependencies = [
[[package]]
name = "semver"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c"
checksum = "3d92beeab217753479be2f74e54187a6aed4c125ff0703a866c3147a02f0c6dd"
[[package]]
name = "serde"

View File

@ -118,7 +118,7 @@ out:
help_text: The final playout compression. Set the settings to your needs. 'mode'
has the options 'desktop', 'hls', 'null', 'stream'.
'preview' works only in streaming output and creates a separate preview stream.
mode: 'stream'
mode: stream
preview: false
preview_param: >-
-s 512x288

View File

@ -14,33 +14,33 @@ For example you want to stream different resolutions, you could apply this outpu
...
output_param: >-
-c:v libx264
-c:v:0 libx264
-crf 23
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate 1300k
-bufsize 2600k
-maxrate:0 1300k
-bufsize:0 2600k
-preset faster
-tune zerolatency
-profile:v Main
-level 3.1
-c:a aac
-ar 44100
-b:a 128k
-c:a:0 aac
-ar:0 44100
-b:a:0 128k
-flags +global_header
-f flv rtmp://example.org/live/stream-high
-s 960x540
-c:v libx264
-c:v:1 libx264
-crf 23
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate 1000k
-bufsize 1800k
-maxrate:1 1000k
-bufsize:1 1800k
-preset faster
-tune zerolatency
-profile:v Main
-level 3.1
-c:a aac
-ar 44100
-b:a 128k
-c:a:1 aac
-ar:1 44100
-b:a:1 128k
-flags +global_header
-f flv rtmp://example.org/live/stream-low
```
@ -59,6 +59,67 @@ In desktop mode you will get your picture on screen. For this you need a desktop
In this mode you can output directly to a hls playlist. The nice thing here is, that ffplayout need less resources then in streaming mode.
**HLS multiple outputs example:**
```YAML
...
output_param: >-
-filter_complex [0:v]split=3[v1_out][v2][v3];[v2]scale=w=960:h=540[v2_out];[v3]scale=w=640:h=360[v3_out];[0:a]asplit=3[a1][a2][a3]
-map [v1_out]
-map [a1]
-c:v:0 libx264
-crf 23
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate:0 2000k
-bufsize:0 3200k
-preset faster
-tune zerolatency
-profile:v Main
-flags +cgop
-c:a:0 aac
-ar:0 44100
-b:a:0 128k
-map [v2_out]
-map [a2]
-c:v:1 libx264
-crf 23
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate:1 1100k
-bufsize:1 2200k
-preset faster
-tune zerolatency
-profile:v Main
-flags +cgop
-c:a:1 aac
-ar:1 44100
-b:a:1 96k
-map [v3_out]
-map [a3]
-c:v:2 libx264
-crf 23
-x264-params keyint=50:min-keyint=25:scenecut=-1
-maxrate:2 800k
-bufsize:2 1400k
-preset faster
-tune zerolatency
-profile:v Main
-flags +cgop
-c:a:2 aac
-ar:2 44100
-b:a:2 64k
-f hls
-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_%v-%d.ts
-master_pl_name master.m3u8
-var_stream_map "v:0,a:0,name:720p v:1,a:1,name:540p v:2,a:2,name:360p"
/var/www/html/live/stream_%v.m3u8
```
The using of **-filter_complex** and *mapping* is very limited, don't use it in situations other then for splitting the outputs.
#### Activating Output
To use one of the outputs you need to edit the **ffplayout.yml** config, here under **out** set your **mode** and use the different **output** options.

View File

@ -4,7 +4,7 @@ description = "24/7 playout based on rust and ffmpeg"
license = "GPL-3.0"
authors = ["Jonathan Baecker jonbae77@gmail.com"]
readme = "README.md"
version = "0.10.1"
version = "0.10.2"
edition = "2021"
[dependencies]

View File

@ -4,7 +4,7 @@ description = "Library for ffplayout"
license = "GPL-3.0"
authors = ["Jonathan Baecker jonbae77@gmail.com"]
readme = "README.md"
version = "0.10.1"
version = "0.10.2"
edition = "2021"
[dependencies]

View File

@ -423,10 +423,6 @@ pub fn seek_and_length(src: String, seek: f64, out: f64, duration: f64) -> Vec<S
source_cmd
}
pub fn format_log_line(line: String, level: &str) -> String {
line.replace(&format!("[{level: >5}] "), "")
}
/// Prepare output parameters
///
/// seek for multiple outputs and add mapping for it
@ -446,8 +442,15 @@ pub fn prepare_output_cmd(
if !filter.is_empty() {
output_params.clear();
for (i, param) in params.iter().enumerate() {
output_params.push(param.clone());
for (i, p) in params.iter().enumerate() {
let mut param = p.clone();
param = param.replace("[0:v]", "[vout1]");
param = param.replace("[0:a]", "[aout1]");
if param != "-filter_complex" {
output_params.push(param.clone());
}
if i > 0
&& !param.starts_with('-')
@ -477,6 +480,11 @@ pub fn prepare_output_cmd(
filter.drain(2..);
cmd.append(&mut filter);
cmd.append(&mut vec_strings!["-map", "[v_out1]", "-map", "[a_out1]"]);
} else if output_count == 1 && mode == "hls" && output_params[0].contains("split") {
let out_filter = output_params.remove(0);
filter[1].push_str(format!(";{out_filter}").as_str());
filter.drain(2..);
cmd.append(&mut filter);
} else if output_count > 1 && mode == "stream" {
filter[1].push_str(format!(",split={output_count}{output_v_map}").as_str());
cmd.append(&mut filter);
@ -506,6 +514,10 @@ pub fn valid_source(source: &str) -> bool {
Path::new(&source).is_file()
}
pub fn format_log_line(line: String, level: &str) -> String {
line.replace(&format!("[{level: >5}] "), "")
}
/// Read ffmpeg stderr decoder and encoder instance
/// and log the output.
pub fn stderr_reader(buffer: BufReader<ChildStderr>, suffix: &str) -> Result<(), Error> {