docs: public README + reproducible build image

This commit is contained in:
Sulkta 2026-06-28 12:25:49 -07:00
parent 120caa9050
commit a033402a44
2 changed files with 153 additions and 49 deletions

143
README.md
View file

@ -1,77 +1,122 @@
# Straw
A Sulkta fork of [NewPipe](https://github.com/TeamNewPipe/NewPipe). Android YouTube
client, Compose UI, Media3 player, with [SponsorBlock](https://sponsor.ajay.app/)
and [Return YouTube Dislike](https://returnyoutubedislike.com/) baked in.
A privacy-focused Android YouTube client. Compose UI, Media3 player, with
[SponsorBlock](https://sponsor.ajay.app/) auto-skip and
[Return YouTube Dislike](https://returnyoutubedislike.com/) baked in. No login,
no Google Play Services, no tracking — Straw talks to public web endpoints only.
The extractor is `strawcore`, a Rust port of NewPipeExtractor exposed to Kotlin
via UniFFI. No InnerTube/JS deobf code path lives on the JVM anymore.
Straw is a fork of [NewPipe](https://github.com/TeamNewPipe/NewPipe). The
extractor is **strawcore**, a Rust port of NewPipe's extraction logic exposed
to Kotlin via [UniFFI](https://mozilla.github.io/uniffi-rs/) — there's no
InnerTube/JS-deobfuscation code path on the JVM anymore.
## Features
- Search, video detail, channel pages, playlists
- Inline player + fullscreen + swipe-down minibar + background audio + PiP
- Media3 ExoPlayer (DASH / HLS / progressive / merged DASH chunks)
- SponsorBlock auto-skip, with per-category toggles
- Return YouTube Dislike on the video detail page
- RSS-based subscription feed (fast — about a second for 50 subscriptions)
- Hide-shorts / hide-paid / hide-age-restricted feed filters
- Resume positions, watch history, search history
- Local playlists; downloads (video + audio)
- Imports NewPipe-format settings (subscriptions + playlists + history)
### Out of scope (on purpose)
- Trending / algorithmic feeds — subscriptions only
- iOS / desktop targets — Android only for now
- Anything that needs Google Play Services or an account
## Install
F-Droid repo: <https://fdroid.sulkta.com/fdroid/repo>
Add the repo in your F-Droid client of choice, then install Straw.
The app also self-updates from the same repo when an APK lands there with a
higher `versionCode`.
## What's in
- Search, video detail, channel pages, playlists
- Inline player + fullscreen + minibar + background audio + PiP
- Media3 ExoPlayer (DASH / HLS / progressive / merged DASH chunks)
- SponsorBlock auto-skip (categories user-toggleable)
- Return YouTube Dislike on video detail
- RSS-based subscription feed (fast — ~1s for 50 subs)
- Hide-shorts / hide-paid / hide-age-restricted feed filters
- Resume positions + watch history + search history
- Local playlists, downloads (video + audio)
- NewPipe-format settings import (subs + playlists + history)
## What's out (on purpose)
- Trending / algorithmic feeds. Subscriptions only.
- iOS / desktop targets. Android-only for now.
- Google Play Services anything.
## Layout
Pre-built APKs are published to an F-Droid repository:
```
strawApp/ Sulkta-authored app — Compose UI, Media3 wiring, SB + RYD clients
rust/ strawcore — UniFFI wrapper around the Rust extractor
shared/ KMP scaffold inherited from upstream NewPipe (unused for now)
app/ Upstream NewPipe :app module — kept for reference
https://fdroid.sulkta.com/fdroid/repo
```
Add that repo to the F-Droid client of your choice and install **Straw**. The
app also self-updates from the same repo when a newer `versionCode` is
published.
If you'd rather build it yourself, see **Build** below.
## Build
```
./gradlew :strawApp:assembleDebug
```
Straw is a standard Gradle project with a Rust component (`strawcore`) compiled
for Android via `cargo-ndk` and bound to Kotlin with `uniffi-bindgen`. The
Gradle build drives both automatically.
Requires the Rust toolchain plus the four Android targets:
### Prerequisites
```
- JDK 21
- Android SDK with platform `android-36`, build-tools `36.0.0`, and NDK `r27`
(`ANDROID_NDK_HOME` must point at it)
- A Rust stable toolchain with the four Android targets, plus `cargo-ndk` and
`uniffi-bindgen`:
```sh
rustup target add aarch64-linux-android armv7-linux-androideabi \
x86_64-linux-android i686-linux-android
cargo install cargo-ndk uniffi-bindgen
```
…and `ANDROID_NDK_HOME` pointing at NDK r27c (or newer). The Gradle build runs
`cargo ndk` + `uniffi-bindgen` automatically.
### Assemble a debug APK
```sh
./gradlew :strawApp:assembleDebug
```
The APK lands in `strawApp/build/outputs/apk/debug/`.
### Reproducible build image
`ci/Dockerfile` defines a self-contained image with the exact JDK + Android SDK
+ NDK + Rust toolchain the build expects, if you'd rather not install all of
that on your host:
```sh
docker build -t straw-build ci/
docker run --rm -v "$PWD":/src -w /src straw-build ./gradlew :strawApp:assembleDebug
```
## Project layout
```
strawApp/ The app — Compose UI, Media3 wiring, SponsorBlock + RYD clients
rust/ strawcore — the UniFFI wrapper crate around the Rust extractor
buildSrc/ Shared Gradle build logic and version constants
iosApp/ Empty iOS shell inherited from upstream (not built)
```
The actual extraction engine (`strawcore-core`) lives in a sibling repository,
[`strawcore`](https://git.sulkta.com/Sulkta-OSS/strawcore), and is pulled in as
a path/Git dependency by `rust/strawcore`.
## Contributing
Issues and pull requests are welcome. A few notes:
- Keep changes scoped and described; the build runs lint/format checks.
- The app is Kotlin + Jetpack Compose; the extractor is Rust. Touch the layer
the change belongs in.
- By contributing you agree your work is licensed under GPL-3.0-or-later (see
**License**).
## License
GPL-3.0-or-later, inherited from upstream NewPipe.
GPL-3.0-or-later, inherited from upstream NewPipe. See [`LICENSE`](LICENSE).
## Upstream
This repo tracks <https://github.com/TeamNewPipe/NewPipe>. Upstream changes
get pulled periodically via the `upstream` remote.
Straw tracks [NewPipe](https://github.com/TeamNewPipe/NewPipe); upstream
improvements are pulled in periodically. The `app/` and `shared/` modules from
NewPipe were removed once Straw became its own app on the strawcore pipeline.
## Disclaimer
Not affiliated with YouTube, Google, NewPipe e.V., the SponsorBlock project,
or Return YouTube Dislike. Trademarks belong to their owners. Straw uses
public web endpoints; nothing here authenticates to any account.
Not affiliated with YouTube, Google, NewPipe e.V., the SponsorBlock project, or
Return YouTube Dislike. All trademarks belong to their respective owners. Straw
uses public web endpoints and does not authenticate to any account.

59
ci/Dockerfile Normal file
View file

@ -0,0 +1,59 @@
# straw-build — reproducible Android + Rust build image for the Straw APK.
#
# A fully self-contained toolchain so a fresh build needs nothing on the host
# but Docker. Build it, then run the Gradle assemble inside it:
#
# docker build -t straw-build ci/
# docker run --rm -v "$PWD":/src -w /src straw-build \
# ./gradlew :strawApp:assembleDebug
#
# Toolchain pinned to what builds successfully:
# JDK 21 · NDK 27.2.12479018 · build-tools 34.0.0 + 36.0.0 · platforms android-36
# Rust stable + 4 Android targets · cargo-ndk · clang/libclang (rquickjs bindgen)
# AGP (compileSdk 36) requires build-tools 36; we pre-install it so the build
# doesn't sdkmanager-download it on every run. 34.0.0 is kept as a fallback;
# apksigner uses the highest build-tools present (36).
FROM eclipse-temurin:21-jdk-jammy
ENV DEBIAN_FRONTEND=noninteractive \
ANDROID_SDK_ROOT=/opt/android-sdk \
ANDROID_HOME=/opt/android-sdk \
ANDROID_NDK_HOME=/opt/android-sdk/ndk/27.2.12479018 \
CARGO_HOME=/opt/cargo \
RUSTUP_HOME=/opt/rustup \
PATH=/opt/cargo/bin:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools:/usr/bin:/bin
# Base OS deps: clang/libclang for rquickjs bindgen, a C toolchain for the
# QuickJS C sources, unzip for the SDK zips, git+ca-certs for checkout.
RUN apt-get update && apt-get install -y --no-install-recommends \
git curl unzip ca-certificates clang libclang-dev build-essential pkg-config \
&& rm -rf /var/lib/apt/lists/*
# Android cmdline-tools + the SDK packages the build needs.
ARG CMDLINE_TOOLS_ZIP=commandlinetools-linux-11076708_latest.zip
RUN mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" \
&& curl -fsSL -o /tmp/cmdtools.zip "https://dl.google.com/android/repository/${CMDLINE_TOOLS_ZIP}" \
&& unzip -q /tmp/cmdtools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools" \
&& mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" \
&& rm /tmp/cmdtools.zip \
&& yes | sdkmanager --licenses >/dev/null 2>&1 \
&& sdkmanager --install \
"platform-tools" \
"platforms;android-36" \
"build-tools;34.0.0" \
"build-tools;36.0.0" \
"ndk;27.2.12479018" >/dev/null \
&& rm -rf "$ANDROID_SDK_ROOT/.temp" /tmp/*
# Rust toolchain + the four Android targets + cargo-ndk.
RUN curl -fsSL https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal \
&& rustup target add \
aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android \
&& cargo install cargo-ndk --locked \
&& rm -rf /opt/cargo/registry/cache /opt/cargo/registry/src
# Sanity: fail the image build early if anything's missing.
RUN java -version && cargo --version && cargo ndk --version || true \
&& test -d "$ANDROID_NDK_HOME" \
&& test -d "$ANDROID_SDK_ROOT/build-tools/34.0.0" \
&& test -d "$ANDROID_SDK_ROOT/build-tools/36.0.0"