Adds an advanced playback setting to enable automatic refresh rate switching during playback When enabled, the app looks at the available display modes, chooses the best candidate, and attempts to switch to it. After playback ends, the display is switched back to the original mode. Closes #62 Closes #379
3.5 KiB
Wholphin developer's guide
See also the Contributing guide for general information on contributing to the project.
Overview
This project is an Android TV client for Jellyfin. It is written in Kotlin and uses the official Jellyfin Kotlin SDK to interact with the server.
The app is a single Activity (MainActivity) with MVVM architecture.
The app uses:
- Compose for the UI
- Navigation 3 for navigating app screen
- Room & DataStore for local data storage
- Hilt for dependency injection
- Media3/ExoPlayer for media playback
- Coil for image loading
- OkHttp for HTTP requests
Getting started
We follow GitHub's fork & pull request model for contributions.
After forking and cloning your fork, you can import the project into Android Studio.
You need a compatible Android Studio version for the configured AGP. This is generally Narwhal 3 Feature Drop | 2025.1.3 or newer. See https://developer.android.com/build/releases/gradle-plugin and `libs.versions.toml.
Code organization
Code is split into several packages:
data- app-specific data models and servicespreferences- Non-UI related code for user settings and preferencesservices- hilt injectable services often used by ViewModels for API callsui- User interface code and ViewModelsutil- Utility classes and functions
Native components
FFmpeg decoder module
Wholphin ships with media3 ffmpeg decoder module.
It is not required to build the extension in order to build the app locally.
You can build the module on MacOS or Linux with the build_ffmpeg_decoder.sh script.
MPV player backend
Wholphin has a playback engine that uses libmpv. The app uses JNI code from mpv-android and has an implementation of androidx.media3.common.Player to swap out for ExoPlayer.
See the build scripts for details on building this component.
App settings
App settings are available with the AppPreferences object and defined by different AppPreference objects (note the s differences).
The AppPreference objects are used to create the UI for configuring settings using the composable functions in com.github.damontecres.wholphin.ui.preferences.
How to add a new app setting
- Add entry in
WholphinDataStore.proto& build to generate classes - Add new
AppPreferenceobject inAppPreference.kt - Add new object to a
PreferenceGroup(listed inAppPreference.kt) - Update
AppPreferencesSerializerto set the default value for new installs - If needed, update
AppUpgradeHandlerto set the default value for app upgrades- Since preferences use proto3, the default values are zero, false, or the first enum, so only need this step if the default value is different