Skip to content
delfuriaPublic

About

Cross-platform .NET MAUI 10 and Uno Platform app for AzuraCast webradio streaming.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

RadioE45

Cross-platform .NET MAUI 10 and Uno Platform app for AzuraCast webradio streaming.

Download

Get it from Microsoft Store Download on the App Store

Join the beta

Want to try RadioE45 before the public release? Join the preliminary tests:

Android beta Linux preview

Platforms

  • iOS 15+
  • Android 8.0+ (API 26), including Android TV and Google TV
  • macOS (Mac Catalyst) 15+
  • Windows 10 (build 17763+)
  • Linux (preview): Debian/Ubuntu-based distributions, .deb package for x64 and arm64
  • Web: modern desktop and mobile browsers, nothing to install (installable as an app)

Features

  • Background audio streaming (iOS: native AVPlayer for HLS and an in-app AudioQueue player for MP3/AAC streams; Android: Media3; Mac Catalyst and Windows: CommunityToolkit.Maui.MediaElement)
  • Now Playing updated every 10 seconds from the AzuraCast API
  • Cover art, artist, and current track title
  • LIVE indicator with streamer name
  • Listener count
  • Player with play/pause/stop and volume control
  • Station list with quick selection
  • Podcast support with saved playback position (resume where you left off) and filters by season, episode, and listening status
  • Song requests, when enabled by the station's AzuraCast platform
  • Recently played tracks list
  • Local persistence with SQLite
  • Dark theme by default
  • Update check: once a day, on the first launch, the app tells you when a newer version is available (App Store on iOS and Mac, Microsoft Store or GitHub Releases on Windows, GitHub Releases for the Linux .deb, the site itself on the web), and Settings has a manual check
  • Apple CarPlay support (iOS)
  • Android Auto support
  • Web app in the browser, built with Uno Platform and installable as an app
  • Android TV and Google TV support, with remote-control (D-pad) screens

Android Auto

Android Auto is now implemented. The Android audio layer was rebuilt: playback moved from CommunityToolkit.Maui.MediaElement to AndroidX Media3 / ExoPlayer with a single MediaLibraryService, enabling Android Auto, Bluetooth/AVRCP controls, and reliable background playback. Full details (technical analysis, rebuild report, dev setup, in Italian and English) are in docs/android-auto-media3/.

Apple CarPlay

CarPlay is implemented for iOS with the CarPlay Audio entitlement. The car screen shows the station list (CPListTemplate); choosing a station starts playback and opens Now Playing (CPNowPlayingTemplate) with track, artist, cover art and elapsed time. Play, pause and next/previous station work from the car controls and the iPhone lock screen. The app can be started directly from CarPlay without opening it on the iPhone first.

Live MP3/AAC streams are played by an in-app AudioQueue player: with AVPlayer CarPlay waited about 20 seconds before the first sound (analysis in docs/carplay-ios/carplay-mp3-start-delay.md). Architecture, files and test procedure: docs/carplay-ios/.

Run it in the browser

Radio E45 also runs in the browser, with no installation: open https://delfuria.github.io/RadioE45/ on a desktop or mobile browser and press Play.

The web app is built with Uno Platform (net10.0-browserwasm, WebAssembly) and shares its logic with the native apps through RadioE45.Core: the same stations, now playing, song requests, podcasts and schedule, with the same view models. It can also be installed as an app from the browser menu (progressive web app), and it checks by itself when a newer version is available.

It is published automatically to GitHub Pages from main (pages.yml). To build and run it locally see Linux and Web (Uno Platform) below.

Android TV and Google TV

The Android app also runs on Android TV and Google TV, with screens designed for the remote control and for viewing from the couch. It is the same app and the same package as the phone version: on a TV it shows a dedicated interface instead of the touch one.

  • On Air: cover art, title and artist, progress, listener count, the next track when the station publishes it, previous/next station and favorite
  • Request: search songs with the on-screen keyboard and send a request, when the station enables it
  • Podcasts: shows and episodes, with the saved position and Β±30 s seek from the D-pad, when the station has podcasts
  • Schedule: the station's programs at full screen, with streamers marked by a microphone
  • Channels: choose the station, and add, edit or delete stations

