summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-09-21 08:38:50 +0000
committerClaude <noreply@anthropic.com>2026-09-21 08:38:50 +0000
commit433866c912a5dc687c02bf597eff093e3b2615ef (patch)
tree9729b0e0df8c7436e9f94563281d7913d23f362f /CLAUDE.md
parent5876025559ba0ad287d3a7a4d9fa0246509e668e (diff)
Embed yt-dlp via Chaquopy instead of shelling out to Termux
Verified end to end on an emulator: the probe resolves a real video and the download lands 54,006,240 bytes of m4a, matching the size the probe predicted. Two traps found by running it rather than reasoning about it: - Chaquopy defaults to CPython 3.8, which yt-dlp no longer supports, so pip silently resolves 2024.10.22 -- the last release that did, nearly two years stale, and YouTube extraction does not work with it. The build succeeds and the feature is dead. Pinned to 3.12, which gets 2026.8.19, and YouTubeAudioTest now fails on any pre-2025 yt-dlp so it cannot regress quietly. - Chaquopy 16.1.0 calls org.gradle.util.VersionNumber, removed in Gradle 9, so Gradle is pinned to 8.14.3 here while FeeDreader stays on 9.5. AGP stays at 8.13.2. Chaquopy 17 requires AGP 9.x, so moving off this means bumping all three together. yt-dlp's JSON is parsed through a separate, unit-tested mapping rather than inline in the Chaquopy call. It is a separate project on its own release cadence and is the boundary most likely to drift, so a field going missing or changing type should fail a test rather than crash on the phone. Parsed with kotlinx.serialization because org.json is an empty stub off device, which would have made the mapping untestable. Audio-only by design: separate streams need ffmpeg to merge, the documented yt-dlp failure mode on Android, and a pre-muxed audio stream has nothing to merge. No ffmpeg dependency at all. No proof-of-origin token support, deliberately -- obtaining one means running Google's attestation script in a WebView, a different act from downloading, and it is not needed from an ordinary connection. Known risk recorded in CLAUDE.md: yt-dlp has deprecated YouTube extraction without a JavaScript runtime, and there is no deno or node on Android. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md22
1 files changed, 19 insertions, 3 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 50e1fcb..d6160d3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -86,6 +86,22 @@ claims three separate times across these repos.
title+date. An episode that loses its identity loses its playback position.
- **Retention is auto-delete-once-played** with a grace period, so a mis-tap doesn't destroy an
episode you were still listening to.
-- **YouTube never touches this app.** Audio arrives via podkit running in Termux on the phone,
- writing to a local folder Listen imports. No extractor code here, nothing to break when Google
- ships a change.
+- **YouTube audio is yt-dlp, embedded.** Chaquopy runs an in-process CPython with real yt-dlp;
+ see `youtube/YouTubeAudio.kt` and `src/main/python/ytaudio.py`. No Termux, no podkit, no
+ server round trip.
+ - **Pin the Python version.** Chaquopy defaults to 3.8, which yt-dlp no longer supports, so
+ pip silently resolves the last 3.8-compatible release (2024.10.22) and YouTube extraction
+ fails while the build succeeds. `YouTubeAudioTest` fails on a pre-2025 yt-dlp for exactly
+ this reason.
+ - **Audio-only, always.** Separate audio and video streams need ffmpeg to merge, which is the
+ documented failure mode for yt-dlp on Android. A single pre-muxed audio stream has nothing
+ to merge and needs no ffmpeg.
+ - **No proof-of-origin tokens.** Obtaining one means running Google's attestation script in a
+ WebView, which this app does not do. It works without one from an ordinary phone connection.
+ - **Known risk:** yt-dlp has deprecated YouTube extraction without a JavaScript runtime and
+ warns that some formats may be missing. There is no deno/node on Android. If yt-dlp makes a
+ JS runtime mandatory, this breaks and the fallback is bundling a JS engine it accepts.
+
+- **Gradle is pinned to 8.14.3, not 9.x**, because Chaquopy 16.1.0 calls `org.gradle.util.
+ VersionNumber`, removed in Gradle 9. Chaquopy 17 moved to AGP 9.x; going there means bumping
+ AGP, Gradle and Chaquopy together. This is the one deliberate divergence from FeeDreader.