Cobb wants rustypipe primary, yt-dlp fallback, and rip-to-temp as the last-resort path when streams die mid-play. README expanded to spell out all three tiers + adds the 'fight YouTube alongside the FOSS ecosystem' framing. MILESTONES M1 rewritten to cover all three tiers. New file docs/upstream.md tracks every PR we file against rustypipe / NPE / yt-dlp with honest outcomes. Opens empty; fills as M1+ surface real bugs to fix.
66 lines
2.9 KiB
Markdown
66 lines
2.9 KiB
Markdown
# torttube milestones
|
|
|
|
## M0 — Scaffold [current]
|
|
|
|
- [x] `Sulkta-Coop/torttube` on LAN Gitea
|
|
- [x] Layout: `addon/` (Python) + `sidecar/` (Rust workspace)
|
|
- [x] GPL-3.0 license headers
|
|
- [ ] crafting-table build target produces a static aarch64 sidecar binary
|
|
|
|
## M1 — sidecar resolve (three-tier)
|
|
|
|
- [ ] reads `{"op":"resolve","id":"<yt-id>"}` from stdin
|
|
- [ ] **Tier 1:** rustypipe → `{"streams":[…],"title":"…","duration_s":N,"source":"rustypipe"}`
|
|
- [ ] **Tier 2:** on Tier-1 failure, shell out to `yt-dlp -j <url>` → same JSON shape with `"source":"yt-dlp"`
|
|
- [ ] **Tier 3:** new op `{"op":"rip","id":"<yt-id>","dest":"/storage/.kodi/temp/torttube/<id>.<ext>"}` invoked by addon on Tier-1+2 stream failures or 403-mid-play; yt-dlp downloads file, sidecar returns local path
|
|
- [ ] typed errors for age-restricted / region-restricted / private (not panics)
|
|
- [ ] sig decoding verified against a known-good video
|
|
- [ ] DASH manifest URL or per-itag direct stream URL — whichever inputstream.adaptive prefers
|
|
|
|
## M2 — SponsorBlock
|
|
|
|
- [ ] `{"op":"sponsorblock","id":"<yt-id>"}` → segments array
|
|
- [ ] SHA-256 prefix lookup (privacy-preserving — only send first 4 hex chars)
|
|
- [ ] category filter honoured from addon settings (skip / mute / show only)
|
|
- [ ] cache per-session
|
|
|
|
## M3 — Kodi addon plays one video
|
|
|
|
- [ ] `addon.xml` + `main.py` register as video plugin
|
|
- [ ] hardcoded list of 3 test videos
|
|
- [ ] select → sidecar `resolve` → stream URL → Kodi player
|
|
- [ ] verified end-to-end on LibreELEC RPi at `192.168.0.158`
|
|
|
|
## M4 — search + channel browse
|
|
|
|
- [ ] search box → sidecar `{"op":"search","q":"…"}` → results
|
|
- [ ] channel browse → `{"op":"channel","id":"…"}`
|
|
- [ ] playlist browse → `{"op":"playlist","id":"…"}`
|
|
- [ ] result thumbnails + duration + uploader
|
|
|
|
## M5 — SponsorBlock skipping
|
|
|
|
- [ ] background thread on `Player()` polls position
|
|
- [ ] when position enters a skip segment → `xbmc.Player().seekTime(end)`
|
|
- [ ] toast on skip + skip-counter in settings
|
|
- [ ] category toggles in `settings.xml`
|
|
|
|
## M6 — install + cross-compile
|
|
|
|
- [ ] crafting-table builds `torttube-sidecar.aarch64` + `.armv7`
|
|
- [ ] `addon.zip` ships with platform detect via `xbmc.getCondVisibility('system.platform.linux.raspberrypi')`
|
|
- [ ] one-shot install path documented for LibreELEC `/storage/.kodi/`
|
|
|
|
## Upstream PR work (parallel lane — every bug evaluated for "fix it upstream?")
|
|
|
|
This isn't a separate milestone, it's a posture. Every sidecar bug we
|
|
diagnose: ask "is this rustypipe / NPE / yt-dlp's bug?" — if yes, fix lands
|
|
upstream too. Log every filed PR in [docs/upstream.md](docs/upstream.md).
|
|
|
|
Opening shortlist:
|
|
|
|
- rustypipe PR #77 — review + help land
|
|
- NPE #1357 (JDoc) — smallest credible PR, opens the relationship
|
|
- NPE #1444 (typed errors) — clean signal/contract change
|
|
- NPE #1360 (refactor link handlers, "help wanted")
|
|
- rustypipe ↔ NPE port — anything one project has that the other lacks
|