Skip to content

Latest commit

 

History

105 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CloudStream Desktop (Unofficial Client)

Caution

PURELY EXPERIMENTAL - NOT FOR REGULAR USERS
This project is a massive, highly experimental sandbox. It is NOT a stable release, it is NOT meant for regular users, and it is NOT ready for daily use. Expect crashes, broken features, and missing functionality. This is strictly a developer playground and proof-of-concept for running Android plugins natively on the desktop.

Also, this project contains AI-generated code, so beware: it might not make sense sometimes because the dev is very lazy and too stupid to write their own code.

Welcome to the CloudStream Desktop project. This is a native Compose for Desktop application designed to run CloudStream Android plugins natively in a desktop JVM environment.


🏗️ Multi-Module Architecture

The project is structured into modular layers to cleanly separate concerns and allow the Android-specific plugin code to execute on the desktop:

  • :library (android-reference): A submodule copy of the core Android CloudStream library. It contains the primary data models, scrapers, and extension interfaces.
  • :android-stubs: Compatibility mock stubs for Android platform APIs (e.g., Context, SharedPreferences, ActivityThread). This allows standard JVM compilation of Android-targeted plugin code.
  • :common: The persistence and settings layer. It uses SQLDelight for local database management and Jackson-based file serialization, remaining completely decoupled from the UI.
  • :player-abstraction: Abstracts media playback. It hosts native wrappers for MPV (JNA bindings) and VLC (process wrappers), and embeds a local Ktor Netty proxy (LocalStreamProxy) to rewrite HLS segment headers for CDN requests.
  • :desktop-app: The main entry point. It hosts the Compose for Desktop UI, navigation, theme controls, and window chrome.
  • :plugin-runtime / :plugin-sandbox: Handles isolated plugin loading and basic bytecode sandboxing to protect local files.

✨ Core Capabilities

  • Native Compose UI: Built entirely in Compose for Desktop with rich cinematic header fades, responsive hero layouts, dynamic color extraction, and multi-mode search (persistent overlays & quick-clear controls).
  • Android Plugin Compatibility: Runs standard Android plugins directly on the JVM through custom compatibility stubs (android.*, androidx.*) and isolated class loaders.
  • Advanced Media Abstraction (:player-abstraction): Native MPV decoding (via JNA libmpv bindings) and fallback web/process wrappers, backed by an embedded Ktor Netty proxy (LocalStreamProxy) for HLS segment header rewriting and CDN bypasses.
  • Modular Storage & Synchronization: SQLDelight local database management decoupled from the presentation layer, with built-in multi-provider watch tracking and history sync.

🛠️ Setup & Development Workflow

Prerequisites

Make sure you have all of these installed before you start:

  • JDK 21 or higher — Download Temurin
  • Git — needed for cloning with submodules (Download)
  • MinGW-w64 / g++ — only needed if you plan to modify the C++ JNI bridge (compile_jni.ps1). Make sure g++ is available in your PATH (Download via MSYS2)
  • Inno Setup 6 — only needed if you want to build the .exe installer locally (Download)

Note

You do not need Android Studio or any Android SDK. This is a pure JVM/Desktop project.

1. Clone the Repository

You must use Git clone with recursive submodules so the Android core library references are pulled correctly:

git clone --recursive https://github.com/errorcode26/CS3-desktop-client-unofficial.git
cd CS3-desktop-client-unofficial

Warning

Do not download this repository as a zip file from GitHub, as submodules will be missing.

2. Download Native Binaries

Before running, you need a local copy of the libmpv shared library for video decoding:

  1. Download the latest mpv-dev Windows build (e.g., from SourceForge).
  2. Extract and place libmpv-2.dll (or mpv-2.dll) directly inside the following folder: desktop-app/appResources/windows/mpv/

3. Run Locally

To compile and launch the desktop application in developer mode:

.\gradlew.bat :desktop-app:run

Warning

Running this command bypasses jpackage and the release .cfg configuration entirely. Always build the actual .exe using compile.bat and test it locally before pushing packaging or JNI changes, otherwise you might introduce silent crashes in the release build! To quickly run only the isolated media player test harness (without starting the entire app UI):

# For WebView player testing:
.\gradlew.bat :desktop-app:runTestWebViewPlayer

# For native MPV player testing:
.\gradlew.bat :desktop-app:runTestMpvPlayer

