OnAirDeck is a lightweight, high-performance radio automation console and web streaming suite built with the JUCE 8 framework. It bridges the gap between digital music playlists and live vocal performance, providing a professional "deck" experience for modern broadcasters.
- Advanced Broadcast Engine: Native support for ASIO (Windows) and CoreAudio (macOS) ensuring ultra-low latency for professional web radio standards.
- Smart Streaming: Integrated encoder for direct-to-server streaming via Icecast and Shoutcast protocols.
- Pro Voice-Over (Ducking): Intelligent automatic volume management to balance music and speech during live broadcast sessions.
- Dynamic Playlist Deck: Seamless track transitions and high-fidelity playback for continuous radio rotation.
- Embedded Web UI: The full On Air Deck interface (built with Vite + React from
andpia/on-air-deck-figma) runs inside a JUCEWebBrowserComponent, with a bidirectional JS β JUCE bridge.
- Core app:
andpia/on-air-deck - Frontend UI companion (required for Web UI development and Release bundle generation):
andpia/on-air-deck-figma, tracked here as thevendor/web-ui/submodule
OnAirDeck uses CMake for modern, cross-platform dependency management.
JUCE 8 required β OnAirDeck uses the
WebBrowserComponent::Options::withResourceProviderAPI introduced in JUCE 8. Thevendor/JUCEsubmodule is pinned to JUCE 8.0.12 or later. On Windows, the Microsoft WebView2 SDK NuGet package is required β without it JUCE falls back to the legacy IE backend which does not support modern JavaScript (ES modules) and the UI will show a blank white screen at runtime.
Ninja required β
CMakePresets.jsonuses theNinja Multi-Configgenerator fordebugandrelease, so Ninja must be available on PATH before runningcmake --preset ....
-
Clone the repository:
git clone --recursive https://github.com/andpia/on-air-deck.git cd on-air-deck -
Generate and Build (Quick Start - Debug):
cmake --preset debug cmake --build --preset debug
-
Release build: Build
vendor/web-ui/distfirst (or passWEBUI_DIST_PATHto an external dist), then:cmake --preset release cmake --build --preset release
If compiling on Linux, ensure you have the required development libraries installed:
sudo apt-get update && sudo apt-get install libasound2-dev libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libgl-dev libwebkit2gtk-4.1-dev libgtk-3-dev libcurl4-openssl-devFor a complete automated setup on Ubuntu 24.04 LTS:
bash scripts/setup-linux.shThis script installs all required JUCE dependencies and system libraries needed for OnAirDeck compilation.
The application embeds the On Air Deck Web UI (from andpia/on-air-deck-figma) inside a native JUCE window using WebBrowserComponent.
In Debug builds the app first loads bundled static assets (if available), and otherwise connects to the Vite dev server so UI changes appear instantly without recompiling JUCE.
- Start the Vite dev server from the
vendor/web-ui/submodule:cd vendor/web-ui npm install npm run dev # starts http://localhost:5173 by default
- Build OnAirDeck in Debug mode and run it:
The embedded browser will load
cmake --preset debug cmake --build --preset debug ./out/build/debug/OnAirDeck_artefacts/Debug/OnAirDeck # path varies by OShttp://localhost:5173and reflect live edits.
Configuring the dev server URL: pass
-DWEBUI_DEV_SERVER_URL=http://localhost:<port>to CMake if Vite listens on a different port.
-
Build the frontend static bundle:
cd vendor/web-ui npm run build # outputs to dist/
Vite base path: the frontend must set
base: './'invite.config.*so that asset paths are relative and work across local origins (file://andjuce://). Confirm this line exists invite.config.ts:export default defineConfig({ base: './', ... })
-
Build OnAirDeck in Release:
cmake --preset release cmake --build --preset release
If your frontend dist is outside
vendor/web-ui/dist, point CMake at that folder explicitly:cmake --preset release -DWEBUI_DIST_PATH=/path/to/on-air-deck-figma/dist cmake --build --preset release
CMake will copy the Web UI to the correct location automatically:
- macOS:
OnAirDeck.app/Contents/Resources/WebUI/ - Windows / Linux:
WebUI/next to the executable
Release configure is fail-fast for single-config generators. With multi-config generators (for example Ninja Multi-Config), configure emits a warning if
WEBUI_DIST_PATHis missing or invalid; ensure the dist folder exists before building--config Release.The Web UI is therefore bundled with the Release app package, but not embedded directly into the executable binary. At runtime, the app serves these assets via JUCE's internal
juce://resource origin. - macOS:
| Variable | Default | Description |
|---|---|---|
WEBUI_DIST_PATH |
vendor/web-ui/dist when present |
Path to the Vite dist/ folder. If not set explicitly, CMake auto-detects the submodule build output when available. |
WEBUI_DEV_SERVER_URL |
http://localhost:5173 |
URL loaded in Debug builds. |
π Read the full documentation on GitHub Pages β
Project documentation is now built with MkDocs and published through GitHub Pages.
- Install the documentation dependencies:
python3 -m pip install -r ./docs/mkdocs-requirements.txt
- Start the local documentation server:
mkdocs serve
- Open
http://127.0.0.1:8000in your browser.
To generate the static site locally:
mkdocs build --strictThe generated site will be written to the out/docs/site/ directory.
To run frontend + CMake Release build in one command:
bash scripts/release.shOptional environment variables:
FRONTEND_DIR: path to frontend repo (default:vendor/web-ui, fallback:../on-air-deck-figma)BUILD_DIR: optional custom build directory (if omitted,RELEASE_PRESETis used)RELEASE_PRESET: CMake preset for release builds (default:release)DIST_DIR: frontend dist path (default:$FRONTEND_DIR/dist)
This repository provides CMakePresets.json to standardize output folders:
debug->out/build/debugrelease->out/build/release
You can use CMake directly:
cmake --preset debug
cmake --build --preset debug
cmake --preset release
cmake --build --preset releaseUse the cleanup script for common reset scenarios:
bash scripts/clean.sh safeAvailable modes:
safe: removesout/full: removesout/,vendor/web-ui/dist, andvendor/web-ui/node_modulesdeep: removesfulltargets plus legacybuild/and known JUCE submodule build folderspristine --yes: runsgit clean -fdxin the repo and all submodules
Legacy generated output folders build-debug, build-release, and site are deprecated in favor of the out/ structure.
JavaScript can send actions to JUCE by navigating to the custom URL scheme myapp://:
// Trigger an action from the Web UI
window.location = 'myapp://setVolume?value=0.75';
window.location = 'myapp://play';
window.location = 'myapp://stop';JUCE intercepts the URL in WebUIComponent::pageAboutToLoad() before any network request is made, parses the action and query parameters, logs them with DBG, and cancels the navigation so the page stays intact.
- JS side β navigate to
myapp://<action>[?key=value&...] - JUCE side β add a new
else if (action == "<action>")branch insideWebUIComponent::handleBridgeAction()insrc/WebUIComponent.cpp:
else if (action == "myNewAction")
{
const juce::String param = params["myParam"];
DBG ("WebUIComponent: myNewAction -> " + param);
// Forward to the audio engine or other JUCE subsystem
}- Audio Interface: Use an ASIO driver on Windows for the best broadcasting experience.
- Streaming Output: Supports MP3/AAC streams for global web radio compatibility.
- Bitrate: Optimized for 64β128 kbps broadcast standards.
This project is licensed under the GNU GPLv3. See the LICENSE file for more details.
| Platform | Web Backend | Resource Provider | Notes |
|---|---|---|---|
| macOS | WebKit (WKWebView) | β Available | Assets served via juce://juce.backend/ |
| Linux | WebKit2GTK | β Available | Assets served via juce://juce.backend/ |
| Windows + WebView2 | Edge/Chromium | β Available | Assets served via https://juce.backend/ |
| Windows (no WebView2) | Internet Explorer | β Not available |
Installing WebView2 on Windows (required):
- Install the Microsoft WebView2 SDK NuGet package into your local NuGet package directory:
Register-PackageSource -Name nuget -ProviderName NuGet ` -Location https://www.nuget.org/api/v2 -Trusted -Force Install-Package Microsoft.Web.WebView2 -Scope CurrentUser -Force
- Run CMake β
FindWebView2.cmake(from JUCE) will detect the package automatically and enableJUCE_USE_WIN_WEBVIEW2=1.
If the SDK is absent CMake now prints a warning and the build continues, but the resulting app will not display the UI.
If you see error C2039: 'withResourceProvider': is not a member of 'juce::WebBrowserComponent::Options', it means your JUCE copy is older than JUCE 8 or WebView2 is not enabled. Make sure:
vendor/JUCEis at JUCE 8.0.12 or newer (git submodule update --init --recursive)- On Windows, install the WebView2 SDK as described above
Made with β€οΈ, JUCE 8 and a passion for Radio Broadcasting