addozhang/leancast

★ 113⑂ 8

Ad-free DLNA / UPnP cast receiver for Android TV · 极简无广告投屏接收器

About addozhang/leancast

addozhang/leancast is an open-source project on GitHub, mainly written in Kotlin. Ad-free DLNA / UPnP cast receiver for Android TV · 极简无广告投屏接收器 It currently holds 113 stars and 8 forks with 0 open issues, and was last pushed on 2026-10-29 (repository created 2026-10-28).

Project Overview

Git Homed tracks it on the Today's Trending board, currently at rank #68 with 0 new stars today.

GitHub Repository Details

Repository addozhang/leancast · default branch main · size 4826 KB · watchers 0 · source: GitHub REST API and repository README

README

LeanCast

English | 简体中文

https://github.com/addozhang/leancast/blob/HEAD/LeanCast TV dashboard https://github.com/addozhang/leancast/blob/HEAD/LeanCast playback OSD

A minimal, ad-free DLNA/UPnP cast receiver for Android TV. Open any video app with a cast button (Bilibili, iQiyi, Tencent Video, Youku, Quark, …), pick this receiver, and the video plays fullscreen with hardware decoding — no ads, no accounts, no cloud.

Phone app --SSDP--> discovers  Phone app --SOAP SetAVTransportURI--> LeanCast
                                                                    |
                                                        ExoPlayer + MediaCodec HW decode

Highlights

RenderingControl / ConnectionManager SOAP control, and real GENA eventing (initial LastChange on subscribe, then a notification per state change). Matroska, HTTP-FLV (best effort), HTTP↔HTTPS redirects, cleartext LAN URLs. escalating fast-forward ladder (10 s → 5 min while held), Back = exit; on-screen HUD with live progress bar, media title, and seek-step feedback in English or Chinese. analytics, zero non-LAN network calls; pure-Kotlin APK with no native libs — one artifact runs on armeabi-v7a, arm64-v8a, x86, x86_64. user-renamable; UUID is derived from the device id, so it survives reboots and reinstalls; UI language switchable between 简体中文 and English. minSdk 21 / targetSdk 28.

Build

Requirements: JDK 17+, Android SDK (platform 34). Then:

./gradlew assembleDebug

app/build/outputs/apk/debug/app-debug.apk

Install & use

adb connect :5555
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n io.leancast/io.leancast.app.MainActivity

Launch the app once to start the receiver service; it then appears in every DLNA sender's device list under the receiver name (rename it in the app). Optional: enable Start on boot in the app.

Supported devices

LeanCast is a pure-Kotlin APK with no native libraries and minSdk 21 (Android 5.0, 2014), so a single artifact covers armeabi-v7a, arm64-v8a, x86 and x86_64. Decoding uses each device's platform MediaCodec, so codec coverage follows the device: H.264 everywhere, HEVC/4K on 2016+ TVs, AV1 only on newer boxes.

| Tier | Devices | Notes | | :--- | :--- | :--- | | ✅ Verified | Amazon Fire TV / Fire TV Stick (Fire OS 6/7) | Primary test device: Fire OS 7.7, 32-bit MTK SoC | | ✅ Expected | Certified Android TV / Google TV (Sony, TCL, Philips, Chromecast w/ Google TV), NVIDIA Shield, Amlogic / Rockchip boxes, Xiaomi international boxes | Sideload and go | | ⚠️ Experimental | CN smart TVs with sideloading (MIUI TV / PatchWall, Coocaa, Hisense Android models), Tmall boxes (YunOS) | Enable "unknown sources"; report results via the compatibility issue template | | ❌ Unsupported | Samsung (Tizen), LG (webOS), Huawei Vision (HarmonyOS), non-smart TVs | No Android app runtime — use any TV box from the ✅ tiers |

Notes:

receiver, so use the [TV] button inside video apps. help grow the matrix.

Resource usage

Measured on the primary test device (Fire TV, 1.6 GB RAM); idle = receiver waiting on the dashboard:

| State | RAM (PSS) | CPU | Storage | | :--- | :--- | :--- | :--- | | Idle / waiting | 63–72 MB (≈ 33 MB private) | ≈ 0% | 5 MB APK + < 0.1 MB data | | Casting 1080p | ≈ 74 MB | ~4–5% of total (decode is hardware) | — |

Lighter than the stock Fire TV launcher (83 MB PSS) on the same device.

Releases & CI

Two GitHub Actions workflows ship with the repo:

every push to main and every PR; uploads the debug APK as an artifact. tag (or manually via workflow_dispatch). Builds the release APK, runs the unit tests, creates a GitHub Release with auto-generated notes, and attaches LeanCast-.apk.

To publish a release:

git tag v0.2.0
git push origin v0.2.0

Release signing

By default the release APK falls back to the debug keystore (fine for personal sideloading). For a stable release signature across builds, add these repository secrets (Settings → Secrets and variables → Actions):

| Secret | Value | | :--- | :--- | | KEYSTORE_BASE64 | base64 -i release.keystore \| pbcopy (or base64 -w0 on Linux) | | KEYSTORE_PASSWORD | Keystore password | | KEY_ALIAS | Key alias | | KEY_PASSWORD | Key password |

The workflow decodes the keystore to ci-release.keystore (git-ignored) and signs with it. Generate a keystore once with:

keytool -genkeypair -v -keystore release.keystore -alias leancast \
  -keyalg RSA -keysize 2048 -validity 10000

Project layout

domain/          Pure-Kotlin protocol core (JVM-unit-tested, 90 tests)
  ssdp/          M-SEARCH parsing, target matching, USN, alive/byebye, MX delays
  upnp/          Device description + SCPDs, SOAP parser (prefix-tolerant DIDL),
                 response envelopes & faults, H:MM:SS time math, SOAP router
  cast/          AVTransport state machine, player port, volume math
app/             Android shell (thin adapters, E2E-verified on device)
  ControlServer  Minimal HTTP/1.1 server: /desc.xml, /scpd/, /ctl/, /evt/*
  SsdpAgent      Multicast UDP listener + advertiser (MulticastLock held)
  ExoPlayerPort  PlayerPort adapter (main-thread marshalled, cached position)
  ReceiverService Foreground service assembling everything
tools/
  e2e_control_point.py  Scripted UPnP control point for device E2E runs
openspec/        Spec-driven development artifacts (proposal/specs/design/tasks)

Development follows OpenSpec (openspec/) with strict TDD: every spec scenario maps to unit tests in domain; run them with ./gradlew :domain:test. End-to-end verification drives a real device from a dev box:

python3 tools/e2e_control_point.py http:///video.mp4

License

Apache-2.0. Dependencies: Media3 (Apache-2.0).

GitHub Stars & Activity

113Stars
8Forks
0Open issues
KotlinLanguage

GitHub Popularity

GitHub stars113
Forks8
Open issues0
Primary languageKotlin
LicenseApache-2.0
Stars gained today0
Created2026-10-28
Last pushed2026-10-29

Trending History

Daily boardrank #68 · ▲ 0 stars

Related GitHub Projects

1

JunWan666 / astrbot-for-android

Kotlin★ 246⑂ 11
→
2

anhao / ai-pose-gallery-zh

HTML★ 2,551⑂ 668
→
3

andyhuo520 / digital-human-koubo

TypeScript★ 1,400⑂ 323
→
4

Motionsites-AI / claude-skill

Python★ 1,021⑂ 106
→
5

kargulstudio / calender-app-design

TypeScript★ 795⑂ 96
→
6

smithjohn78390 / tongjiang-lab

HTML★ 760⑂ 206
→
7

yaojingang / GEOInflow

TypeScript★ 707⑂ 227
→
8

blakeandersonw / ai-app-playbook

TypeScript★ 571⑂ 77
→

More Trending Repositories