4. Working on the Native C++ Bridge

If you are tweaking the raw C++ code for the WebView2 JNI player bridge (desktop-app/src/main/cpp), you do not need to memorize the 15+ GCC compiler/linking flags. Simply run the included PowerShell script to instantly recompile the .dll:

.\compile_jni.ps1

Important

The CI/CD pipeline does not recompile the C++ bridge automatically. After running the script, make sure you commit the updated player_bridge.dll along with your C++ changes before pushing. Otherwise the CI build will ship the old binary.

Note

Want a new UI feature that uses native Windows functionality? If the feature you want doesn't already exist in the C++ bridge (e.g., a new WebView2 control, a new window event, a new native dialog), you must add the corresponding JNI method to player_bridge.cpp first and recompile the .dll. The Kotlin/Compose UI layer can only call native capabilities that are already exposed through the JNI bridge — there is no other way to add them.

5. Build Installer (Optional)

If you need to generate a standalone Windows .exe setup installer for testing:

  1. Run compile.bat to clean and compile the latest executable binaries.
  2. Open Inno Setup Compiler and compile installer/setup.iss.

The compiled setup installer will be generated at desktop-app\build\outputs\CloudStream-Setup.exe.

6. Automated GitHub Releases (CI/CD)

The project is configured to automatically build and publish a Windows .exe installer directly to GitHub Releases whenever a new version tag is pushed to main. To trigger a new public release:

  1. Bump APP_VERSION in gradle.properties (e.g., from 0.1.2 to 0.1.3).
  2. Commit the change to the main branch.
  3. Create and push a version tag matching the version number:
    git tag v0.1.3
    git push origin v0.1.3

GitHub Actions will automatically spin up a Windows runner, compile the JVM binaries, package the Inno Setup executable, and draft the release notes for you!


🧪 Testing & Code Quality

This architecture is built for rapid iteration. We have a lightweight test harness, but our focus is on active developer validation:

  • Use isolated experimental/feature branches for development to keep the dev branch clean.
  • To run the standard automated unit test suite (verifies math, updaters, and API parsers):
    .\gradlew.bat :desktop-app:test
  • To test changes on the video player directly without booting the full app shell, use the isolated harnesses:
    .\gradlew.bat :desktop-app:runTestWebViewPlayer
    .\gradlew.bat :desktop-app:runTestMpvPlayer
cd C:\Users\prady\Downloads\CS3-desktop-client-unofficial
gradlew --stop
gradlew clean
# Set WIX to the official installation root (no \bin)
$env:WIX = "C:\Program Files (x86)\WiX Toolset v3.14"

# Add the bin folder to PATH for this session
$env:Path += ";C:\Program Files (x86)\WiX Toolset v3.14\bin"

# Kill old Gradle daemons
.\gradlew --stop

# Build WITHOUT a daemon so it picks up the current environment
.\gradlew clean :desktop-app:createDistributable --info --no-daemon
fix jdk 21
$env:JAVA_HOME="C:\Program Files\Java\jdk-21.0.11"
$env:Path="$env:JAVA_HOME\bin;" + ($env:Path -replace [regex]::Escape("C:\Program Files\Eclipse Adoptium\jdk-17.0.18.8-hotspot\bin;"), "")

🤝 Contributing & Issues

Reporting Issues

Found a bug or got a cool feature idea? Just open an issue! Keep it simple and to the point:

  1. What were you trying to do? (e.g., "I clicked the play button...")
  2. What actually happened? (e.g., "...and the app crashed.") If things blew up, drop the error logs or a screenshot.
  3. How can we reproduce it? (Step-by-step is super helpful so we can see the bug ourselves).

Pull Requests (PRs)

Want to build a feature yourself? Awesome! We love PRs.

  1. Fork the repo and create your own branch off the dev branch.
  2. Build your feature. Be sure to test it locally using the test commands above!
  3. Important: Don't touch the version numbers in gradle.properties (we handle version bumping when we merge).
  4. Open a PR, give it a quick description of what you added and why it's cool, and we'll take a look!

Disclaimer

This repository acts purely as a blank-slate media shell. The application does not ship with any plugins, media files, or pre-configured content sources. The developers hold no responsibility or liability for how users choose to utilize this software.

Releases

Packages

Contributors

Languages