An unofficial standalone server host/launcher for Jellyfin on Android (ARM64).
Fishbowl is a native Android application that hosts and runs the full Jellyfin Media Server (v10.11.11) directly on your Android device (ARM64).
It transforms any Android phone, tablet, or TV box into a standalone, energy-efficient home media streaming server without requiring root access, Docker, or external PC hardware.
- AI/LLM Usage Disclosure
- Key Features & Highlights
- System Architecture
- Client Ecosystem & Compatibility
- Step-by-Step Installation & Setup
- Storage Access Framework (SAF) Bridge
- Dynamic Metadata DNS Pipeline
- Memory-Safe Logging Engine
- Permissions & Privacy
- Directory Hierarchy & Persistence
- Building From Source
- Troubleshooting & FAQ
- License & Acknowledgments
In compliance with open-source community standards and the Jellyfin project's AI/LLM policies, we disclose that:
- Vibe Coding: This project was built utilizing a "vibe coding" methodologyβrelying on conversational programming, interactive agent instruction, and iterative design loops to rapidly prototype and assemble the application.
- Development Assistance: The Java wrappers, UI layouts, shell structures, and build configuration files were generated with the assistance of agentic AI coding tools (specifically Google Antigravity / Gemini models).
- Review & Verification: All generated code has been manually audited, integrated, refactored, and empirically tested on physical hardware (ARM64 Android devices) to ensure reliability, security, and performance. No code is shipped without manual verification.
- Documentation & Assets: README documentation, architectural diagrams, and project metadata templates were refined or generated with the aid of LLM tools.
- Full Jellyfin 10.11.11 Core: Direct POSIX execution on Android's Bionic C runtime (
libc.so) without virtualization or Docker containers. - Embedded .NET 9.0 Host: High-throughput JIT-compiled server core with optimized memory management.
- Jellyfin-FFmpeg Transcoder: Mobile-optimized native FFmpeg binary for on-the-fly video transcoding, audio remuxing, and HLS segmenting.
- SQLite3 Database Engine (
libe_sqlite3.so): Low-latency local database storage managing media libraries, user watch states, and item metadata.
- Pure Dark Mode (
#121316): OLED-optimized dark theme with distinct surface cards, crisp typography, and fluid Material Touch Ripples. - Real-Time Startup Progression: Displays authentic multi-stage initialization (
STARTING_RUNTIME->LAUNCHING_SERVER->WAITING_FOR_SERVER->CHECKING_READINESS->READY). - Dual-Band Network Hub: Instant local loopback (
http://127.0.0.1:8096) and local Wi-Fi LAN IP display (http://192.168.x.x:8096) with one-tapCOPY IPbuttons. - 3-Tab Navigation:
- Home: Server lifecycle dashboard, status pills, address cards, and action buttons (
OPEN JELLYFIN,START,STOP,RESTART). - Logs: Memory-capped, live-streaming diagnostic console with 500ms throttled rendering and smart auto-scrolling.
- Settings: Storage breakdown, SAF media folder bridge, software stack audit, and boot auto-start switches.
- Home: Server lifecycle dashboard, status pills, address cards, and action buttons (
- Foreground Service Supervision: Managed by
JellyfinServerServicewith an ongoing status notification (ID1001) preventing Android OS aggressive memory killing. - Smart CPU WakeLock: Automatically acquires a
PARTIAL_WAKE_LOCKwith an automatic safety timeout to maintain uninterrupted streaming when the screen is locked. - Immediate State Hydration: Asynchronous
reconcileStateAsync()directly resolves running server state on app launch/resume with zero UI latency.
- Native in-app WebView container allowing immediate local playback and administrative server configuration without leaving the application.
+-------------------------------------------------------------------------+
| Android User Space |
| |
| +-------------------------------------------------------------------+ |
| | Fishbowl UI Shell | |
| | JellyfinDroidActivity (3-Tab Pixel UI / Home / Logs / Settings) | |
| | JellyfinWebActivity (Hardware-Accelerated WebView Client) | |
| | JellyfinStorageActivity (SAF Document Tree File Bridge) | |
| +-------------------------------------------------------------------+ |
| | |
| +-------------------------------------------------------------------+ |
| | Lifecycle & Service Layer | |
| | JellyfinController (State Machine: STARTING -> READY) | |
| | JellyfinServerService (Foreground Service / Ongoing Notification)| |
| | JellyfinBootstrapper (Asset Extraction & Dynamic DNS Setup) | |
| +-------------------------------------------------------------------+ |
| | |
| +-------------------------------------------------------------------+ |
| | Native Subsystem (POSIX) | |
| | .NET 9.0 Host (dotnet) ---> Jellyfin.Server.dll (10.11.11) | |
| | Jellyfin-FFmpeg Engine ---> Hardware Transcoding / HLS Remux | |
| | libe_sqlite3.so Engine ---> Database Storage (~/.local/share) | |
| | libfontconfig / libfreetype ---> Subtitle Burn-In Engine | |
| +-------------------------------------------------------------------+ |
| |
+-------------------------------------------------------------------------+
Once Fishbowl is active on your device, you can stream your movies, shows, and music to any official Jellyfin client across your local home network:
| Client App | Supported Platforms | Features & Direct Stream |
|---|---|---|
| Jellyfin for Android TV | Google TV, FireStick, Shield TV, Xiaomi Box | 4K HDR, HEVC, Dolby Vision, Direct Play |
| Jellyfin Mobile | Android Smartphones & Tablets | Touch Gestures, Background Audio, Casting |
| Jellyfin for iOS | iPhone, iPad | Native Player, HLS Streaming, AirPlay |
| Web Browser | Chrome, Firefox, Safari, Edge, Brave | Full HTML5 Video Player, Admin Dashboard |
| Roku Client | Roku Streaming Sticks, Roku Smart TVs | Direct Play, On-The-Fly Transcoding |
| Swiftfin & Infuse | Apple TV, macOS, iOS | Native Metal Decoding, Subtitle Sync |
| Kodi Integration | Windows, Linux, LibreELEC, Raspberry Pi | Jellyfin for Kodi Addon / Direct Path |
Tip
Connecting Clients: Open any Jellyfin client on the same Wi-Fi network and enter the LAN Address shown on your Fishbowl Home screen (e.g., http://<YOUR-DEVICE-LAN-IP>:8096 or http://192.168.x.x:8096).
- Download the latest
Fishbowl-v1.4.0-release-universal.apkfrom GitHub Releases. - Install the APK on your ARM64 Android device.
- Grant Notification and Storage permissions when prompted.
- Launch Fishbowl.
- Tap the START SERVER button.
- The authentic stage pipeline will verify runtime environment, start the Dotnet process, and poll HTTP readiness.
- Once the hero badge turns green (SERVER RUNNING), tap OPEN JELLYFIN.
- Select your preferred display language.
- Create your admin username and password.
- Add your media libraries (point to
/sdcard/Movies,/sdcard/Music, or your SAF storage bridge path). - Configure your preferred metadata language (English, Spanish, French, German, etc.).
- Finish the wizard and start streaming!
Android 11+ enforces Scoped Storage boundaries. Fishbowl includes a built-in Storage Access Framework (SAF) document tree bridge:
- In Fishbowl, navigate to the Settings tab.
- Tap Manage Media Storage (SAF).
- Tap Add Media Folder and select any directory on internal storage, microSD card, or OTG USB storage using Android's system document picker.
- Fishbowl preserves persistent URI permissions across device reboots and surfaces folder size calculations dynamically.
Fishbowl uses dynamic multi-provider DNS resolution to ensure movie and TV show identification, metadata retrieval, and artwork fetching operate smoothly:
- DNS Resolvers: Embedded POSIX environment dynamically resolves DNS via Google DNS (
8.8.8.8) and Cloudflare DNS (1.1.1.1). - Metadata Endpoints: Seamlessly fetches data and posters from:
- The Movie Database (TMDb):
api.themoviedb.org,image.tmdb.org - The Open Movie Database (OMDb)
- Internet Movie Database (IMDb) metadata scrapers
- OpenSubtitles & MusicBrainz
- The Movie Database (TMDb):
- SSL / TLS Trust Store: Built-in Mozilla CA Certificate bundle (
cacert.pem) ensures secure HTTPS communication with all upstream providers.
Fishbowl features a hardened logging subsystem designed to prevent UI freezes during heavy transcoding or library imports:
- Decoupled Observers (
LogListener): Log stream updates are completely separated from Activity state rendering. - 500ms Handler Throttling: Incoming log lines from stdout/stderr are batched and posted to the UI looper at most 2 times per second.
- 30KB Bounded Ring Buffer: Memory consumption is strictly capped at ~500 lines, automatically discarding stale log lines without triggering garbage collection spikes.
- Smart Viewport Auto-Scrolling: Auto-scroll engages only when the user is already at the bottom of the log view, allowing you to scroll up and inspect past events without viewport jumping.
Fishbowl operates strictly within standard Android OS application sandboxing rules:
| Android Permission | Purpose |
|---|---|
FOREGROUND_SERVICE |
Keeps server process active in background |
FOREGROUND_SERVICE_MEDIA_PLAYBACK |
Android 14+ FGS media streaming classification |
WAKE_LOCK |
Prevents CPU sleep during active media streaming |
INTERNET & ACCESS_NETWORK_STATE |
Handles LAN and loopback socket communication |
READ_EXTERNAL_STORAGE / MANAGE_EXTERNAL_STORAGE |
Accesses local movie, music, and show files |
Privacy Verification:
- 0 Remote Trackers
- 0 Analytics Libraries
- 0 Telemetry Sockets
- 100% Local Storage & Processing
All Jellyfin server configuration, database, and cache files are stored within the app's sandboxed data directory:
| Directory Type | Absolute Android Path | Purpose |
|---|---|---|
| System Prefix | /data/data/com.fishbowl.app/files/usr |
Native binaries, Dotnet assemblies, FFmpeg executables, and shared C/C++ libraries. |
Persistent Data (--datadir) |
/data/data/com.fishbowl.app/files/home/.local/share/jellyfin |
Jellyfin SQLite database (jellyfin.db), user accounts, library definitions, and metadata. Survives all updates. |
Configuration (--configdir) |
/data/data/com.fishbowl.app/files/home/.config/jellyfin |
Server XML configuration (system.xml, network.xml, encoding.xml). |
Cache (--cachedir) |
/data/data/com.fishbowl.app/files/home/.cache/jellyfin |
Image thumbnail caches, transcoded media chunks, and temporary streaming buffers. |
Logs (--logdir) |
/data/data/com.fishbowl.app/files/home/.local/share/jellyfin/log |
On-disk server execution logs. |
- Operating System: Windows 10/11, macOS, or Linux
- JDK: OpenJDK 17 or OpenJDK 21
- Android SDK & NDK: Android SDK (API 28+), NDK r25+
- Gradle: Gradle 8.x / 9.x (wrapper included)
# 1. Clone the repository
git clone https://github.com/Suz41/Fishbowl.git
cd Fishbowl
# 2. Build Debug ARM64 APK
./gradlew assembleDebug
# 3. Build Universal Release APK
./gradlew assembleReleaseGenerated APKs will be located in app/build/outputs/apk/release/ and app/build/outputs/apk/debug/.
A: Ensure battery optimization is set to "Unrestricted" for Fishbowl in Android Settings (Apps -> Fishbowl -> Battery -> Unrestricted). Fishbowl runs an ongoing Foreground Service with WakeLock, but aggressive OEM battery managers (e.g. Xiaomi MIUI/HyperOS, Huawei EMUI, Vivo OriginOS, Samsung OneUI) may require explicit permission to run in the background.
A: Open the Fishbowl app, locate the LAN Address under the Network Connection card (e.g. http://<YOUR-DEVICE-LAN-IP>:8096 or http://192.168.1.xxx:8096), and enter that URL into any browser or Jellyfin app on any device connected to the same Wi-Fi network.
A: Simply install the updated APK over the existing installation. All database records, user accounts, and library configurations reside in --datadir (~/.local/share/jellyfin) which is preserved across APK updates.
- Fishbowl: Licensed under the GNU General Public License v3.0 (GPLv3).
- Jellyfin Core: Jellyfin Project (GPLv3).
- Packaging Foundation: Built upon the Termux open-source container architecture.