Everything is reachable with the D-pad (up, down, left, right, OK, Back) and the media keys of the remote. The TV has no settings page and no side menu. Tested on the Android TV emulator and on a Sony BRAVIA Google TV; the release package includes armeabi-v7a, needed by 32-bit TVs. Plan, measurements and remaining decisions: docs/ANDROID-TV-ROADMAP.md.

Documentation

All documentation lives in docs/:

Topic Path
Android Auto / Bluetooth β†’ Media3 rebuild (IT + EN) docs/android-auto-media3/
Apple CarPlay (architecture, tests, App Store) docs/carplay-ios/
CarPlay / Android Auto β€” original implementation docs/carplay/
UI localization (.resx) docs/LOCALIZATION.md
Store distribution docs/STORE-DISTRIBUTION.md Β· docs/store-descriptions.md
Version bump procedure docs/VERSION-BUMP.md
Windows build notes docs/WINDOWS-README.md
App Store review 5.2.3 (third-party content, Terms of Use) docs/APP-REVIEW-5.2.3.md
App Store review 5.1.1 (Local Network purpose string, private hosts) docs/APP-REVIEW-5.1.1.md
Tester distribution docs/tester/distribuzione-tester.md

Preloaded stations

The app ships with no third-party catalog. The only stations it can add on first launch are these two; every other station is added by the user via public URL.

Name Server
RadioE45 (operated by the developer) radioe45.ddns.net
AzuraTest Radio (official AzuraCast demo) demo.azuracast.com

On first launch the app also shows Terms of Use once (see docs/APP-REVIEW-5.2.3.md).

Development

Secrets configuration

RadioE45/AppSecrets.cs contains sensitive data (e.g. the Sentry DSN) and is excluded from the repository via .gitignore. Before building, create it from the template:

cp RadioE45/AppSecrets.template.cs RadioE45/AppSecrets.cs

Then open AppSecrets.cs and fill in the real values:

internal static class AppSecrets
{
    public const string SentryDsn = "https://..."; // your Sentry DSN
}

Without this file the project will not compile. Never commit AppSecrets.cs.

# Restore packages
dotnet restore RadioE45/RadioE45.csproj

macOS (Mac Catalyst)

# Debug build
dotnet build -f net10.0-maccatalyst RadioE45/RadioE45.csproj

# Run on macOS
dotnet build -t:Run -f net10.0-maccatalyst RadioE45/RadioE45.csproj

# Release β€” universal binary (x64 + arm64, default in Release config)
dotnet publish -f net10.0-maccatalyst -c Release RadioE45/RadioE45.csproj

# Release β€” x64 only (Intel Mac), self-contained
dotnet publish -f net10.0-maccatalyst -c Release -r maccatalyst-x64 --self-contained RadioE45/RadioE45.csproj

# Release β€” arm64 only (Apple Silicon), self-contained
dotnet publish -f net10.0-maccatalyst -c Release -r maccatalyst-arm64 --self-contained RadioE45/RadioE45.csproj

Output: RadioE45/bin/Release/net10.0-maccatalyst/

In Release config the default is already a universal binary (x64 + arm64). The Mac App Store requires either both architectures or x64 only β€” never arm64 alone.
With --self-contained the .NET 10 runtime is bundled in the .app; without it the target machine must have the runtime installed.

Windows

Must be built on a Windows machine.

# Release β€” x64, self-contained (.exe, no MSIX)
dotnet publish -f net10.0-windows10.0.19041.0 -c Release -r win-x64 --self-contained RadioE45/RadioE45.csproj

# Release β€” arm64, self-contained (.exe, no MSIX)
dotnet publish -f net10.0-windows10.0.19041.0 -c Release -r win-arm64 --self-contained RadioE45/RadioE45.csproj

Output: RadioE45/bin/Release/net10.0-windows10.0.19041.0/win-x64/publish/

WindowsPackageType=None is already set in the project, so the output is an unpackaged .exe with no MSIX wrapper.
Remove --self-contained (or pass --self-contained false) to produce a smaller, framework-dependent executable that requires .NET 10 installed on the target machine.

iOS

Requires macOS with Xcode installed. Physical device deployment requires a valid Apple Developer account.

# Debug build
dotnet build -f net10.0-ios RadioE45/RadioE45.csproj

# Release β€” physical device (arm64), signed
dotnet publish -f net10.0-ios -c Release -r ios-arm64 --self-contained RadioE45/RadioE45.csproj \
  -p:CodesignKey="iPhone Distribution: <Your Name>" \
  -p:CodesignProvision="<Provisioning Profile Name>"

# Release β€” simulator arm64 (Apple Silicon Mac), no signing required
dotnet publish -f net10.0-ios -c Release -r iossimulator-arm64 --self-contained RadioE45/RadioE45.csproj

# Release β€” simulator x64 (Intel Mac)
dotnet publish -f net10.0-ios -c Release -r iossimulator-x64 --self-contained RadioE45/RadioE45.csproj

The .NET runtime is always embedded in the .ipa bundle β€” --self-contained is effectively implicit for iOS.
Obtain the distribution certificate and provisioning profile from Apple Developer.

Android

# Debug build
dotnet build -f net10.0-android RadioE45/RadioE45.csproj

# Release APK β€” all ABIs (arm64-v8a, armeabi-v7a, x86_64)
dotnet publish -f net10.0-android -c Release RadioE45/RadioE45.csproj

# Release APK β€” arm64 only (modern devices)
dotnet publish -f net10.0-android -c Release -r android-arm64 RadioE45/RadioE45.csproj

# Release APK β€” x64 only (emulators, Intel Chromebooks)
dotnet publish -f net10.0-android -c Release -r android-x64 RadioE45/RadioE45.csproj

Output: RadioE45/bin/Release/net10.0-android/publish/

The Mono runtime is always bundled inside the APK β€” --self-contained is implicit and has no effect here.
To sign the APK for store distribution, add:

-p:AndroidSigningKeyStore=key.jks \
-p:AndroidSigningKeyAlias=<alias> \
-p:AndroidSigningKeyPass=<pass> \
-p:AndroidSigningStorePass=<pass>

Linux and Web (Uno Platform)

The Linux desktop app and the web app are built with Uno Platform from the RadioE45.Uno project, which shares the logic in RadioE45.Core. Build them on Linux (Ubuntu/Debian recommended) or on macOS for the desktop and web targets.
AppSecrets.cs is not needed: the Uno projects do not use it.

Requirements (Ubuntu/Debian):

# System packages (libVLC for playback, X11 and fontconfig for the desktop renderer)
sudo apt update && sudo apt install -y git curl \
  vlc libvlc-dev libvlc5 libx11-dev libfontconfig1 libice6 libsm6

# .NET 10 SDK (or: dotnet-install.sh --channel 10.0)
sudo apt install -y dotnet-sdk-10.0

# Uno Platform checks and WebAssembly workload (web target)
dotnet tool install -g uno.check && uno-check --target linux --non-interactive
dotnet workload install wasm-tools

Packaging a .deb also needs dpkg-deb (included in dpkg on Linux; on macOS: brew install dpkg).

# Restore packages
dotnet restore RadioE45.Uno/RadioE45.Uno.csproj

# Desktop debug build and run
dotnet build RadioE45.Uno -f net10.0-desktop
dotnet run --project RadioE45.Uno -f net10.0-desktop

# Web debug build and run (http://localhost:5045)
dotnet build RadioE45.Uno -f net10.0-browserwasm
dotnet run --project RadioE45.Uno -f net10.0-browserwasm

# Release .deb package (x64 or arm64)
packaging/linux/build-deb.sh linux-x64 <output-dir>
packaging/linux/build-deb.sh linux-arm64 <output-dir>

Output: <output-dir>/radioe45_<version>_<amd64|arm64>.deb. The .deb is self-contained for .NET; libVLC and the other libraries come from the system and are declared as package dependencies.

The Windows libVLC binaries (pulled in by the Uno media player package) are excluded from the Linux publish, so the .deb stays around 40–45 MB.
The Linux package is a preview; the MAUI app remains the main app on macOS and Windows.

Tech stack

  • Uno Platform β€” Linux desktop and web app (shares RadioE45.Core with the MAUI app)
  • .NET MAUI 10 β€” cross-platform framework
  • CommunityToolkit.Mvvm β€” MVVM with source generators
  • CommunityToolkit.Maui.MediaElement β€” audio streaming + background
  • Refit β€” typed HTTP client for the AzuraCast API
  • sqlite-net-pcl β€” local station persistence
  • Uno Platform β€” Linux desktop and web app (shares RadioE45.Core with the MAUI app)

About

Cross-platform .NET MAUI 10 and Uno Platform app for AzuraCast webradio streaming.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages