Stage 1-2 of the crabidy-store dev-flow (architecture/crabidy-store.md, quality/, plan/): one /crabidy provider replacing queues/bookmarks/ captures, with track tomls linking into a content-addressed store that de-duplicates by provider id and content hash. Additive, build stays green: - proto: Track.provider_item_id + is_captured; LibraryNode.is_captured; LibraryNodeChild.is_captured (swept all literals). - fsdy: Playable::Store + PlayableSpec.store, 5-way cardinality, from_track_store, Client.with_store_root + store resolution. - crabidy_store.rs: StoreSidecar/ProviderEntry/StoreIndex/CrabidyStore type + method surface (bodies stubbed for the implement stage). - supersede bookmarks/captures/capture-deletion docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
README.md
ytdy — the YouTube provider
Mounts YouTube at /youtube in the crabidy library.
How it works
Metadata comes from the pure-Rust rustypipe Innertube client:
/youtube/searchworks without any login. Press%to create a search term; the term becomes a persistent child node listing the top video results as tracks. Terms are renamable (e, re-runs the search) and deletable (d). Terms live in memory — a server restart forgets them, but navigating to an old term path recreates it./youtube/playlistsappears when a cookie login is configured and accepted: it lists the account's saved playlists.
Stream URLs are resolved through a minimal yt-dlp sidecar when
the binary is available (one bounded subprocess call per played or
captured track — no other functionality uses it). This is a deliberate
concession: YouTube currently caps tokenless stream URLs at their
leading ~1 MiB, and yt-dlp is the only maintained solver for the
cipher challenges that lift the cap; its URLs stream whole files at a
throttled ~32 KB/s (still ~2× audio bitrate). Without the binary the
provider still works, but playback of a track stops after roughly a
minute. Streams prefer audio/mp4 (AAC), the format the built-in
player decodes; captures therefore store .m4a files. See
architecture/youtube-rustypipe.md for the full analysis.
Search results and playlists are downloadable: W captures them with
audio into /captures/<name> (slow under the throttle, but captures
are resumable — re-capture the same name to continue).
Configuration — ~/.config/crabidy/ytdy.toml
All options with their defaults:
# Netscape cookies.txt export for the logged-in features (saved
# playlists). Export with a browser extension like "Get cookies.txt
# LOCALLY", ideally from an Incognito session you close afterwards.
# The provider caches the rotated session cookie under
# ~/.config/crabidy/rustypipe/, so the export only needs to be valid
# once. Default: unset (logged out; search still works).
# cookies = "/home/me/youtube-cookies.txt"
# Results per search term. Default: 20.
# search_results = 20
# Per-request timeout in seconds (Innertube calls; the yt-dlp sidecar
# gets at least 60 s). Default: 30.
# call_timeout_secs = 30
# The yt-dlp binary used ONLY for stream URLs. A bare name resolves
# via PATH. Default: "yt-dlp". Keep it fresh — a stale yt-dlp is the
# first suspect when YouTube playback breaks.
# binary = "yt-dlp"
# Optional rustypipe-botguard binary for PO-token attestation (also
# auto-detected on PATH). Currently ineffective upstream, but once
# rustypipe's web-client deciphering is fixed this makes streams work
# without yt-dlp. Default: unset.
# botguard_bin = "/home/me/.cargo/bin/rustypipe-botguard"
Secrets: the cookies file and the rustypipe cache grant access to your YouTube session — keep both private. The provider never logs their contents (paths only), and stream URLs are redacted from logs.
Failure behavior
- No network / broken client at startup: only
/youtubeis disabled, the server runs on. - Rejected or missing cookies: degrades to logged-out with a warning.
- Missing
yt-dlp: warning at startup; streams stop after ~1 MiB. 403 Forbiddenon streams in the log: YouTube's per-IP/per-video enforcement fluctuates; usually transient. If it persists, updateyt-dlp.