M6 — cross-compile aarch64-musl + addon.zip + install docs
scripts/build-addon-zip.sh runs the whole pipeline from a host with ssh lucy: - one-shot messense/rust-musl-cross:aarch64-musl container builds the sidecar static (6.2MB stripped). Doesn't mutate crafting-table. - fetches yt-dlp_linux_aarch64 from the upstream release page so Tier 2 + Tier 3 work on the Pi (LibreELEC ships no Python YouTube tools) - packages everything into plugin.video.torttube.zip with the Kodi install-from-zip layout - drops the zip at /mnt/user/downloads/torttube/ on Lucy SMB Cargo.toml swaps rustypipe to default-features=false + rustls-tls-webpki-roots so the cross-compile is openssl-free. addon.xml drops the unused script.module.requests requirement — main.py only uses Python stdlib + Kodi's own modules. docs/install.md walks the Kodi UI flow + a smoke curl that fires Player.Open via JSON-RPC. Pi-side smoke is pending Cobb's install on 192.168.0.158.
This commit is contained in:
parent
9b2a47c909
commit
f4ceae3b70
5 changed files with 139 additions and 7 deletions
|
|
@ -48,11 +48,19 @@
|
|||
- [ ] toast on skip + skip-counter in settings
|
||||
- [ ] category toggles in `settings.xml`
|
||||
|
||||
## M6 — install + cross-compile
|
||||
## M6 — install + cross-compile [PARTIAL]
|
||||
|
||||
- [ ] 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/`
|
||||
- [x] cross-compile sidecar for aarch64-musl static via throwaway
|
||||
`messense/rust-musl-cross:aarch64-musl` container. 6.2MB stripped
|
||||
static binary. Builds clean from `scripts/build-addon-zip.sh`.
|
||||
- [x] bundle yt-dlp's `yt-dlp_linux_aarch64` release binary for Tier 2/3
|
||||
- [x] zip layout matches Kodi "install from zip" expectations
|
||||
- [x] addon.zip dropped at `smb://lucy/downloads/torttube/` for Pi-side install
|
||||
- [x] install + smoke recipe documented at `docs/install.md`
|
||||
- [ ] **install on the actual Pi** + verify the JSON-RPC `Player.Open`
|
||||
smoke against `192.168.0.158` — needs Cobb to either install via
|
||||
Kodi UI or grant SSH to drop the zip directly
|
||||
- [ ] armv7 build for older Pis (deferred — Cobb's TVs are all aarch64-capable)
|
||||
|
||||
## Upstream PR work (parallel lane — every bug evaluated for "fix it upstream?")
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
provider-name="Sulkta-Coop">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="3.0.0"/>
|
||||
<import addon="script.module.requests" version="2.22.0"/>
|
||||
<import addon="inputstream.adaptive" version="2.0.0" optional="true"/>
|
||||
</requires>
|
||||
<extension point="xbmc.python.pluginsource" library="main.py">
|
||||
|
|
|
|||
65
docs/install.md
Normal file
65
docs/install.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Installing torttube on the LibreELEC RPi
|
||||
|
||||
The addon ships as a single `plugin.video.torttube-<version>.zip` that
|
||||
contains the Python addon, a static aarch64 sidecar binary, and yt-dlp's
|
||||
aarch64 release binary (for Tier 2/3 fallback). Nothing else needs to be
|
||||
installed on the Pi.
|
||||
|
||||
## Build the zip (Sulkta-internal)
|
||||
|
||||
```bash
|
||||
bash scripts/build-addon-zip.sh
|
||||
# → /mnt/user/downloads/torttube/plugin.video.torttube-0.0.1.zip on Lucy
|
||||
```
|
||||
|
||||
The script cross-compiles the sidecar in a throwaway
|
||||
`messense/rust-musl-cross:aarch64-musl` container, fetches yt-dlp's
|
||||
official `yt-dlp_linux_aarch64` release binary, packages everything,
|
||||
drops the result at `/mnt/user/downloads/torttube/` (Lucy SMB).
|
||||
|
||||
## Install on the Pi (Kodi UI flow)
|
||||
|
||||
1. On the Pi: Settings → File manager → Add source → enter
|
||||
`smb://lucy/downloads/` → name it `lucy-downloads`.
|
||||
2. Settings → Add-ons → Install from zip file → `lucy-downloads` →
|
||||
`torttube/plugin.video.torttube-<version>.zip`.
|
||||
3. Kodi installs, the addon appears under Video add-ons.
|
||||
|
||||
Unsigned addons need `Settings → System → Add-ons → Unknown sources` ON.
|
||||
|
||||
## Verify
|
||||
|
||||
After install, fire the smoke from any LAN client:
|
||||
|
||||
```bash
|
||||
curl -u kodi:pineapple -H "Content-Type: application/json" \
|
||||
-X POST http://192.168.0.158:8080/jsonrpc -d '{
|
||||
"jsonrpc": "2.0", "id": 1, "method": "Player.Open",
|
||||
"params": {"item": {"file":
|
||||
"plugin://plugin.video.torttube/?action=play&id=dQw4w9WgXcQ"}}}'
|
||||
```
|
||||
|
||||
The TV should switch to playback of "Never Gonna Give You Up" within a
|
||||
few seconds (rustypipe resolve takes ~1s, then Kodi starts the stream).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Black screen + "no stream URL"** notification: rustypipe returned
|
||||
separate audio + video streams (DASH-style), and we're picking the
|
||||
video stream which may be video-only. This is the M3 known gap —
|
||||
needs the audio+video merge work in M3+. Workaround: try a video that
|
||||
yt-dlp's tier-2 path can resolve to a combined format; the sidecar
|
||||
falls back automatically.
|
||||
- **Sidecar crashes**: `cat /storage/.kodi/temp/kodi.log | grep torttube`
|
||||
on the Pi. Sidecar logs to stderr; Kodi captures those.
|
||||
- **yt-dlp permission denied**: addon's bin/ dir needs +x. The zip
|
||||
preserves perms but if you copied files manually, `chmod +x bin/*`.
|
||||
- **HTTPS errors from sidecar**: it bundles rustls + webpki roots, so
|
||||
no system CA store needed. If you see "invalid certificate", your Pi
|
||||
clock is wrong (LibreELEC's NTP failed).
|
||||
|
||||
## Updating
|
||||
|
||||
Just rebuild + bump the version in `addon/plugin.video.torttube/addon.xml`,
|
||||
re-run `build-addon-zip.sh`, install the new zip from the same SMB
|
||||
location. Kodi will treat it as an upgrade if the version is higher.
|
||||
57
scripts/build-addon-zip.sh
Executable file
57
scripts/build-addon-zip.sh
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
# Build addon.zip for torttube — runs from a host that can ssh lucy.
|
||||
#
|
||||
# Cross-compiles the sidecar via messense/rust-musl-cross:aarch64-musl
|
||||
# (one-shot container, no crafting-table mutation), bundles yt-dlp's
|
||||
# aarch64 release binary, packages with the Kodi addon dir layout, and
|
||||
# drops the zip at /mnt/user/downloads/torttube/ on Lucy.
|
||||
#
|
||||
# Usage: bash scripts/build-addon-zip.sh
|
||||
#
|
||||
# Expected: ssh alias "lucy" works (per Sulkta SSH config), and the
|
||||
# torttube source is at /mnt/cache/appdata/crafting-table/workspace/torttube/
|
||||
# on Lucy (rsync first if you're iterating locally).
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${VERSION:-0.0.1}"
|
||||
SRC=/mnt/cache/appdata/crafting-table/workspace/torttube
|
||||
CARGO_HOME_CACHE=/mnt/cache/appdata/crafting-table/workspace/.cargo-aarch64
|
||||
TARGET_DIR=/mnt/cache/appdata/crafting-table/workspace/.aarch64-target
|
||||
STAGE=/tmp/torttube-stage
|
||||
DEST_DIR=/mnt/user/downloads/torttube
|
||||
|
||||
echo ">>> Cross-compile sidecar for aarch64-musl"
|
||||
ssh lucy "docker run --rm \
|
||||
-v $SRC/sidecar:/src \
|
||||
-v $CARGO_HOME_CACHE:/cargo-home \
|
||||
-v $TARGET_DIR:/target \
|
||||
-e PATH=/root/.cargo/bin:/usr/local/musl/bin:/usr/local/bin:/usr/bin:/bin \
|
||||
-e CARGO_HOME=/cargo-home \
|
||||
-e CARGO_TARGET_DIR=/target \
|
||||
-e CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-unknown-linux-musl-gcc \
|
||||
-e CC_aarch64_unknown_linux_musl=aarch64-unknown-linux-musl-gcc \
|
||||
-w /src \
|
||||
messense/rust-musl-cross:aarch64-musl \
|
||||
cargo build --release"
|
||||
|
||||
echo ">>> Stage addon tree"
|
||||
ssh lucy "rm -rf $STAGE && mkdir -p $STAGE/plugin.video.torttube/bin"
|
||||
ssh lucy "rsync -a $SRC/addon/plugin.video.torttube/ $STAGE/plugin.video.torttube/ --exclude bin"
|
||||
ssh lucy "cp $TARGET_DIR/aarch64-unknown-linux-musl/release/torttube-sidecar $STAGE/plugin.video.torttube/bin/"
|
||||
|
||||
echo ">>> Fetch yt-dlp aarch64 release binary"
|
||||
ssh lucy "curl -sSL -o $STAGE/plugin.video.torttube/bin/yt-dlp \
|
||||
https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux_aarch64"
|
||||
ssh lucy "chmod +x $STAGE/plugin.video.torttube/bin/*"
|
||||
|
||||
echo ">>> Build addon.zip"
|
||||
ssh lucy "cd $STAGE && rm -f plugin.video.torttube.zip && \
|
||||
zip -r plugin.video.torttube.zip plugin.video.torttube/ -x '*.DS_Store' > /dev/null"
|
||||
|
||||
echo ">>> Drop at $DEST_DIR/plugin.video.torttube-$VERSION.zip"
|
||||
ssh lucy "mkdir -p $DEST_DIR && cp $STAGE/plugin.video.torttube.zip \
|
||||
$DEST_DIR/plugin.video.torttube-$VERSION.zip"
|
||||
|
||||
ssh lucy "ls -la $DEST_DIR/"
|
||||
echo ">>> done — install via Kodi: Settings > Add-ons > Install from zip"
|
||||
echo " SMB path: smb://lucy/downloads/torttube/plugin.video.torttube-$VERSION.zip"
|
||||
|
|
@ -11,8 +11,11 @@ name = "torttube-sidecar"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
# Tier 1 — native Rust Innertube
|
||||
rustypipe = "0.11"
|
||||
# Tier 1 — native Rust Innertube.
|
||||
# default-features=false skips rustypipe's default-tls which pulls in
|
||||
# native-tls / openssl — we use rustls so cross-compile to aarch64-musl
|
||||
# stays openssl-free.
|
||||
rustypipe = { version = "0.11", default-features = false, features = ["rustls-tls-webpki-roots"] }
|
||||
|
||||
# Tier 2 + 3 — yt-dlp subprocess shell-out (no library, just std::process)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue