RAY LIU’s Island
中

Muon Music Player

Mobile App · 2026

✕
← Redstone Factory

A cross-platform mobile music player app built with Flutter, streaming and downloading YouTube audio/video ad-free with offline playback support.

Project Overview

Muon is a minimalist, ad-free mobile music player for iOS and Android that streams and downloads YouTube content. Users can search YouTube, play audio in the background with lock-screen controls, download audio (m4a) or full video (H.264/mp4), and manage offline playlists. The FastAPI backend handles download tasks asynchronously via a task queue with status polling, serves static media files, and runs a TTL-based disk cleanup service.

Technical Challenges & Solutions

  1. Background Audio on iOS & Android

    Maintaining uninterrupted audio playback when the app is backgrounded or the screen is locked on both platforms.

    Solution: Integrated audio_service to register as a background audio service, implementing the required platform callbacks for play/pause/skip. Combined with just_audio for actual playback, this gives native lock-screen controls and Bluetooth headset support.

  2. Async Download Task System

    YouTube downloads via yt-dlp can take 10–60+ seconds. A synchronous API would time out and leave the client hanging.

    Solution: Implemented an async task queue on the FastAPI backend: the POST /api/download endpoint immediately returns a task_id, while the Flutter client polls GET /api/status/{task_id} until the status is 'completed', then fetches the media URL.

  3. Offline Storage & Playlist Management

    Managing downloaded tracks and user playlists reliably in a local SQLite database on the device.

    Solution: Used Drift (type-safe SQLite ORM for Flutter) with code generation to define strongly-typed tables for tracks and playlists, ensuring safe migrations and compile-time query correctness.

Architecture

Flutter frontend uses Riverpod (code-gen) for state management, just_audio + audio_service for background playback, Drift (SQLite) for local offline storage, and Dio for HTTP. FastAPI backend wraps yt-dlp + ffmpeg in an async task system, exposes a /api/status/{task_id} polling endpoint, and serves downloaded files via StaticFiles. Deployed via Docker Compose.

Learnings

Building Muon gave me deep experience with Flutter's audio ecosystem (just_audio, audio_service) and the complexity of background media sessions across iOS and Android. Designing an async task queue on FastAPI with status polling was a valuable pattern for handling long-running jobs without blocking the API response cycle.

Tech Stack

Mobile Framework

FlutterDartRiverpod

Audio & Playback

just_audioaudio_servicevideo_player

Local Database

Drift (SQLite)

Backend

PythonFastAPI

Media Processing

yt-dlpffmpeg

Deployment

Docker Compose