ProjectM TV and ProjectM Android turn sound into MilkDrop visuals using 9,606 presets from Jason Fletcher's Cream of the Crop collection. ProjectM TV listens to a music app on your Android TV or Google TV. ProjectM Android runs on touchscreen phones and tablets and uses microphone input or music played locally by another app. Both render in landscape and use the same engine; neither is a music player.
GitHub editions bundle the complete collection. The smaller F-Droid editions start offline with 20 curated presets and offer an optional, verified download of the full collection. ProjectM Android for phones and tablets is available from F-Droid.
It runs ProjectM TV Engine: projectM, the open-source reimplementation of Winamp's MilkDrop, based on unreleased projectM 4.2 master (commit 6f6480746) plus 38 ordered patches. The patches restore MilkDrop 2's behaviour where projectM differs, keep presets at their authored scale on 4K screens, and make preset changes smooth on TV hardware.
Install on your TV with the Downloader app: code
4821216Install Downloader by AFTVnews on the TV, open it, enter 4821216 and install the APK it downloads. The code always points to the newest stable release. Details under Install.
Install on your phone or tablet with the Downloader app: code
6565691Install Downloader by AFTVnews from Google Play, open it, enter 6565691 and install ProjectM Android. The code points to the newest stable touchscreen APK.
johnneerdael.github.io/ProjectM-Android covers:
- Using the app: installation on TV or phones, remote and touchscreen controls, audio input, every setting, preset moods, custom packs, picture quality and troubleshooting.
- ProjectM TV Engine: the patch catalog with before/after proof images and measured benefits, how 4K rendering keeps the authored look (including the resolution-scaling part of projectM #682), and how a frame reaches the TV.
- Writing presets: a source-level guide to how
.milkpresets execute, drawn from MilkDrop 2's code and the analysis of thousands of presets. - The predictor: how ProjectM TV reads a preset's source and works out its look without rendering it: the feedback and colour mathematics, the calibration behind the moods, accuracy per option, predictions next to real renders, the JSON output, the SDK and the research journal.
- 9,606 MilkDrop presets with smooth blends, shuffled within the mood you choose.
- Preset mood: a Mood panel with Energy, Brightness, Colour, Palette, Main colour, Movement, Style and Comfort options, live preset counts and combinable choices, predicted for every bundled preset by static analysis of its source (no rendering); some presets are deliberately left without an option where the prediction is not confident. How it works.
- Presets that work as on MilkDrop 2: equation code MilkDrop tolerated, HLSL its compiler accepted, Direct3D pixel and texel rules, live per-frame waveform and display controls, legacy colour shading and spirals, huge rotations and negative zoom. Patch catalog.
- 4K without the darkness: lines, blur and texel steps scale with resolution; Native trails keeps feedback at an authored-scale canvas with sharp native geometry on top.
- No freezes at preset changes: upcoming presets are compiled in the background.
- Adaptive quality: resolution follows the target frame rate and live memory headroom, up to the panel's native size.
- Track titles: cover, artist and title of the playing track, from the music app's media session.
- Custom preset packs: upload up to 50,000 presets and textures from a phone by scanning a QR code.
- Private: audio is analysed locally. Native crash reports stay in private app storage and are never uploaded automatically. GitHub app updates can be switched off; F-Droid collection downloads require your choice. Custom uploads use a temporary local page.
- Remote and touchscreen controls with a settings panel and live status.
| Key | Action |
|---|---|
| Right, Next, Fast forward | Random preset (instant cut) |
| Left, Previous, Rewind | Previous preset (instant cut) |
| Up, Down, Info | Show the current track again (with notification access) |
| Center, Enter, Menu | Open the settings panel |
| Back | Exit the app |
In the panel, Up and Down move between rows, Left and Right change a value, and Center cycles a value or runs an action. Back closes the panel (from Advanced, Track display or Preset mood it returns to the main panel), Menu closes it, and it hides itself after 10 seconds without input.
In ProjectM Android, swipe right for a random preset and left for the previous preset, matching the remote's Right/Left actions. Switches are instant cuts. Tap the visuals to open the menu; tap a row to cycle its value or run its action. Scroll vertically to reach every setting, including Advanced and Track display. Use Back to menu, Close menu, or tap outside the panel. Touch input restarts the 10-second menu timeout.
| Setting | Values | Default |
|---|---|---|
| Audio input (Android only) | Microphone; Phone playback (Android 10+, consent required) | Microphone |
| Auto change | Off, On | On |
| Preset mood | Opens the Mood panel: Energy (Chill, Normal, Intense), Brightness (Dark, Balanced, Bright), Colour (Monochrome, Pastel, Vivid, Warm, Cool), Palette (Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink), Main colour (the same eight colours), Movement (Still, Drifting, Fast), Style (Kaleidoscope, Tunnel, Liquid, Geometric, Particles, Fractal), Comfort (No strobe); Collection (Built-in, Custom) after an upload; Clear all | Nothing selected (all presets) |
| Preset duration | 10, 15, 20, 30, 45, 60, 90 s | 30 s |
Track display ›
| Setting | What it does | Default |
|---|---|---|
| Track info | Cover, artist and title in the upper left; Off · Allow while notification access is missing | On |
| Show for | 10, 20, 30 or 60 s from the start of each track, or Always while music plays | Always |
| Pill style | One line (Title — Artist) in the lower-left pill instead | Off |
Advanced ›
| Setting | What it does | Default |
|---|---|---|
| Resolution | Auto; fixed 720p, 1080p, 1440p, 4K up to the panel; Native. Memory protection stays active | Auto |
| Frame rate | The refresh rate, half or a quarter of it, at least 24 fps | About 30 fps (30 at 60 Hz, 25 at 50 Hz) |
| Detail | Warp mesh: Minimal, Low, Medium, High, Ultra | High on SHIELD/Tegra, Low on low-RAM devices, otherwise Medium |
| Native trails | Standard, Medium, High; active above 1330p | Standard |
| Transition | Instant, 1–10 s | 7 s (2 s on low-RAM devices) |
| Transitions | Auto, Lightweight, Classic | Auto |
| Cut on loud beats | Lets projectM cut to the next preset on a loud beat | Off |
| Skip slow presets | In Auto resolution, skips presets that cannot reach half the target frame rate | On |
| Skip blank presets | Moves on from presets that stay black while music plays; skips them for good the second time | On |
| Auto-update | GitHub editions check for new stable releases; F-Droid editions update through F-Droid | On for GitHub; preserves an explicit Off |
| Cream of the Crop (F-Droid only) | Download or remove the full collection; custom packs stay separate | 20 starters |
| Custom preset pack | Upload one ZIP from a phone or computer on the same network | No pack |
| Skipped presets | Count of skipped presets; select to reset | – |
| Last exit | Saved native crash reports, Android exit reasons (Android 11+), and what the engine was doing; reports stay on-device | – |
On TV, opening Advanced also shows a Diagnostics card: render size, memory status, panel and UI size, frame rate, Native trails state, blend, audio source and level, track display, update status, device tier and GPU. The settings reference explains every value.
- Android TV or Google TV for the TV APK; a touchscreen phone or tablet for the Android APK. Both require Android 5.0 (API 21) or later and OpenGL ES 3.0; visuals stay in landscape.
- At least 2 GB of RAM is highly recommended.
- PowerVR crash fix (2.3.56+): fixes framebuffer-blit crashes, confirmed on Fire TV Stick 4K Max (2nd generation,
AFTKRT). The fix is automatic on all supported Imagination/PowerVR GPUs, including other GE9215 Fire TV sticks, Google TV Streamer and PowerVR phones/tablets. See device models and upgrade guidance. - TV audio: a music app playing on the same TV. Spotify, SoundCloud, SmartTube and Milkbeat have been verified on TV. The TV build has no microphone or line-in input; already Dolby-encoded audio cannot be visualized.
- Phone audio: microphone input works independently of a music app. Phone playback capture needs Android 10+, Android's consent and a player that allows capture and keeps playing in the background. The TV player list does not certify phone compatibility. Both builds feed the engine 8-bit mono audio.
- Preset moods are predicted from each preset's source code, not measured on your TV: out of fold about 4 of 5 given options are correct, some presets carry no option in a group, and music, random textures and per-load colours can change a preset's look. Style rests on source structure and is the least certain. No strobe and Chill are not guarantees against flashing. Custom-pack presets are not played while any option is active; choose Custom in the Collection row to play them.
- Some presets still look different from MilkDrop on Windows: random textures change per load, chaotic presets diverge, and GPU drivers differ in undefined arithmetic. Negative warp zoom follows MilkDrop 2’s CPU power calculation for valid integer nested exponents; fractional negative powers still have nonfinite coordinates with no portable appearance guarantee.
- 189 of the 9,795 Cream of the Crop presets are not included: 116 cannot react to music, 73 use images with text, logos or people (one is in both groups), and 1 has a missing texture.
| Permission | Why | When |
|---|---|---|
| Record audio | TV: the player's audio session. Android: microphone input or approved phone playback capture | First launch |
| Internet | GitHub app updates, an explicitly requested F-Droid collection download, and the local custom-pack upload page | Granted at install |
| Install apps (GitHub only) | Hands a downloaded app update to Android's installer | The first time you install an update |
| Notification access | Only to read the music app's media session for track titles; no notifications are read | Optional, via Track display › Track info |
Nothing the app hears or reads leaves the device.
On the TV, with Downloader
- Install Downloader by AFTVnews from the TV's app store and allow it to install apps.
- Open Downloader, enter 4821216 and confirm the installation.
The code links to https://github.com/johnneerdael/ProjectM-Android/releases/latest/download/projectM-TV.apk. Every version is under Releases.
On a phone or tablet, with Downloader
- Install Downloader by AFTVnews from Google Play.
- Open Downloader and enter 6565691.
- Allow Downloader to install apps when Android asks, then confirm installation of ProjectM Android.
You can also download the touchscreen Android APK directly. The stable filenames are projectM-TV.apk for TV and projectM-Android.apk for phones/tablets. The two apps have separate app IDs and settings; auto-update selects the matching APK.
Versions 2.3.46 and older cannot update themselves since the repository moved to ProjectM-Android: their update check fails with HTTP 301 (the Update line under Settings › Advanced). Install the current version once with Downloader; later versions update automatically again.
F-Droid editions
| Device | Stable APK | Presets | App updates |
|---|---|---|---|
| TV | projectM-TV-FDroid.apk |
20 starters; optional full collection | F-Droid |
| Phone/tablet | projectM-Android-FDroid.apk |
20 starters; optional full collection | F-Droid |
Phones and tablets: install ProjectM Android from the official F-Droid catalog, or open that listing in the F-Droid client. TV: the F-Droid-flavor TV APK is available from GitHub Releases; a TV catalog listing is not yet available. Both F-Droid-flavor APKs are also separate GitHub release artifacts. F-Droid catalog updates can lag GitHub, so check the minimum version for the PowerVR crash fix. On first launch, choose Download (recommended) or Use 20 starters. Reopen Advanced › Cream of the Crop to download or remove it later. The download is 39.1 MiB, with 131.0 MiB of unpacked collection contents; allow at least 186.1 MiB of free storage during installation. After installation the collection works offline. Downloading requires the app to stay in the foreground. Custom packs survive collection removal. Setup and updates.
From a computer
curl -LO https://github.com/johnneerdael/ProjectM-Android/releases/latest/download/projectM-TV.apk
adb install -r projectM-TV.apkStart music on the TV, open ProjectM TV and allow audio recording. On phones, choose Audio input in the menu: Microphone (default) or Phone playback. Playback capture requires Android 10+, Android's capture consent each session, and a player that permits capture; protected or opted-out audio is silent. Capture stops when the visualizer leaves the foreground. The getting-started guide walks through permissions and track titles with screenshots. Releases are signed with one permanent key; a build signed with your own debug key must be uninstalled before installing a release.
For troubleshooting audio, track titles, stutter and black presets, see the troubleshooting guide.
git clone --recurse-submodules https://github.com/johnneerdael/ProjectM-Android.git
./gradlew assembleRelease # APK + core AAR (signed with your local debug key)
./gradlew :app:assembleRelease -PandroidTouchscreen=true # touchscreen APK (same output path)
./gradlew :app:assembleFdroidTvRelease -PprojectmDistribution=fdroid
./gradlew :app:assembleFdroidAndroidRelease -PprojectmDistribution=fdroid -PandroidTouchscreen=true
./gradlew testDebugUnitTest # JVM tests
core/src/test/native/run_native_tests.sh # native engine and projectM regression controls- Engine: the
:coremodule builds projectM from the submodulethird_party/projectm, pinned to6f64807467e312034883a4389e6aa80a675458bc, and appliestools/projectm-patches/at configure time. Never edit the submodule; add a patch. CMake reports4.2.0, but upstream has not released this snapshot as 4.2.ProjectMJNI.getVersion()reports that upstream number; identify a build by release version, source revision and artifact checksum. - Core library: each release publishes
projectM-TV-core-<version>.aar(and the aliasprojectM-TV-core.aar), which Milkbeat consumes. - Embedded crash capture: the core AAR includes source-built xCrash. Hosts must use
packagingOptions.jniLibs.useLegacyPackaging = trueand retain the AAR'sextractNativeLibs="true"manifest attribute so its dumper can execute.NativeCrashReports.recent(context)reads local native reports on a background thread. - F-Droid: recipe and synchronization tooling uses the same source/version for both devices. The canonical core AAR keeps all 9,606 presets and 74 textures.
- Contributing: pull requests to
mainrun the full build after a completed review of their latest commit. Each tested merge publishes a new version automatically, with release notes from the PR's## Release notessection.
Further reading: build and test guide, architecture, patch assessment, releasing, diagnostics, profiling.
- projectM, the visualization engine (LGPL 2.1), including this project's shader remainder and precedence fix merged upstream
- xCrash, source-built local native crash capture (MIT and included third-party notices)
- Cream of the Crop presets, curated by Jason Fletcher (ISOSCELES), via presets-cream-of-the-crop
- The MilkDrop texture pack, and textures from the community MilkDrop 135k+ Presets MegaPack collected by Incubo_
- The authors of the MilkDrop presets
Sources and licences are listed in docs/THIRD_PARTY.md.
The app's own code is licensed under the GNU Lesser General Public License, version 2.1; see LICENSE. This matches projectM.
The bundled presets and textures are distributed under CC0 1.0 (LICENSES/CC0-1.0.txt): free for any use. The presets and textures themselves were freely released by their authors; authors who want their work removed can open an issue. Details in docs/THIRD_PARTY.md.






