CRIT-1: ExtractionError::Deobfuscation is now switchable.
Deobfuscator gains has_sig()/has_nsig() — deobfuscate_sig/_nsig
short-circuit with a recognisable error class so cipher streams
on the wrong client fall through to the next client in the chain
instead of killing the whole call.
CRIT-2: Soft-failed DeobfData now caches with a 1-hour retry instead of
living for 24h. Re-extraction kicks in automatically once YT
rotates back to a player.js shape we recognise — no more
wall-clock-day-of-poisoned-cache.
HIGH-1: Reporter now emits a Level::WRN `extract_deobf_soft_fail` report
on partial extraction. straw / torttube get an artefact when
sig/nsig regex starts missing.
HIGH-2: player_client_order branches on opts.auth. With botguard
+ authed-cookie users, Desktop is now position 2 (where their
cookie maps to an OAuth session) instead of position 4.
HIGH-3: Android dropped from the default order. needs_po_token doesn't
flag Android, so requests were firing unsigned and tripping
YT's bot-check rejection — which is also not switchable.
Re-add when a real po_token strategy lands.
MED-1: Comment in needs_deobf softened — the iOS/Android-no-deobf
property is a current YT behaviour, not a permanent protocol.
MED-2: Cargo.toml workspace pin bumped 0.11.4 → 0.11.5 so it matches
the package version (avoids future 0.12.x bump surprises).
MED-3: Smoke test fixture uses an isolated per-process scratch dir
instead of the repo root, avoiding cache-race with
tests/youtube.rs (which uses CARGO_MANIFEST_DIR and could
wipe OAuth tokens).
LOW-1: Misleading "dead-code fallback" comment in extract_fns replaced
with the actual behaviour description.
LOW-2: get_deobf_data uses read-then-write — concurrent player calls
on warm cache no longer serialise on the write lock.
LOW-3: Smoke test catches IpBan via exact UnavailabilityReason match
instead of substring "Sign in/IpBan/bot" — a real regression
won't silently pass anymore.
LOW-4: TV smoke test now asserts !audio_streams.is_empty() too,
matching iOS / default-order tests.
LOW-5: needs_deobf comment notes YT's historical n= experiments on
Android — sets expectation for future review passes.
132 lines
3.5 KiB
TOML
132 lines
3.5 KiB
TOML
[package]
|
|
name = "rustypipe"
|
|
version = "0.11.5"
|
|
rust-version = "1.67.1"
|
|
edition.workspace = true
|
|
authors.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
keywords.workspace = true
|
|
categories.workspace = true
|
|
description = "Client for the public YouTube / YouTube Music API (Innertube), inspired by NewPipe"
|
|
|
|
include = ["/src", "README.md", "CHANGELOG.md", "LICENSE", "!snapshots"]
|
|
|
|
[workspace]
|
|
members = [".", "codegen", "downloader", "cli"]
|
|
|
|
[workspace.package]
|
|
edition = "2021"
|
|
authors = ["ThetaDev <thetadev@magenta.de>"]
|
|
license = "GPL-3.0"
|
|
repository = "https://codeberg.org/ThetaDev/rustypipe"
|
|
keywords = ["youtube", "video", "music"]
|
|
categories = ["api-bindings", "multimedia"]
|
|
|
|
[workspace.dependencies]
|
|
rquickjs = "0.9.0"
|
|
once_cell = "1.12.0"
|
|
regex = "1.6.0"
|
|
fancy-regex = "0.14.0"
|
|
thiserror = "2.0.0"
|
|
url = "2.2.0"
|
|
reqwest = { version = "0.12.0", default-features = false }
|
|
tokio = "1.20.4"
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0.82"
|
|
serde_with = { version = "3.0.0", default-features = false, features = [
|
|
"alloc",
|
|
"macros",
|
|
] }
|
|
serde_plain = "1.0.0"
|
|
sha1 = "0.10.0"
|
|
rand = "0.9.0"
|
|
time = { version = "0.3.37", features = [
|
|
"macros",
|
|
"serde-human-readable",
|
|
"serde-well-known",
|
|
"local-offset",
|
|
] }
|
|
futures-util = "0.3.31"
|
|
ress = "0.11.0"
|
|
phf = "0.11.0"
|
|
phf_codegen = "0.11.0"
|
|
data-encoding = "2.0.0"
|
|
urlencoding = "2.1.0"
|
|
quick-xml = { version = "0.37.0", features = ["serialize"] }
|
|
tracing = { version = "0.1.0", features = ["log"] }
|
|
localzone = "0.3.1"
|
|
|
|
# CLI
|
|
indicatif = "0.17.0"
|
|
anyhow = "1.0"
|
|
clap = { version = "4.0.0", features = ["derive"] }
|
|
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
|
serde_yaml = "0.9.0"
|
|
dirs = "6.0.0"
|
|
filenamify = "0.1.0"
|
|
|
|
# Testing
|
|
rstest = "0.25.0"
|
|
tokio-test = "0.4.2"
|
|
insta = { version = "1.17.1", features = ["ron", "redactions"] }
|
|
path_macro = "1.0.0"
|
|
tracing-test = "0.2.5"
|
|
|
|
# Included crates
|
|
rustypipe = { path = ".", version = "0.11.5", default-features = false }
|
|
rustypipe-downloader = { path = "./downloader", version = "0.3.1", default-features = false, features = [
|
|
"indicatif",
|
|
"audiotag",
|
|
] }
|
|
|
|
[features]
|
|
default = ["default-tls"]
|
|
|
|
rss = ["dep:quick-xml"]
|
|
userdata = []
|
|
|
|
# Reqwest TLS options
|
|
default-tls = ["reqwest/default-tls"]
|
|
native-tls = ["reqwest/native-tls"]
|
|
native-tls-alpn = ["reqwest/native-tls-alpn"]
|
|
native-tls-vendored = ["reqwest/native-tls-vendored"]
|
|
rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots"]
|
|
rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"]
|
|
|
|
[dependencies]
|
|
rquickjs.workspace = true
|
|
once_cell.workspace = true
|
|
regex.workspace = true
|
|
fancy-regex.workspace = true
|
|
thiserror.workspace = true
|
|
url.workspace = true
|
|
reqwest = { workspace = true, features = ["json", "gzip", "brotli"] }
|
|
tokio = { workspace = true, features = ["macros", "time", "process"] }
|
|
serde.workspace = true
|
|
serde_json.workspace = true
|
|
serde_with.workspace = true
|
|
serde_plain.workspace = true
|
|
sha1.workspace = true
|
|
rand.workspace = true
|
|
time.workspace = true
|
|
ress.workspace = true
|
|
phf.workspace = true
|
|
data-encoding.workspace = true
|
|
urlencoding.workspace = true
|
|
tracing.workspace = true
|
|
localzone.workspace = true
|
|
quick-xml = { workspace = true, optional = true }
|
|
|
|
[dev-dependencies]
|
|
rstest.workspace = true
|
|
tokio-test.workspace = true
|
|
insta.workspace = true
|
|
path_macro.workspace = true
|
|
tracing-test.workspace = true
|
|
|
|
[package.metadata.docs.rs]
|
|
# To build locally:
|
|
# RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --features rss,userdata --no-deps --open
|
|
features = ["rss", "userdata"]
|
|
rustdoc-args = ["--cfg", "docsrs"]
|