diff --git a/Cargo.lock b/Cargo.lock index 7c2a6f4..99b223b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,6 +220,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.35" @@ -378,7 +384,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.2.5" +version = "3.3.0" dependencies = [ "chrono", "clap", @@ -391,7 +397,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.2.5" +version = "3.3.0" dependencies = [ "anyhow", "async-speed-limit", @@ -408,7 +414,7 @@ dependencies = [ "indicatif", "lazy_static", "log", - "nix", + "nix 0.28.0", "num_cpus", "regex", "reqwest", @@ -479,7 +485,7 @@ version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" dependencies = [ - "nix", + "nix 0.27.1", "windows-sys 0.52.0", ] @@ -1174,6 +1180,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -1441,7 +1459,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -1515,12 +1533,13 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.1.1", + "rustls-pki-types", "schannel", "security-framework", ] @@ -1534,6 +1553,16 @@ dependencies = [ "base64", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +dependencies = [ + "base64", + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.3.1" diff --git a/Cargo.toml b/Cargo.toml index 01c5be1..cf4f676 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.2.5" +version = "3.3.0" edition = "2021" license = "MIT" @@ -14,7 +14,7 @@ openssl-tls = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli- openssl-tls-static = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli-core/openssl-tls-static"] [dependencies] -tokio = { version = "1.35", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.36", features = ["macros", "rt-multi-thread", "time"], default-features = false } native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } @@ -22,8 +22,8 @@ crunchy-cli-core = { path = "./crunchy-cli-core" } [build-dependencies] chrono = "0.4" -clap = { version = "4.4", features = ["string"] } -clap_complete = "4.4" +clap = { version = "4.5", features = ["string"] } +clap_complete = "4.5" clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } diff --git a/README.md b/README.md index 57a8b7c..46bee72 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,8 @@ You can set specific settings which will be The `--proxy` flag supports https and socks5 proxies to route all your traffic through. This may be helpful to bypass the geo-restrictions Crunchyroll has on certain series. + You are also able to set in which part of the cli a proxy should be used. + Instead of a normal url you can also use: `:` (only proxies api requests), `:` (only proxies download traffic), `:` (proxies api requests through the first url and download traffic through the second url). ```shell $ crunchy-cli --proxy socks5://127.0.0.1:8080 @@ -283,6 +285,14 @@ The `download` command lets you download episodes with a specific audio language Default is the template, set by the `-o` / `--output` flag. See the [Template Options section](#output-template-options) below for more options. +- Universal output + + The output template options can be forced to get sanitized via the `--universal-output` flag to be valid across all supported operating systems (Windows has a lot of characters which aren't allowed in filenames...). + + ```shell + $ crunchy-cli download --universal-output -o https://www.crunchyroll.com/watch/G7PU4XD48/tales-veldoras-journal-2 + ``` + - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. @@ -293,6 +303,15 @@ The `download` command lets you download episodes with a specific audio language Default is `best`. +- Language tagging + + You can force the usage of a specific language tagging in the output file with the `--language-tagging` flag. + This might be useful as some video players doesn't recognize the language tagging Crunchyroll uses internally. + + ```shell + $ crunchy-cli download --language-tagging ietf https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` + - FFmpeg Preset You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. @@ -327,6 +346,15 @@ The `download` command lets you download episodes with a specific audio language $ crunchy-cli download --skip-specials https://www.crunchyroll.com/series/GYZJ43JMR/that-time-i-got-reincarnated-as-a-slime[S2] ``` +- Include chapters + + Crunchyroll sometimes provide information about skippable events like the intro or credits. + These information can be stored as chapters in the resulting video file via the `--include-chapters` flag. + + ```shell + $ crunchy-cli download --include-chapters https://www.crunchyroll.com/watch/G0DUND0K2/the-journeys-end + ``` + - Yes Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. @@ -416,6 +444,14 @@ The `archive` command lets you download episodes with multiple audios and subtit Default is the template, set by the `-o` / `--output` flag. See the [Template Options section](#output-template-options) below for more options. +- Universal output + + The output template options can be forced to get sanitized via the `--universal-output` flag to be valid across all supported operating systems (Windows has a lot of characters which aren't allowed in filenames...). + + ```shell + $ crunchy-cli archive --universal-output -o https://www.crunchyroll.com/watch/G7PU4XD48/tales-veldoras-journal-2 + ``` + - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. @@ -441,6 +477,26 @@ The `archive` command lets you download episodes with multiple audios and subtit Default is `auto`. +- Merge auto tolerance + + Sometimes two video tracks are downloaded with `--merge` set to `auto` even if they only differ some milliseconds in length which shouldn't be noticeable to the viewer. + To prevent this, you can specify a range in milliseconds with the `--merge-auto-tolerance` flag that only downloads one video if the length difference is in the given range. + + ```shell + $ crunchy-cli archive -m auto --merge-auto-tolerance 100 https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + + Default are `200` milliseconds. + +- Language tagging + + You can force the usage of a specific language tagging in the output file with the `--language-tagging` flag. + This might be useful as some video players doesn't recognize the language tagging Crunchyroll uses internally. + + ```shell + $ crunchy-cli archive --language-tagging ietf https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + - FFmpeg Preset You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. @@ -477,6 +533,16 @@ The `archive` command lets you download episodes with multiple audios and subtit $ crunchy-cli archive --include-fonts https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` +- Include chapters + + Crunchyroll sometimes provide information about skippable events like the intro or credits. + These information can be stored as chapters in the resulting video file via the `--include-chapters` flag. + This flag only works if `--merge` is set to `audio` because chapters cannot be mapped to a specific video steam. + + ```shell + $ crunchy-cli archive --include-chapters https://www.crunchyroll.com/watch/G0DUND0K2/the-journeys-end + ``` + - Skip existing If you re-download a series but want to skip episodes you've already downloaded, the `--skip-existing` flag skips the already existing/downloaded files. @@ -485,6 +551,16 @@ The `archive` command lets you download episodes with multiple audios and subtit $ crunchy-cli archive --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` +- Skip existing method + + By default, already existing files are determined by their name and the download of the corresponding episode is skipped. + But sometimes Crunchyroll adds dubs or subs to an already existing episode and these changes aren't recognized and `--skip-existing` just skips it. + This behavior can be changed by the `--skip-existing-method` flag. Valid options are `audio` and `subtitle` (if the file already exists but the audio/subtitle are less from what should be downloaded, the episode gets downloaded and the file overwritten). + + ```shell + $ crunchy-cli archive --skip-existing-method audio --skip-existing-method video https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + - Skip specials If you doesn't want to download special episodes, use the `--skip-specials` flag to skip the download of them. diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 2d3ac61..fcb178a 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli-core" authors = ["Crunchy Labs Maintainers"] -version = "3.2.5" +version = "3.3.0" edition = "2021" license = "MIT" @@ -14,7 +14,7 @@ openssl-tls-static = ["reqwest/native-tls", "reqwest/native-tls-alpn", "reqwest/ [dependencies] anyhow = "1.0" async-speed-limit = "0.4" -clap = { version = "4.4", features = ["derive", "string"] } +clap = { version = "4.5", features = ["derive", "string"] } chrono = "0.4" crunchyroll-rs = { version = "0.8.5", features = ["dash-stream", "experimental-stabilizations", "tower"] } ctrlc = "3.4" @@ -33,16 +33,16 @@ reqwest = { version = "0.11", default-features = false, features = ["socks", "st serde = "1.0" serde_json = "1.0" serde_plain = "1.0" -shlex = "1.2" +shlex = "1.3" sys-locale = "0.3" -tempfile = "3.9" -tokio = { version = "1.35", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] } +tempfile = "3.10" +tokio = { version = "1.36", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] } tokio-util = "0.7" tower-service = "0.3" -rustls-native-certs = { version = "0.6", optional = true } +rustls-native-certs = { version = "0.7", optional = true } [target.'cfg(not(target_os = "windows"))'.dependencies] -nix = { version = "0.27", features = ["fs"] } +nix = { version = "0.28", features = ["fs"] } [build-dependencies] chrono = "0.4" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 38f22f4..8067c42 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -374,9 +374,8 @@ fn reqwest_client(proxy: Option, user_agent: Option) -> Client { let mut builder = builder.use_native_tls().tls_built_in_root_certs(false); for certificate in rustls_native_certs::load_native_certs().unwrap() { - builder = builder.add_root_certificate( - reqwest::Certificate::from_der(certificate.0.as_slice()).unwrap(), - ) + builder = + builder.add_root_certificate(reqwest::Certificate::from_der(&certificate).unwrap()) } builder.build().unwrap()