From 5ffaf482670de835d17a3e2502bc5f44e8e5b00b Mon Sep 17 00:00:00 2001 From: euzu Date: Wed, 19 Mar 2025 09:54:59 +0100 Subject: [PATCH] added sah url handling, some refactorings, added provider connection check, --- Cargo.lock | 149 +++++++---------- Cargo.toml | 9 +- bin/build_resources.sh | 2 +- resources/provider_connections_exhausted.jpg | Bin 0 -> 237490 bytes src/api/api_utils.rs | 153 +++++++++++++----- src/api/endpoints/hdhomerun_api.rs | 6 +- src/api/endpoints/hls_api.rs | 12 +- src/api/endpoints/m3u_api.rs | 9 +- src/api/endpoints/xtream_api.rs | 17 +- src/api/model/active_provider_manager.rs | 59 ++++--- src/api/model/event_manager.rs | 7 +- src/api/model/hls_cache.rs | 21 ++- src/api/model/mod.rs | 2 +- src/api/model/streams/provider_stream.rs | 47 +++--- .../model/streams/provider_stream_factory.rs | 24 ++- src/model/api_proxy.rs | 1 + src/model/config.rs | 77 +++++---- src/model/hls.rs | 4 +- src/model/playlist.rs | 5 +- src/processing/parser/hls.rs | 10 +- src/processing/processor/xtream.rs | 8 +- src/processing/processor/xtream_series.rs | 2 +- src/repository/kodi_repository.rs | 70 ++++---- src/repository/m3u_playlist_iterator.rs | 1 + src/repository/playlist_repository.rs | 14 +- src/repository/storage.rs | 6 +- src/repository/xtream_repository.rs | 10 +- src/utils/hash_utils.rs | 5 - src/utils/network/request.rs | 11 +- 29 files changed, 405 insertions(+), 336 deletions(-) create mode 100644 resources/provider_connections_exhausted.jpg diff --git a/Cargo.lock b/Cargo.lock index f2821dd7a..d8beaddde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310c9bcae737a48ef5cdee3174184e6d548b292739ede61a1f955ef76a738861" +checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" dependencies = [ "brotli", "flate2", @@ -301,9 +301,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753" +checksum = "b17679a8d69b6d7fd9cd9801a536cec9fa5e5970b69f9d4747f70b39b031f5e7" dependencies = [ "arrayref", "arrayvec", @@ -587,9 +587,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -916,14 +916,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -1421,9 +1423,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.21" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" dependencies = [ "cc", "libc", @@ -1433,9 +1435,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" @@ -1485,7 +1487,7 @@ dependencies = [ "pest", "pest_derive", "quick-xml", - "rand 0.9.0", + "rand", "regex", "reqwest", "rpassword", @@ -1503,7 +1505,6 @@ dependencies = [ "tower-http", "unidecode", "url", - "uuid", "vergen", "winapi", ] @@ -1627,9 +1628,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.0" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde51589ab56b20a6f686b2c68f7a0bd6add753d697abf720d63f8db3ab7b1ad" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "openssl" @@ -1892,11 +1893,12 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -1906,17 +1908,18 @@ dependencies = [ "thiserror", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "getrandom 0.2.15", - "rand 0.8.5", + "getrandom 0.3.2", + "rand", "ring", "rustc-hash", "rustls", @@ -1952,15 +1955,10 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.8.5" +name = "r-efi" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand" @@ -1968,21 +1966,11 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_chacha", + "rand_core", "zerocopy", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -1990,16 +1978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", + "rand_core", ] [[package]] @@ -2008,7 +1987,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.2", ] [[package]] @@ -2051,9 +2030,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", "bytes", @@ -2174,9 +2153,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ "bitflags 2.9.0", "errno", @@ -2187,9 +2166,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "once_cell", "ring", @@ -2219,9 +2198,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ "ring", "rustls-pki-types", @@ -2491,13 +2470,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.18.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" +checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" dependencies = [ - "cfg-if", "fastrand 2.3.0", - "getrandom 0.3.1", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -2525,9 +2503,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.39" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" dependencies = [ "deranged", "itoa", @@ -2542,15 +2520,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" dependencies = [ "num-conv", "time-core", @@ -2841,15 +2819,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" -dependencies = [ - "getrandom 0.3.1", -] - [[package]] name = "vcpkg" version = "0.2.15" @@ -2915,9 +2884,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -3068,9 +3037,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-registry" @@ -3085,9 +3054,9 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ "windows-link", ] @@ -3324,9 +3293,9 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags 2.9.0", ] diff --git a/Cargo.toml b/Cargo.toml index 5806ba5a9..65a5a91c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,20 +40,19 @@ mime = "0.3" log = "0.4" env_logger = "0.11" rustelebot = "0.3" -bincode = { version = "2.0.0-rc.3", features = ["std", "serde"] } +bincode = { version = "2.0.1", features = ["std", "serde"] } rand = "0.9" rpassword = "7.3" flate2 = "1" -blake3 = "1.5" +blake3 = "1.7" bytes = "1.10" tokio-stream = { version = "0.1", features = ["sync"] } -tokio = { version = "1.43", features = ["rt-multi-thread", "parking_lot", "fs"] } +tokio = { version = "1.44", features = ["rt-multi-thread", "parking_lot", "fs"] } tokio-util = "0.7" paste = "1.0" -tempfile = "3.16" +tempfile = "3.19" ruzstd = "0" filetime = "0.2" -uuid = { version = "1", features = ["v4"] } #[cfg(target_os = "macos")] libc = "0" #[cfg(target_os = "windows")] diff --git a/bin/build_resources.sh b/bin/build_resources.sh index 889100321..90f87f684 100755 --- a/bin/build_resources.sh +++ b/bin/build_resources.sh @@ -21,7 +21,7 @@ while getopts "fh" opt; do esac done -declare -a resources=("channel_unavailable" "user_connections_exhausted") +declare -a resources=("channel_unavailable" "user_connections_exhausted" "provider_connections_exhausted") for resource in "${resources[@]}"; do if [ "$flag_force" = false ]; then diff --git a/resources/provider_connections_exhausted.jpg b/resources/provider_connections_exhausted.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fde4b92284165b997842ca308e05befabe01722e GIT binary patch literal 237490 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%0DeBcHN@6TV`=g$aPN9R0z7vW2KlB5##vx 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 E0DWuYX#fBK literal 0 HcmV?d00001 diff --git a/src/api/api_utils.rs b/src/api/api_utils.rs index 69ea68b12..3e50c3617 100644 --- a/src/api/api_utils.rs +++ b/src/api/api_utils.rs @@ -68,6 +68,8 @@ macro_rules! try_result_bad_request { pub use try_option_bad_request; pub use try_result_bad_request; +use crate::api::model::active_provider_manager::ProviderConfig; +use crate::api::model::streams::provider_stream::{create_provider_connections_exhausted_stream, ProviderStreamResponse}; use crate::auth::authenticator::Claims; pub async fn serve_file(file_path: &Path, mime_type: mime::Mime) -> impl axum::response::IntoResponse + Send { @@ -155,78 +157,141 @@ fn get_stream_options(app_state: &AppState) -> StreamOptions { // content_length // } -pub async fn stream_response(app_state: &AppState, stream_url: &str, +fn get_stream_alternative_url(stream_url: &str, input: &ConfigInput, alias_input: &ProviderConfig) -> String { + let Some(input_user_info) = input.get_user_info() else { return stream_url.to_owned() }; + let Some(alt_input_user_info) = alias_input.get_user_info() else { return stream_url.to_owned() }; + + let modified = stream_url.replace(&input_user_info.base_url, &alt_input_user_info.base_url); + let modified = modified.replace(&input_user_info.username, &alt_input_user_info.username); + let modified = modified.replace(&input_user_info.password, &alt_input_user_info.password); + modified +} + +/** +* If successfully a provider connection is used, do not forget to release if unsuccessfully +*/ +fn get_stream_response_params(app_state: &AppState, stream_url: &str, input_opt: Option<&ConfigInput>) + -> (Option, Option>, Option, Option) { + let (custom_stream, input_headers, input_name, request_url) = if let Some(input) = input_opt { + let (stream_response, alias_input_name, request_url) = match app_state.active_provider.acquire_connection(&input.name) { + None => { + let stream = create_provider_connections_exhausted_stream(&app_state.config, &[]); + (Some(stream), None, None) + }, + Some(alias_input) => { + if alias_input.id != input.id { + (None, Some(alias_input.name.to_string()), Some(get_stream_alternative_url(stream_url, input, &alias_input))) + } else { + (None, Some(input.name.to_string()), Some(stream_url.to_string())) + } + } + }; + (stream_response, Some(input.headers.clone()), alias_input_name, request_url) + } else { + (None, None, None, None) + }; + (custom_stream, input_headers, input_name, request_url) +} + +async fn create_stream_response(app_state: &AppState, stream_options: &StreamOptions, stream_url: &str, + req_headers: &HeaderMap, input_opt: Option<&ConfigInput>, + item_type: PlaylistItemType, share_stream : bool) -> (ProviderStreamResponse, Option) { + let (provider_stream, input_headers, stream_input_name, request_url) = get_stream_response_params(app_state, stream_url, input_opt); + if let Some(provider_stream_response) = provider_stream{ + return (provider_stream_response, None); + } + + let parsed_url = request_url.map_or_else(|| Url::parse(stream_url), |u| Url::parse(&u)); + + let (stream, stream_info) = if let Ok(url) = parsed_url { + if stream_options.pipe_provider_stream { + provider_stream::get_provider_pipe_stream(app_state, &url, req_headers, input_headers, item_type, &stream_options).await + } else { + let buffer_stream_options = BufferStreamOptions::new(item_type, share_stream, &stream_options); + provider_stream::get_provider_reconnect_buffered_stream(app_state, &url, req_headers, input_headers, buffer_stream_options).await + } + } else { + (None, None) + }; + + // if we have no stream we should release the provider + if stream.is_none() { + if let Some(alt_input_name) = &stream_input_name { + app_state.active_provider.release_connection(alt_input_name); + } + } + + ((stream, stream_info), stream_input_name.or(input_opt.map(|i| i.name.to_string()))) +} + +pub async fn stream_response(app_state: &AppState, + stream_url: &str, req_headers: &HeaderMap, input: Option<&ConfigInput>, - item_type: PlaylistItemType, target: &ConfigTarget, + item_type: PlaylistItemType, + target: &ConfigTarget, user: &ProxyUserCredentials) -> impl axum::response::IntoResponse + Send { if log_enabled!(log::Level::Trace) { trace!("Try to open stream {}", sanitize_sensitive_info(stream_url)); } let share_stream = is_stream_share_enabled(item_type, target); if share_stream { - if let Some(value) = shared_stream_response(app_state, stream_url, user, input).await { + if let Some(value) = shared_stream_response(app_state, stream_url, user).await { return value.into_response(); } } - let stream_options = get_stream_options(app_state); get_stream_options(app_state); - - if let Ok(url) = Url::parse(stream_url) { - let event_manager = Arc::clone(&app_state.event_manager); - let (stream_opt, provider_response) = if stream_options.pipe_provider_stream { - provider_stream::get_provider_pipe_stream(&app_state.config, &app_state.http_client, &url, req_headers, input, item_type, &stream_options).await - } else { - let buffer_stream_options = BufferStreamOptions::new(item_type,share_stream, &stream_options); - provider_stream::get_provider_reconnect_buffered_stream(&app_state.config, &app_state.http_client, &url, req_headers, input, buffer_stream_options).await - }; - if let Some(stream) = stream_opt { - // let content_length = get_stream_content_length(provider_response.as_ref()); - let stream = ActiveClientStream::new(stream, event_manager, &user.username, input.map(|c| c.name.clone())).await; - let stream_resp = if share_stream { - let shared_headers = provider_response.as_ref().map_or_else(Vec::new, |(h, _)| h.clone()); - SharedStreamManager::subscribe(app_state, stream_url, stream, shared_headers, stream_options.buffer_size).await; - if let Some(broadcast_stream) = SharedStreamManager::subscribe_shared_stream(app_state, stream_url).await { - let (status_code, header_map) = get_stream_response_with_headers(provider_response, stream_url); - let mut response = axum::response::Response::builder() - .status(status_code); - for (key, value) in &header_map { - response = response.header(key, value); - } - response.body(axum::body::Body::from_stream(broadcast_stream)).unwrap().into_response() - // if content_length > 0 { - // response_builder.body(SizedStream::new(content_length, broadcast_stream)) } - // else { - // response_builder.body(BodyStream::new(broadcast_stream)) - // } - } else { - axum::http::StatusCode::BAD_REQUEST.into_response() - } - } else { + let stream_options = get_stream_options(app_state); + let event_manager = Arc::clone(&app_state.event_manager); + let ((stream_opt, provider_response), stream_input_name) = create_stream_response(app_state, &stream_options, &stream_url, req_headers, input, item_type, share_stream).await; + if let Some(stream) = stream_opt { + // let content_length = get_stream_content_length(provider_response.as_ref()); + let stream = ActiveClientStream::new(stream, event_manager, &user.username, stream_input_name).await; + let stream_resp = if share_stream { + // Shared Stream response + let shared_headers = provider_response.as_ref().map_or_else(Vec::new, |(h, _)| h.clone()); + SharedStreamManager::subscribe(app_state, stream_url, stream, shared_headers, stream_options.buffer_size).await; + if let Some(broadcast_stream) = SharedStreamManager::subscribe_shared_stream(app_state, stream_url).await { let (status_code, header_map) = get_stream_response_with_headers(provider_response, stream_url); let mut response = axum::response::Response::builder() .status(status_code); for (key, value) in &header_map { response = response.header(key, value); } - response.body(axum::body::Body::from_stream(stream)).unwrap().into_response() + response.body(axum::body::Body::from_stream(broadcast_stream)).unwrap().into_response() + // if content_length > 0 { + // response_builder.body(SizedStream::new(content_length, broadcast_stream)) } + // else { + // response_builder.body(BodyStream::new(broadcast_stream)) + // } + } else { + axum::http::StatusCode::BAD_REQUEST.into_response() + } + } else { + let (status_code, header_map) = get_stream_response_with_headers(provider_response, stream_url); + let mut response = axum::response::Response::builder() + .status(status_code); + for (key, value) in &header_map { + response = response.header(key, value); + } + response.body(axum::body::Body::from_stream(stream)).unwrap().into_response() - // if content_length > 0 { response_builder.body(SizedStream::new(content_length, stream)) } else { response_builder.streaming(stream) } - }; + // if content_length > 0 { response_builder.body(SizedStream::new(content_length, stream)) } else { response_builder.streaming(stream) } + }; - return stream_resp.into_response(); - } + return stream_resp.into_response(); } + error!("Cant open stream {}", sanitize_sensitive_info(stream_url)); axum::http::StatusCode::BAD_REQUEST.into_response() } -async fn shared_stream_response(app_state: &AppState, stream_url: &str, user: &ProxyUserCredentials, input: Option<&ConfigInput>,) -> Option { +async fn shared_stream_response(app_state: &AppState, stream_url: &str, user: &ProxyUserCredentials) -> Option { if let Some(stream) = SharedStreamManager::subscribe_shared_stream(app_state, stream_url).await { debug_if_enabled!("Using shared channel {}", sanitize_sensitive_info(stream_url)); if let Some(headers) = app_state.shared_stream_manager.get_shared_state_headers(stream_url).await { let (status_code, header_map) = get_stream_response_with_headers(Some((headers.clone(), StatusCode::OK)), stream_url); let event_manager = Arc::clone(&app_state.event_manager); - let stream = ActiveClientStream::new(stream, event_manager, &user.username, input.map(|c| c.name.clone())).await.boxed(); + let stream = ActiveClientStream::new(stream, event_manager, &user.username, None).await.boxed(); let mut response = axum::response::Response::builder() .status(status_code); for (key, value) in &header_map { @@ -239,7 +304,7 @@ async fn shared_stream_response(app_state: &AppState, stream_url: &str, user: &P } pub fn is_stream_share_enabled(item_type: PlaylistItemType, target: &ConfigTarget) -> bool { - (item_type == PlaylistItemType::Live || item_type == PlaylistItemType::LiveHls) && target.options.as_ref().is_some_and(|opt| opt.share_live_streams) + (item_type == PlaylistItemType::Live /* || item_type == PlaylistItemType::LiveHls */) && target.options.as_ref().is_some_and(|opt| opt.share_live_streams) } pub type HeaderFilter = Option bool + Send>>; diff --git a/src/api/endpoints/hdhomerun_api.rs b/src/api/endpoints/hdhomerun_api.rs index 711040766..1918e797b 100644 --- a/src/api/endpoints/hdhomerun_api.rs +++ b/src/api/endpoints/hdhomerun_api.rs @@ -93,9 +93,9 @@ where match channels { Some(chans) => { let mapped = chans.map(move |(item, has_next)| { - let input = cfg.get_input_by_name(&item.input_name); - let (live_stream_use_prefix, live_stream_without_extension) = input.map_or((true, false), |i| i.options.as_ref() - .map_or((true, false), |o| (o.xtream_live_stream_use_prefix, o.xtream_live_stream_without_extension))); + let input_options = cfg.get_input_options_by_name(&item.input_name); + let (live_stream_use_prefix, live_stream_without_extension) = input_options.as_ref() + .map_or((true, false), |o| (o.xtream_live_stream_use_prefix, o.xtream_live_stream_without_extension)); let container_extension = item.get_additional_property("container_extension").map(|v| get_string_from_serde_value(&v).unwrap_or_default()); let stream_url = match &base_url { None => item.url.to_string(), diff --git a/src/api/endpoints/hls_api.rs b/src/api/endpoints/hls_api.rs index 30d8838e4..2ae553367 100644 --- a/src/api/endpoints/hls_api.rs +++ b/src/api/endpoints/hls_api.rs @@ -15,7 +15,7 @@ use std::sync::Arc; #[derive(Deserialize)] struct HlsApiPathParams { - token: String, + token: u32, username: String, password: String, stream_id: u32, @@ -32,7 +32,8 @@ pub(in crate::api) async fn handle_hls_stream_request(app_state: &Arc, let server_info = app_state.config.get_user_server_info(user).await; match request::download_text_content(Arc::clone(&app_state.http_client), input, &url, None).await { Ok(content) => { - let (hls_entry, hls_content) = rewrite_hls(&server_info.get_base_url(), &content, hls_url, virtual_id, user, &target_type, &input.name); + let hls_token = app_state.hls_cache.new_token(); + let (hls_entry, hls_content) = rewrite_hls(&server_info.get_base_url(), &content, hls_url, virtual_id, hls_token, user, &target_type, input.id); app_state.hls_cache.add_entry(hls_entry).await; axum::response::Response::builder() .status(axum::http::StatusCode::OK) @@ -62,12 +63,11 @@ async fn hls_api_stream( if user.connections_exhausted(&app_state).await { return create_custom_video_stream_response(&app_state.config, &CustomVideoStreamType::UserConnectionsExhausted).into_response(); } - - let Some(hls_entry) = app_state.hls_cache.get_entry(¶ms.token).await else { return axum::http::StatusCode::BAD_REQUEST.into_response(); }; + let Some(hls_entry) = app_state.hls_cache.get_entry(params.token).await else { return axum::http::StatusCode::BAD_REQUEST.into_response(); }; let Some(hls_url) = hls_entry.get_chunk_url(params.chunk) else { return axum::http::StatusCode::BAD_REQUEST.into_response(); }; let target_name = &target.name; let virtual_id = params.stream_id; - let input = try_option_bad_request!(app_state.config.get_input_by_name(&hls_entry.input_name), true, format!("Cant find input for target {target_name}, context {}, stream_id {virtual_id}", XtreamCluster::Live)); + let input = try_option_bad_request!(app_state.config.get_input_by_id(hls_entry.input_id), true, format!("Cant find input for target {target_name}, context {}, stream_id {virtual_id}", XtreamCluster::Live)); if is_hls_url(hls_url) { return handle_hls_stream_request(&app_state, &user, hls_url, virtual_id, input, hls_entry.target_type.clone()).await.into_response(); @@ -80,7 +80,7 @@ async fn hls_api_stream( // let pli = try_result_bad_request!(m3u_repository::m3u_get_item_for_stream_id(virtual_id, &app_state.config, target).await, true, format!("Failed to read xtream item for stream id {}", virtual_id)); // (pli.url, pli.input_name) // }; - stream_response(&app_state, hls_url, &req_headers, Some(input), PlaylistItemType::Live, target, &user).await.into_response() + stream_response(&app_state, hls_url, &req_headers, Some(input), PlaylistItemType::LiveHls, target, &user).await.into_response() } pub fn hls_api_register() -> axum::Router> { diff --git a/src/api/endpoints/m3u_api.rs b/src/api/endpoints/m3u_api.rs index 13dc0286e..2a11b2710 100644 --- a/src/api/endpoints/m3u_api.rs +++ b/src/api/endpoints/m3u_api.rs @@ -7,7 +7,7 @@ use crate::model::config::TargetType; use crate::model::playlist::{FieldGetAccessor, PlaylistItemType, XtreamCluster}; use crate::repository::m3u_playlist_iterator::{M3U_RESOURCE_PATH, M3U_STREAM_PATH}; use crate::repository::m3u_repository::{m3u_get_item_for_stream_id, m3u_load_rewrite_playlist}; -use crate::utils::network::request::{replace_url_extension, sanitize_sensitive_info, HLS_EXT}; +use crate::utils::network::request::{replace_url_extension, sanitize_sensitive_info, DASH_EXT, HLS_EXT}; use crate::utils::debug_if_enabled; use axum::response::IntoResponse; use bytes::Bytes; @@ -91,13 +91,16 @@ async fn m3u_api_stream( let input = app_state.config.get_input_by_name(m3u_item.input_name.as_str()); let is_hls_request = m3u_item.item_type == PlaylistItemType::LiveHls || stream_ext.as_deref() == Some(HLS_EXT); + let is_dash_request = !is_hls_request && m3u_item.item_type == PlaylistItemType::LiveDash || stream_ext.as_deref() == Some(DASH_EXT); - if user.proxy == ProxyType::Redirect { - let redirect_url = if is_hls_request { &replace_url_extension(&m3u_item.url, "m3u8") } else { &m3u_item.url }; + if user.proxy == ProxyType::Redirect || is_dash_request { + let redirect_url = if is_hls_request { &replace_url_extension(&m3u_item.url, HLS_EXT) } else { &m3u_item.url }; + let redirect_url = if is_dash_request { &replace_url_extension(redirect_url, DASH_EXT) } else { redirect_url }; // TODO alias processing debug_if_enabled!("Redirecting m3u stream request to {}", sanitize_sensitive_info(redirect_url)); return redirect(redirect_url.as_str()).into_response(); } + // Reverse proxy mode if is_hls_request { let target_name = &target.name; diff --git a/src/api/endpoints/xtream_api.rs b/src/api/endpoints/xtream_api.rs index 4ecd45a70..0ec8ea324 100644 --- a/src/api/endpoints/xtream_api.rs +++ b/src/api/endpoints/xtream_api.rs @@ -35,7 +35,7 @@ use crate::repository::{user_repository, xtream_repository}; use crate::repository::xtream_repository::{TAG_EPISODES, TAG_INFO_DATA, TAG_SEASONS_DATA}; use crate::utils::hash_utils::generate_playlist_uuid; use crate::utils::json_utils::get_u32_from_serde_value; -use crate::utils::network::request::{extract_extension_from_url, sanitize_sensitive_info, HLS_EXT}; +use crate::utils::network::request::{extract_extension_from_url, replace_url_extension, sanitize_sensitive_info, DASH_EXT, HLS_EXT}; use crate::utils::network::xtream::{create_vod_info_from_item, ACTION_GET_LIVE_CATEGORIES, ACTION_GET_LIVE_STREAMS, ACTION_GET_SERIES, ACTION_GET_SERIES_CATEGORIES, ACTION_GET_SERIES_INFO, ACTION_GET_VOD_CATEGORIES, ACTION_GET_VOD_INFO, ACTION_GET_VOD_STREAMS}; use crate::utils::json_utils; use crate::utils::debug_if_enabled; @@ -108,7 +108,7 @@ pub fn serve_query(file_path: &Path, filter: &HashMap<&str, HashSet>) -> } fn get_xtream_player_api_stream_url(input: &ConfigInput, context: &XtreamApiStreamContext, action_path: &str, fallback_url: &str) -> Option { - if let Some(user_info) = input.get_user_info() { + if let Some(input_user_info) = input.get_user_info() { let ctx = match context { XtreamApiStreamContext::LiveAlt | XtreamApiStreamContext::Live => { @@ -121,10 +121,10 @@ fn get_xtream_player_api_stream_url(input: &ConfigInput, context: &XtreamApiStre }; let ctx_path = if ctx.is_empty() { String::new() } else { format!("{ctx}/") }; Some(format!("{}/{}{}/{}/{}", - &user_info.base_url, + &input_user_info.base_url, ctx_path, - &user_info.username, - &user_info.password, + &input_user_info.username, + &input_user_info.password, action_path )) } else if !fallback_url.is_empty() { @@ -177,10 +177,15 @@ async fn xtream_player_api_stream( } // if pli.item_type == PlaylistItemType::LiveHls { - // let redirect_url = &replace_extension(&pli.url, "m3u8"); + // let redirect_url = &replace_extension(&pli.url, HLS_EXT); // debug_if_enabled!("Redirecting stream request to {}", sanitize_sensitive_info(redirect_url)); // return redirect(redirect_url).into_response(); // } + if pli.item_type == PlaylistItemType::LiveDash { + let redirect_url = &replace_url_extension(&pli.url, DASH_EXT); + debug_if_enabled!("Redirecting stream request to {}", sanitize_sensitive_info(redirect_url)); + return redirect(redirect_url).into_response(); + } debug_if_enabled!("Redirecting stream request to {}", sanitize_sensitive_info(&pli.url)); return redirect(&pli.url).into_response(); diff --git a/src/api/model/active_provider_manager.rs b/src/api/model/active_provider_manager.rs index 3a8d22905..d76742280 100644 --- a/src/api/model/active_provider_manager.rs +++ b/src/api/model/active_provider_manager.rs @@ -1,5 +1,5 @@ use std::cell::RefCell; -use crate::model::config::{Config, ConfigInput, ConfigInputAlias, InputType}; +use crate::model::config::{Config, ConfigInput, ConfigInputAlias, InputType, InputUserInfo}; use std::collections::HashMap; use std::sync::atomic::{AtomicU16, AtomicUsize, Ordering}; @@ -52,6 +52,10 @@ impl ProviderConfig { } } + pub fn get_user_info(&self) -> Option { + InputUserInfo::new(self.input_type.clone(), self.username.as_deref(), self.password.as_deref(), &self.url) + } + #[inline] pub fn is_exhausted(&self) -> bool { self.max_connections > 0 && self.current_connections.load(Ordering::SeqCst) >= self.max_connections @@ -62,9 +66,9 @@ impl ProviderConfig { // !self.is_exhausted() // } - pub fn try_allocate(&self, force: bool) -> bool { + pub fn try_allocate(&self) -> bool { let connections = self.current_connections.load(Ordering::SeqCst); - if force || self.max_connections == 0 || connections < self.max_connections { + if self.max_connections == 0 || connections < self.max_connections { self.current_connections.fetch_add(1, Ordering::SeqCst); return true; } @@ -94,10 +98,10 @@ enum ProviderLineup { } impl ProviderLineup { - fn acquire(&self, force: bool) -> Option<&ProviderConfig> { + fn acquire(&self) -> Option<&ProviderConfig> { match self { - ProviderLineup::Single(lineup) => lineup.acquire(force), - ProviderLineup::Multi(lineup) => lineup.acquire(force), + ProviderLineup::Single(lineup) => lineup.acquire(), + ProviderLineup::Multi(lineup) => lineup.acquire(), } } @@ -122,8 +126,8 @@ impl SingleProviderLineup { } } - fn acquire(&self, force: bool) -> Option<&ProviderConfig> { - if self.provider.try_allocate(force) { + fn acquire(&self) -> Option<&ProviderConfig> { + if self.provider.try_allocate() { Some(&self.provider) } else { None @@ -235,7 +239,7 @@ impl MultiProviderLineup { fn acquire_next_provider_from_group(priority_group: &ProviderPriorityGroup) -> Option<&ProviderConfig> { match priority_group { ProviderPriorityGroup::SingleProviderGroup(p) => { - if p.try_allocate(false) { + if p.try_allocate() { return Some(p); } } @@ -245,7 +249,7 @@ impl MultiProviderLineup { for _ in 0..provider_count { let p = pg.get(idx).unwrap(); idx = (idx + 1) % provider_count; - if p.try_allocate(false) { + if p.try_allocate() { index.store(idx, Ordering::SeqCst); return Some(p); } @@ -258,9 +262,6 @@ impl MultiProviderLineup { /// Attempts to acquire a provider from the lineup based on priority and availability. /// - /// # Parameters - /// - `force`: A boolean flag indicating whether to force allocation even if all providers are exhausted. - /// /// # Returns /// - `Some(&ProviderConfig)`: A reference to the acquired provider if allocation was successful. /// - `None`: If no providers are available and `force` is `false`. @@ -286,7 +287,7 @@ impl MultiProviderLineup { /// println!("No available providers."); /// } /// ``` - fn acquire(&self, force: bool) -> Option<&ProviderConfig> { + fn acquire(&self) -> Option<&ProviderConfig> { let mut main_idx = self.index.load(Ordering::SeqCst); let provider_count = self.providers.len(); @@ -301,21 +302,17 @@ impl MultiProviderLineup { } } - if force { - let provider = &self.providers[main_idx]; - self.index.store((main_idx + 1) % provider_count, Ordering::SeqCst); + let provider = &self.providers[main_idx]; + self.index.store((main_idx + 1) % provider_count, Ordering::SeqCst); - return match provider { - ProviderPriorityGroup::SingleProviderGroup(p) => Some(p), - ProviderPriorityGroup::MultiProviderGroup(gindex, group) => { - let idx = gindex.load(Ordering::SeqCst); - gindex.store((idx + 1) % group.len(), Ordering::SeqCst); - group.get(idx) - } - }; - } - - None + return match provider { + ProviderPriorityGroup::SingleProviderGroup(p) => Some(p), + ProviderPriorityGroup::MultiProviderGroup(gindex, group) => { + let idx = gindex.load(Ordering::SeqCst); + gindex.store((idx + 1) % group.len(), Ordering::SeqCst); + group.get(idx) + } + }; } @@ -343,15 +340,12 @@ impl MultiProviderLineup { } pub struct ActiveProviderManager { - user_access_control: bool, providers: Vec, } impl ActiveProviderManager { pub fn new(cfg: &Config) -> Self { - let user_access_control = cfg.user_access_control; let mut this = Self { - user_access_control, providers: Vec::new(), }; for source in &cfg.sources { @@ -403,10 +397,11 @@ impl ActiveProviderManager { pub fn acquire_connection(&self, input_name: &str) -> Option<&ProviderConfig> { match self.get_provider_config(input_name) { None => None, - Some((lineup, _config)) => lineup.acquire(self.user_access_control) + Some((lineup, _config)) => lineup.acquire() } } + // we need the provider_name to exactly release this provider pub fn release_connection(&self, provider_name: &str) { if let Some((lineup, _config)) = self.get_provider_config(provider_name) { lineup.release(provider_name); diff --git a/src/api/model/event_manager.rs b/src/api/model/event_manager.rs index d2e7a5a04..9d099412d 100644 --- a/src/api/model/event_manager.rs +++ b/src/api/model/event_manager.rs @@ -31,21 +31,18 @@ impl EventManager { pub async fn fire(&self, event: Event) { match event { - Event::StreamConnect((username, input_name)) => { + Event::StreamConnect((username, _input_name)) => { let (client_count, connection_count) = self.active_user.add_connection(&username).await; if self.log_active_clients { info!("Active clients: {client_count}, active connections {connection_count}"); } - if let Some(input) = input_name { - // TODO this is the wrong place, move it later to the right place - self.active_provider.acquire_connection(&input); - } } Event::StreamDisconnect((username, input_name)) => { let (client_count, connection_count) = self.active_user.remove_connection(&username).await; if self.log_active_clients { info!("Active clients: {client_count}, active connections {connection_count}"); } + if let Some(input) = input_name { self.active_provider.release_connection(&input); } diff --git a/src/api/model/hls_cache.rs b/src/api/model/hls_cache.rs index ca038e514..90e13b5d2 100644 --- a/src/api/model/hls_cache.rs +++ b/src/api/model/hls_cache.rs @@ -2,6 +2,7 @@ use log::error; use std::collections::HashMap; use std::str::FromStr; use std::sync::Arc; +use std::sync::atomic::AtomicU32; use std::time::Duration; use chrono::Local; use cron::Schedule; @@ -11,6 +12,7 @@ use crate::utils::sys_utils::exit; use crate::model::hls::HlsEntry; const EXPIRE_DURATION: u64 = 600; // 10 minutes +const TOKEN_MAX: u32 = u32::MAX - u16::MAX as u32; fn start_garbage_collector(cache: &Arc) { let cache_clone = cache.clone(); @@ -32,13 +34,15 @@ fn start_garbage_collector(cache: &Arc) { } pub struct HlsCache { - pub entries: RwLock>, + pub entries: RwLock>, + counter: AtomicU32, } impl HlsCache { pub fn garbage_collected() -> Arc { let cache = Arc::new(Self { entries: RwLock::new(HashMap::new()), + counter: AtomicU32::new(1), }); start_garbage_collector(&cache); @@ -46,11 +50,11 @@ impl HlsCache { } pub async fn add_entry(&self, entry: HlsEntry) { - self.entries.write().await.insert(entry.token.to_string(), entry); + self.entries.write().await.insert(entry.token, entry); } - pub async fn get_entry(&self, token: &str) -> Option{ - self.entries.read().await.get(token).cloned() + pub async fn get_entry(&self, token: u32) -> Option{ + self.entries.read().await.get(&token).cloned() } pub async fn gc(&self) { @@ -58,4 +62,13 @@ impl HlsCache { // Remove all expired elements self.entries.write().await.retain(|_, entry| entry.ts > threshold); } + + pub fn new_token(&self) -> u32 { + let token = self.counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + if token > TOKEN_MAX { + self.counter.store(1, std::sync::atomic::Ordering::SeqCst); + return 1; + } + return token; + } } \ No newline at end of file diff --git a/src/api/model/mod.rs b/src/api/model/mod.rs index 51439073d..922490c82 100644 --- a/src/api/model/mod.rs +++ b/src/api/model/mod.rs @@ -9,4 +9,4 @@ pub(crate) mod streams; pub(in crate::api) mod active_user_manager; pub(in crate::api) mod active_provider_manager; pub(in crate::api) mod event_manager; -pub(in crate::api) mod hls_cache; +pub(in crate::api) mod hls_cache; \ No newline at end of file diff --git a/src/api/model/streams/provider_stream.rs b/src/api/model/streams/provider_stream.rs index e0d102bb9..bcd8aedd5 100644 --- a/src/api/model/streams/provider_stream.rs +++ b/src/api/model/streams/provider_stream.rs @@ -1,9 +1,10 @@ +use std::collections::HashMap; use crate::api::api_utils::{get_headers_from_request, HeaderFilter, StreamOptions}; use crate::api::model::model_utils::get_response_headers; use crate::api::model::stream_error::StreamError; use crate::api::model::streams::custom_video_stream::CustomVideoStream; use crate::api::model::streams::provider_stream_factory::{create_provider_stream, BufferStreamOptions}; -use crate::model::config::{Config, ConfigInput}; +use crate::model::config::{Config}; use crate::model::playlist::PlaylistItemType; use crate::utils::debug_if_enabled; use crate::utils::network::request::{get_request_headers, sanitize_sensitive_info}; @@ -17,10 +18,11 @@ use std::time::Duration; use axum::http::HeaderMap; use axum::response::IntoResponse; use url::Url; +use crate::api::model::app_state::AppState; type BoxedProviderStream = BoxStream<'static, Result>; type ProviderStreamHeader = Vec<(String, String)>; -type ProviderStreamResponse = (Option, Option<(ProviderStreamHeader, StatusCode)>); +pub type ProviderStreamResponse = (Option, Option<(ProviderStreamHeader, StatusCode)>); pub enum CustomVideoStreamType { ChannelUnavailable, @@ -28,33 +30,33 @@ pub enum CustomVideoStreamType { ProviderConnectionsExhausted, } -fn create_video_stream(video: Option<&Arc>>, headers: &[(String, String)], log_message: &str) -> Option<(BoxedProviderStream, (ProviderStreamHeader, StatusCode))> { +fn create_video_stream(video: Option<&Arc>>, headers: &[(String, String)], log_message: &str) -> ProviderStreamResponse { if let Some(video) = video { debug!("{}", log_message); let mut response_headers: Vec<(String, String)> = headers.iter() .filter(|(key, _)| !(key.eq("content-type") || key.eq("content-length") || key.contains("range"))) .map(|(key, value)| (key.to_string(), value.to_string())).collect(); response_headers.push(("content-type".to_string(), "video/mp2t".to_string())); - Some((Box::pin(CustomVideoStream::new(Arc::clone(video))), (response_headers, StatusCode::OK))) + (Some(Box::pin(CustomVideoStream::new(Arc::clone(video)))), Some((response_headers, StatusCode::OK))) } else { - None + (None, None) } } -pub fn create_channel_unavailable_stream(cfg: &Config, headers: &[(String, String)], status: StatusCode) -> Option<(BoxedProviderStream, (ProviderStreamHeader, StatusCode))> { +pub fn create_channel_unavailable_stream(cfg: &Config, headers: &[(String, String)], status: StatusCode) -> ProviderStreamResponse { create_video_stream(cfg.t_channel_unavailable_video.as_ref(), headers, &format!("Streaming response channel unavailable for status {status}")) } -pub fn create_user_connections_exhausted_stream(cfg: &Config, headers: &[(String, String)]) -> Option<(BoxedProviderStream, (ProviderStreamHeader, StatusCode))> { +pub fn create_user_connections_exhausted_stream(cfg: &Config, headers: &[(String, String)]) -> ProviderStreamResponse { create_video_stream(cfg.t_user_connections_exhausted_video.as_ref(), headers, "Streaming response user connections exhausted") } -pub fn create_provider_connections_exhausted_stream(cfg: &Config, headers: &[(String, String)]) -> Option<(BoxedProviderStream, (ProviderStreamHeader, StatusCode))> { +pub fn create_provider_connections_exhausted_stream(cfg: &Config, headers: &[(String, String)]) -> ProviderStreamResponse { create_video_stream(cfg.t_provider_connections_exhausted_video.as_ref(), headers, "Streaming response provider connections exhausted") } pub fn create_custom_video_stream_response(config: &Config, video_response: &CustomVideoStreamType) -> impl axum::response::IntoResponse + Send { - if let Some((stream, (headers, status_code))) = match video_response { + if let (Some(stream), Some((headers, status_code))) = match video_response { CustomVideoStreamType::ChannelUnavailable => create_channel_unavailable_stream(config, &[], StatusCode::BAD_REQUEST), CustomVideoStreamType::UserConnectionsExhausted => create_user_connections_exhausted_stream(config, &[]), CustomVideoStreamType::ProviderConnectionsExhausted => create_provider_connections_exhausted_stream(config, &[]), @@ -68,33 +70,29 @@ pub fn create_custom_video_stream_response(config: &Config, video_response: &Cus } axum::http::StatusCode::FORBIDDEN.into_response() } - - pub fn get_header_filter_for_item_type(item_type: PlaylistItemType) -> HeaderFilter { match item_type { - PlaylistItemType::Live | PlaylistItemType::LiveUnknown | PlaylistItemType::LiveHls => { + PlaylistItemType::Live | PlaylistItemType::LiveHls | PlaylistItemType::LiveDash | PlaylistItemType::LiveUnknown => { Some(Box::new(|key| key != "accept-ranges" && key != "range" && key != "content-range")) } _ => None, } } -pub async fn get_provider_pipe_stream(cfg: &Config, - http_client: &Arc, +pub async fn get_provider_pipe_stream(app_state: &AppState, stream_url: &Url, req_headers: &HeaderMap, - input: Option<&ConfigInput>, + input_headers: Option>, item_type: PlaylistItemType, stream_options: &StreamOptions) -> ProviderStreamResponse { let filter_header = get_header_filter_for_item_type(item_type); let req_headers = get_headers_from_request(req_headers, &filter_header); debug_if_enabled!("Stream requested with headers: {:?}", req_headers.iter().map(|header| (header.0, String::from_utf8_lossy(header.1))).collect::>()); // These are the configured headers for this input. - let input_headers = input.map(|i| i.headers.clone()); // The stream url, we need to clone it because of move to async block. // We merge configured input headers with the headers from the request. let headers = get_request_headers(input_headers.as_ref(), Some(&req_headers)); - let client_builder = http_client.get(stream_url.clone()).headers(headers.clone()); + let client_builder = app_state.http_client.get(stream_url.clone()).headers(headers.clone()); let client = if stream_options.stream_connect_timeout_secs > 0 { client_builder.timeout(Duration::from_secs(u64::from(stream_options.stream_connect_timeout_secs))) } else { @@ -107,8 +105,8 @@ pub async fn get_provider_pipe_stream(cfg: &Config, let status = response.status(); if status.is_success() { (Some(Box::pin(response.bytes_stream().map_err(|err| StreamError::reqwest(&err)))), Some((response_headers, status))) - } else if let Some((boxed_provider_stream, response_info)) = create_channel_unavailable_stream(cfg, &response_headers, status) { - (Some(boxed_provider_stream), Some(response_info)) + } else if let (Some(boxed_provider_stream), response_info) = create_channel_unavailable_stream(&app_state.config, &response_headers, status) { + (Some(boxed_provider_stream), response_info) } else { (None, Some((response_headers, status))) } @@ -116,8 +114,8 @@ pub async fn get_provider_pipe_stream(cfg: &Config, Err(err) => { let masked_url = sanitize_sensitive_info(stream_url.as_str()); error!("Failed to open stream {masked_url} {err}"); - if let Some((boxed_provider_stream, response_info)) = create_channel_unavailable_stream(cfg, &get_response_headers(&headers), StatusCode::BAD_GATEWAY) { - (Some(boxed_provider_stream), Some(response_info)) + if let (Some(boxed_provider_stream), response_info) = create_channel_unavailable_stream(&app_state.config, &get_response_headers(&headers), StatusCode::BAD_GATEWAY) { + (Some(boxed_provider_stream), response_info) } else { (None, None) } @@ -125,13 +123,12 @@ pub async fn get_provider_pipe_stream(cfg: &Config, } } -pub async fn get_provider_reconnect_buffered_stream(cfg: &Config, - http_client: &Arc, +pub async fn get_provider_reconnect_buffered_stream(app_state: &AppState, stream_url: &Url, req_headers: &HeaderMap, - input: Option<&ConfigInput>, + input_headers: Option>, options: BufferStreamOptions) -> ProviderStreamResponse { - match create_provider_stream(cfg, Arc::clone(http_client), stream_url, req_headers, input, options).await { + match create_provider_stream(&app_state.config, Arc::clone(&app_state.http_client), stream_url, req_headers, input_headers, options).await { None => (None, None), Some((stream, info)) => { (Some(stream), info) diff --git a/src/api/model/streams/provider_stream_factory.rs b/src/api/model/streams/provider_stream_factory.rs index f536b5448..0a0c244c5 100644 --- a/src/api/model/streams/provider_stream_factory.rs +++ b/src/api/model/streams/provider_stream_factory.rs @@ -5,7 +5,7 @@ use crate::api::model::streams::buffered_stream::BufferedStream; use crate::api::model::streams::client_stream::ClientStream; use crate::api::model::streams::provider_stream::{create_channel_unavailable_stream, get_header_filter_for_item_type}; use crate::api::model::streams::timed_client_stream::{TimeoutClientStream}; -use crate::model::config::{Config, ConfigInput}; +use crate::model::config::{Config}; use crate::model::playlist::PlaylistItemType; use crate::tools::atomic_once_flag::AtomicOnceFlag; use crate::utils::debug_if_enabled; @@ -173,7 +173,7 @@ fn get_request_range_start_bytes(req_headers: &HashMap>) -> Opti fn get_client_stream_request_params( req_headers: &HeaderMap, - input: Option<&ConfigInput>, + input_headers: Option>, options: &BufferStreamOptions) -> (usize, Option, bool, u32, u32, HeaderMap) { let stream_buffer_size = if options.is_buffer_enabled() { options.get_stream_buffer_size() } else { 1 }; @@ -184,8 +184,6 @@ fn get_client_stream_request_params( let req_range_start_bytes = get_request_range_start_bytes(&req_headers); req_headers.remove("range"); - // These are the configured headers for this input. - let input_headers = input.map(|i| i.headers.clone()); // We merge configured input headers with the headers from the request. let headers = get_request_headers(input_headers.as_ref(), Some(&req_headers)); @@ -232,22 +230,22 @@ async fn provider_initial_request(cfg: &Config, request_client: Arc { - if let Some((boxed_provider_stream, response_info)) = + if let (Some(boxed_provider_stream), response_info) = create_channel_unavailable_stream(cfg, &get_response_headers(stream_options.get_headers()), StatusCode::BAD_GATEWAY) { - Ok(Some((boxed_provider_stream, Some(response_info)))) + Ok(Some((boxed_provider_stream, response_info))) } else { Err(StatusCode::SERVICE_UNAVAILABLE) } @@ -335,10 +333,10 @@ async fn get_initial_stream(cfg: &Config, client: Arc, stream_o fn create_provider_stream_options(stream_url: &Url, req_headers: &HeaderMap, - input: Option<&ConfigInput>, + input_headers: Option>, options: &BufferStreamOptions) -> ProviderStreamOptions { let (buffer_size, req_range_start_bytes, reconnect, reconnect_force_secs, connect_timeout_secs, headers) - = get_client_stream_request_params(req_headers, input, options); + = get_client_stream_request_params(req_headers, input_headers, options); let url = stream_url.clone(); let range_bytes = Arc::new(req_range_start_bytes.map(AtomicUsize::new)); let continue_flag = Arc::new(AtomicOnceFlag::new()); @@ -359,9 +357,9 @@ pub async fn create_provider_stream(cfg: &Config, client: Arc, stream_url: &Url, req_headers: &HeaderMap, - input: Option<&ConfigInput>, + input_headers: Option>, options: BufferStreamOptions) -> Option { - let stream_options = create_provider_stream_options(stream_url, req_headers, input, &options); + let stream_options = create_provider_stream_options(stream_url, req_headers, input_headers, &options); let client_stream_factory = |stream, reconnect_flag, range_cnt| { let stream = if stream_options.is_buffered() && !options.is_shared_stream() { diff --git a/src/model/api_proxy.rs b/src/model/api_proxy.rs index a7f441da8..ec826c4d3 100644 --- a/src/model/api_proxy.rs +++ b/src/model/api_proxy.rs @@ -206,6 +206,7 @@ impl ProxyUserCredentials { pub async fn has_connections_left(&self, app_state: &AppState) -> bool { if app_state.config.user_access_control { if let Some(max_connections) = self.max_connections.as_ref() { + // info!("{max_connections} : {}", app_state.get_active_connections_for_user(&self.username).await); if *max_connections < app_state.get_active_connections_for_user(&self.username).await { debug!("User access denied, too many connections: {}", self.username); return false; diff --git a/src/model/config.rs b/src/model/config.rs index 0c947de59..ebce3e029 100644 --- a/src/model/config.rs +++ b/src/model/config.rs @@ -649,6 +649,41 @@ pub struct InputUserInfo { pub password: String, } +impl InputUserInfo { + pub fn new(input_type: InputType, username: Option<&str>, password: Option<&str>, input_url: &str) -> Option { + if input_type == InputType::Xtream { + if let (Some(username), Some(password)) = (username, password) { + return Some(Self { + base_url: input_url.to_string(), + username: username.to_owned(), + password: password.to_owned(), + }); + } + } else if let Ok(url) = Url::parse(&input_url) { + let base_url = url.origin().ascii_serialization(); + let mut username = None; + let mut password = None; + for (key, value) in url.query_pairs() { + if key.eq("username") { + username = Some(value.into_owned()); + } else if key.eq("password") { + password = Some(value.into_owned()); + } + } + if username.is_some() || password.is_some() { + if let (Some(username), Some(password)) = (username.as_ref(), password.as_ref()) { + return Some(Self { + base_url, + username: username.to_owned(), + password: password.to_owned(), + }); + } + } + } + None + } +} + macro_rules! check_input_credentials { ($this:ident, $input_type:expr) => { match $input_type { @@ -756,36 +791,7 @@ impl ConfigInput { } pub fn get_user_info(&self) -> Option { - if self.input_type == InputType::Xtream { - if let (Some(username), Some(password)) = (self.username.as_ref(), self.password.as_ref()) { - return Some(InputUserInfo { - base_url: self.url.clone(), - username: username.to_owned(), - password: password.to_owned(), - }); - } - } else if let Ok(url) = Url::parse(&self.url) { - let base_url = url.origin().ascii_serialization(); - let mut username = None; - let mut password = None; - for (key, value) in url.query_pairs() { - if key.eq("username") { - username = Some(value.into_owned()); - } else if key.eq("password") { - password = Some(value.into_owned()); - } - } - if username.is_some() || password.is_some() { - if let (Some(username), Some(password)) = (username.as_ref(), password.as_ref()) { - return Some(InputUserInfo { - base_url, - username: username.to_owned(), - password: password.to_owned(), - }); - } - } - } - None + InputUserInfo::new(self.input_type.clone(), self.username.as_deref(), self.password.as_deref(), &self.url) } } @@ -1336,6 +1342,17 @@ impl Config { None } + pub fn get_input_options_by_name(&self, input_name: &str) -> Option<&ConfigInputOptions> { + for source in &self.sources { + for input in &source.inputs { + if input.name == input_name { + return input.options.as_ref(); + } + } + } + None + } + pub fn get_input_by_id(&self, input_id: u16) -> Option<&ConfigInput> { for source in &self.sources { for input in &source.inputs { diff --git a/src/model/hls.rs b/src/model/hls.rs index b9283cc85..b020f8cd9 100644 --- a/src/model/hls.rs +++ b/src/model/hls.rs @@ -5,9 +5,9 @@ use crate::model::config::TargetType; #[derive(Clone)] pub struct HlsEntry { pub ts: Instant, - pub token: String, + pub token: u32, pub target_type: TargetType, - pub input_name: String, + pub input_id: u16, pub virtual_id: u32, pub chunk: u32, pub chunks: HashMap, diff --git a/src/model/playlist.rs b/src/model/playlist.rs index 4ac1fd00d..64e4d6429 100644 --- a/src/model/playlist.rs +++ b/src/model/playlist.rs @@ -74,7 +74,7 @@ impl TryFrom for XtreamCluster { type Error = String; fn try_from(item_type: PlaylistItemType) -> Result { match item_type { - PlaylistItemType::Live | PlaylistItemType::LiveHls | PlaylistItemType::LiveUnknown => Ok(Self::Live), + PlaylistItemType::Live | PlaylistItemType::LiveHls | PlaylistItemType::LiveDash | PlaylistItemType::LiveUnknown => Ok(Self::Live), PlaylistItemType::Video => Ok(Self::Video), PlaylistItemType::Series => Ok(Self::Series), _ => Err(format!("Cant convert {item_type}")), @@ -93,6 +93,7 @@ pub enum PlaylistItemType { Catchup = 5, LiveUnknown = 6, // No Provider id LiveHls = 7, // m3u8 entry + LiveDash = 8, // mpd } impl From for PlaylistItemType { @@ -116,7 +117,7 @@ impl PlaylistItemType { impl Display for PlaylistItemType { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", match self { - Self::Live | Self::LiveHls | Self::LiveUnknown => Self::LIVE, + Self::Live | Self::LiveHls | Self::LiveDash |Self::LiveUnknown => Self::LIVE, Self::Video => Self::VIDEO, Self::Series => Self::SERIES, Self::SeriesInfo => Self::SERIES_INFO, diff --git a/src/processing/parser/hls.rs b/src/processing/parser/hls.rs index b47e672b8..8bacf461d 100644 --- a/src/processing/parser/hls.rs +++ b/src/processing/parser/hls.rs @@ -4,14 +4,14 @@ use crate::model::hls::HlsEntry; use std::collections::HashMap; use std::str; use tokio::time::Instant; -use crate::utils::hash_utils::uuid_v4; use crate::utils::string_utils::replace_after_last_slash; pub const HLS_PREFIX: &str = "hls"; -pub fn rewrite_hls(base_url: &str, content: &str, hls_url: &str, virtual_id: u32, user: &ProxyUserCredentials, - target_type: &TargetType, input_name: &str) -> (HlsEntry, String) { - let token = uuid_v4(); +pub fn rewrite_hls(base_url: &str, content: &str, hls_url: &str, virtual_id: u32, + token: u32, + user: &ProxyUserCredentials, + target_type: &TargetType, input_id: u16) -> (HlsEntry, String) { let username = &user.username; let password = &user.password; let mut chunk: u32 = 1; @@ -36,7 +36,7 @@ pub fn rewrite_hls(base_url: &str, content: &str, hls_url: &str, virtual_id: u32 ts: Instant::now(), token, target_type: target_type.clone(), - input_name: input_name.to_string(), + input_id, virtual_id, chunk, chunks, diff --git a/src/processing/processor/xtream.rs b/src/processing/processor/xtream.rs index 8fd2863cc..7b2f6215d 100644 --- a/src/processing/processor/xtream.rs +++ b/src/processing/processor/xtream.rs @@ -49,7 +49,7 @@ pub(in crate::processing) fn write_info_content_to_wal_file(writer: &mut BufWrit } pub(in crate::processing) fn create_resolve_episode_wal_files(cfg: &Config, input: &ConfigInput) -> Option<(File, PathBuf)> { - match get_input_storage_path(input, &cfg.working_dir) { + match get_input_storage_path(&input.name, &cfg.working_dir) { Ok(storage_path) => { let info_path = storage_path.join(format!("{FILE_SERIES_EPISODE_RECORD}.{FILE_SUFFIX_WAL}")); let info_file = append_or_crate_file(&info_path).ok()?; @@ -60,7 +60,7 @@ pub(in crate::processing) fn create_resolve_episode_wal_files(cfg: &Config, inpu } pub(in crate::processing) fn create_resolve_info_wal_files(cfg: &Config, input: &ConfigInput, cluster: XtreamCluster) -> Option<(File, File, PathBuf, PathBuf)> { - match get_input_storage_path(input, &cfg.working_dir) { + match get_input_storage_path(&input.name, &cfg.working_dir) { Ok(storage_path) => { if let Some(file_prefix) = match cluster { XtreamCluster::Live => None, @@ -96,12 +96,12 @@ where { let mut processed_info_ids = HashMap::new(); - let file_path = match get_input_storage_path(fpl.input, &cfg.working_dir) + let fpl_name = &fpl.input.name; + let file_path = match get_input_storage_path(fpl_name, &cfg.working_dir) .map(|storage_path| xtream_get_record_file_path(&storage_path, item_type)).and_then(|opt| opt.ok_or_else(|| str_to_io_error("Not supported"))) { Ok(file_path) => file_path, Err(err) => { - let fpl_name = &fpl.input.name; errors.push(notify_err!(format!("Could not create storage path for input {fpl_name}: {err}"))); return processed_info_ids; } diff --git a/src/processing/processor/xtream_series.rs b/src/processing/processor/xtream_series.rs index 10bb47f77..0154d05db 100644 --- a/src/processing/processor/xtream_series.rs +++ b/src/processing/processor/xtream_series.rs @@ -139,7 +139,7 @@ async fn process_series_info( let mut result: Vec = vec![]; let input = fpl.input; - let Ok(Some((info_path, idx_path))) = get_input_storage_path(input, &cfg.working_dir) + let Ok(Some((info_path, idx_path))) = get_input_storage_path(&input.name, &cfg.working_dir) .map(|storage_path| xtream_get_info_file_paths(&storage_path, XtreamCluster::Series)) else { errors.push(notify_err!("Failed to open input info file for series".to_string())); diff --git a/src/repository/kodi_repository.rs b/src/repository/kodi_repository.rs index a7e7f4a8c..1f0ec438b 100644 --- a/src/repository/kodi_repository.rs +++ b/src/repository/kodi_repository.rs @@ -305,46 +305,44 @@ async fn get_tmdb_value( } } std::collections::hash_map::Entry::Vacant(entry) => { - if let Some(input) = cfg.get_input_by_name(input_name) { - if let Ok(Some(tmdb_path)) = get_input_storage_path(input, &cfg.working_dir) - .map(|storage_path| xtream_get_record_file_path(&storage_path, item_type)) + if let Ok(Some(tmdb_path)) = get_input_storage_path(input_name, &cfg.working_dir) + .map(|storage_path| xtream_get_record_file_path(&storage_path, item_type)) + { { - { - let file_lock = cfg.file_locks.read_lock(&tmdb_path).await; - match item_type { - PlaylistItemType::Series => { - if let Ok(tree) = - BPlusTree::::load(&tmdb_path) - { - let tmdb_id = tree.query(&pid).map(|episode| { - InputTmdbIndexValue::Series(episode.clone()) - }); - entry.insert(Some(( - file_lock, - InputTmdbIndexTree::Series(tree), - ))); - return tmdb_id; - } + let file_lock = cfg.file_locks.read_lock(&tmdb_path).await; + match item_type { + PlaylistItemType::Series => { + if let Ok(tree) = + BPlusTree::::load(&tmdb_path) + { + let tmdb_id = tree.query(&pid).map(|episode| { + InputTmdbIndexValue::Series(episode.clone()) + }); + entry.insert(Some(( + file_lock, + InputTmdbIndexTree::Series(tree), + ))); + return tmdb_id; } - PlaylistItemType::Video => { - if let Ok(tree) = - BPlusTree::::load(&tmdb_path) - { - let tmdb_id = tree.query(&pid).map(|vod_record| { - InputTmdbIndexValue::Video(vod_record.clone()) - }); - entry.insert(Some(( - file_lock, - InputTmdbIndexTree::Video(tree), - ))); - return tmdb_id; - } - } - _ => {} } - }; + PlaylistItemType::Video => { + if let Ok(tree) = + BPlusTree::::load(&tmdb_path) + { + let tmdb_id = tree.query(&pid).map(|vod_record| { + InputTmdbIndexValue::Video(vod_record.clone()) + }); + entry.insert(Some(( + file_lock, + InputTmdbIndexTree::Video(tree), + ))); + return tmdb_id; + } + } + _ => {} + } }; - } + }; entry.insert(None); None } diff --git a/src/repository/m3u_playlist_iterator.rs b/src/repository/m3u_playlist_iterator.rs index 175e34ad2..ee204f6b5 100644 --- a/src/repository/m3u_playlist_iterator.rs +++ b/src/repository/m3u_playlist_iterator.rs @@ -70,6 +70,7 @@ impl M3uPlaylistIterator { | PlaylistItemType::Catchup | PlaylistItemType::LiveUnknown | PlaylistItemType::LiveHls => "live", + | PlaylistItemType::LiveDash => "live", PlaylistItemType::Video => "movie", PlaylistItemType::Series | PlaylistItemType::SeriesInfo => "series", diff --git a/src/repository/playlist_repository.rs b/src/repository/playlist_repository.rs index 900e7d23b..cc0fa6900 100644 --- a/src/repository/playlist_repository.rs +++ b/src/repository/playlist_repository.rs @@ -1,5 +1,4 @@ -use std::path::{Path}; -use crate::m3u_filter_error::{info_err}; +use crate::m3u_filter_error::info_err; use crate::m3u_filter_error::{M3uFilterError, M3uFilterErrorKind}; use crate::model::config::{Config, ConfigTarget, TargetOutput}; use crate::model::playlist::{PlaylistGroup, PlaylistItemType}; @@ -11,7 +10,8 @@ use crate::repository::storage::{ensure_target_storage_path, get_target_id_mappi use crate::repository::target_id_mapping::TargetIdMapping; use crate::repository::xtream_repository::xtream_write_playlist; use crate::utils::file::file_lock_manager::FileWriteGuard; -use crate::utils::network::request::is_hls_url; +use crate::utils::network::request::{is_dash_url, is_hls_url}; +use std::path::Path; pub async fn persist_playlist(playlist: &mut [PlaylistGroup], epg: Option<&Epg>, target: &ConfigTarget, cfg: &Config) -> Result<(), Vec> { @@ -31,7 +31,13 @@ pub async fn persist_playlist(playlist: &mut [PlaylistGroup], epg: Option<&Epg>, if provider_id == 0 { header.item_type = match (is_hls_url(&header.url), header.item_type) { (true, _) => PlaylistItemType::LiveHls, - (false, PlaylistItemType::Live) => PlaylistItemType::LiveUnknown, + (false, PlaylistItemType::Live) => { + if is_dash_url(&header.url) { + PlaylistItemType::LiveDash + } else { + PlaylistItemType::LiveUnknown + } + } _ => header.item_type, }; } diff --git a/src/repository/storage.rs b/src/repository/storage.rs index 8d1c273e7..8ac586f61 100644 --- a/src/repository/storage.rs +++ b/src/repository/storage.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use std::fmt::Write; use crate::m3u_filter_error::{M3uFilterError, M3uFilterErrorKind}; -use crate::model::config::{Config, ConfigInput}; +use crate::model::config::{Config}; use crate::model::playlist::UUIDType; use crate::m3u_filter_error::{notify_err}; use crate::utils::file::file_utils; @@ -56,8 +56,8 @@ pub fn get_target_storage_path(cfg: &Config, target_name: &str) -> Option std::io::Result { - let name = format!("input_{}", &input.name); +pub fn get_input_storage_path(input_name: &str, working_dir: &str) -> std::io::Result { + let name = format!("input_{input_name}"); let path = Path::new(working_dir).join(name); // Create the directory and return the path or propagate the error std::fs::create_dir_all(&path).map(|()| path) diff --git a/src/repository/xtream_repository.rs b/src/repository/xtream_repository.rs index 1ef47152e..b193c2314 100644 --- a/src/repository/xtream_repository.rs +++ b/src/repository/xtream_repository.rs @@ -744,7 +744,7 @@ pub fn xtream_get_input_info( provider_id: u32, cluster: XtreamCluster, ) -> Option { - if let Ok(Some((info_path, idx_path))) = get_input_storage_path(input, &cfg.working_dir).map(|storage_path| xtream_get_info_file_paths(&storage_path, cluster)) + if let Ok(Some((info_path, idx_path))) = get_input_storage_path(&input.name, &cfg.working_dir).map(|storage_path| xtream_get_info_file_paths(&storage_path, cluster)) { let _file_lock = cfg.file_locks.read_lock(&info_path); if let Ok(content) = IndexedDocumentDirectAccess::read_indexed_item::(&info_path, &idx_path, &provider_id) { @@ -760,7 +760,7 @@ pub async fn xtream_update_input_info_file( wal_path: &Path, cluster: XtreamCluster, ) -> Result<(), M3uFilterError> { - match get_input_storage_path(input, &cfg.working_dir).map(|storage_path| xtream_get_info_file_paths(&storage_path, cluster)) { + match get_input_storage_path(&input.name, &cfg.working_dir).map(|storage_path| xtream_get_info_file_paths(&storage_path, cluster)) { Ok(Some((info_path, idx_path))) => { { let _file_lock = cfg.file_locks.write_lock(&info_path); @@ -803,7 +803,7 @@ pub async fn xtream_update_input_vod_record_from_wal_file( input: &ConfigInput, wal_path: &Path, ) -> Result<(), M3uFilterError> { - let record_path = get_input_storage_path(input, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::Video)) + let record_path = get_input_storage_path(&input.name, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::Video)) .map_err(|err| notify_err!(format!("Error accessing storage path: {err}"))) .and_then(|opt| opt.ok_or_else(|| notify_err!(format!("Error accessing storage path for input: {}", &input.name))))?; @@ -843,7 +843,7 @@ pub async fn xtream_update_input_series_record_from_wal_file( input: &ConfigInput, wal_path: &Path, ) -> Result<(), M3uFilterError> { - let record_path = get_input_storage_path(input, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::SeriesInfo)) + let record_path = get_input_storage_path(&input.name, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::SeriesInfo)) .map_err(|err| notify_err!(format!("Error accessing storage path: {err}"))) .and_then(|opt| opt.ok_or_else(|| notify_err!(format!("Error accessing storage path for input: {}", &input.name))))?; { @@ -877,7 +877,7 @@ pub async fn xtream_update_input_series_episodes_record_from_wal_file( input: &ConfigInput, wal_path: &Path, ) -> Result<(), M3uFilterError> { - let record_path = get_input_storage_path(input, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::Series)) + let record_path = get_input_storage_path(&input.name, &cfg.working_dir).map(|storage_path| xtream_get_record_file_path(&storage_path, PlaylistItemType::Series)) .map_err(|err| notify_err!(format!("Error accessing storage path: {err}"))) .and_then(|opt| opt.ok_or_else(|| notify_err!(format!("Error accessing storage path for input: {}", &input.name))))?; { diff --git a/src/utils/hash_utils.rs b/src/utils/hash_utils.rs index d5d2026c1..7adf72410 100644 --- a/src/utils/hash_utils.rs +++ b/src/utils/hash_utils.rs @@ -22,8 +22,3 @@ pub fn generate_playlist_uuid(key: &str, provider_id: &str, item_type: PlaylistI } hash_string(url) } - -#[inline] -pub fn uuid_v4() -> String { - uuid::Uuid::new_v4().to_string().replace('-', "") -} diff --git a/src/utils/network/request.rs b/src/utils/network/request.rs index 7221dd5ef..a4d612dd8 100644 --- a/src/utils/network/request.rs +++ b/src/utils/network/request.rs @@ -27,6 +27,7 @@ use crate::m3u_filter_error::create_m3u_filter_error_result; use crate::utils::debug_if_enabled; pub const HLS_EXT: &str = ".m3u8"; +pub const DASH_EXT: &str = ".mpd"; pub const fn bytes_to_megabytes(bytes: u64) -> u64 { bytes / 1_048_576 @@ -289,7 +290,7 @@ pub async fn download_text_content_as_file(client: Arc, input: Err(Error::new(ErrorKind::NotFound, format!("Unknown file {file_path:?}"))) }) } else { - let file_path = persist_filepath.map_or_else(|| match get_input_storage_path(input, working_dir) { + let file_path = persist_filepath.map_or_else(|| match get_input_storage_path(&input.name, working_dir) { Ok(download_path) => { Ok(download_path.join(FILE_EPG)) } @@ -430,12 +431,20 @@ pub fn classify_content_type(headers: &[(String, String)]) -> MimeCategory { const HLS_EXT_QUERY: &str = ".m3u8?"; const HLS_EXT_FRAGMENT: &str = ".m3u8#"; +const DASH_EXT_QUERY: &str = ".mpd?"; +const DASH_EXT_FRAGMENT: &str = ".mpd#"; + pub fn is_hls_url(url: &str) -> bool { let lc_url = url.to_lowercase(); lc_url.ends_with(HLS_EXT) || lc_url.contains(HLS_EXT_QUERY) || lc_url.contains(HLS_EXT_FRAGMENT) } +pub fn is_dash_url(url: &str) -> bool { + let lc_url = url.to_lowercase(); + lc_url.ends_with(DASH_EXT) || lc_url.contains(DASH_EXT_QUERY) || lc_url.contains(DASH_EXT_FRAGMENT) +} + pub fn replace_url_extension(url: &str, new_ext: &str) -> String { let ext = new_ext.strip_prefix('.').unwrap_or(new_ext); // Remove leading dot if exists