One-Player
Introduction: 增强的 Android 视频播放器
Tags:
Built with Kotlin, Jetpack Compose, Hilt, and Media3 / ExoPlayer. Continues from the original Next Player project with in-app language switching, settings backup & restore, and ASS subtitle effects.
Special thanks to the original Next Player project and all upstream contributors for the solid foundation and long-term maintenance.
✨ Highlights
| Feature | Description | |
|---|---|---|
| 🎬 | Smart Library | Folder / tree / flat views, search, grid & list layouts |
| ▶️ | Full Playback | Resume, autoplay, PiP, gestures, per-file track memory |
| 🔤 | Rich Subtitles | ASS effects, external subs, encoding & appearance tweaks |
| 🎨 | Material You | Dynamic color, in-app language switch, full theming |
| 💾 | Backup & Restore | Export / import all settings across devices |
| 🚀 | CI/CD Ready | Signing validation and release artifacts |
📖 Feature Guide
Media Library
- Browse videos in folder mode, tree mode, or flat video mode
- Search media from the library screen
- Switch list and grid layouts
- Sort by title, duration, size, date, and related view options
- Exclude selected folders from scanning
- Optionally ignore
.nomediaand include those directories in scanning - Refresh and verify media behavior faster with debug-only commands
Playback
- Play local videos directly from the library or external intents
- Continue playback from the previous position
- Autoplay the next video in the current folder
- Use Picture in Picture mode
- Keep background playback behavior configurable
- Adjust playback speed, long-press speed, zoom, and content scale
- Use seek, brightness, volume, zoom, and double-tap gestures
- Remember per-file selections like audio track and subtitle track
Subtitle and Audio
- Select built-in audio tracks and subtitle tracks
- Load external subtitle files from the system document picker
- Render ASS subtitles with effect support
- Configure preferred audio language and subtitle language
- Change subtitle font, bold text, text size, background, delay, speed, and text encoding
- Control decoder preferences for audio and video playback behavior
Personalization and Settings
- Switch app language inside the app
- Use Material 3 and dynamic color theming
- Configure gestures, player controls, orientation, decoder priority, and thumbnails
- Back up app settings and player settings to a file
- Restore settings from a backup file
- Reset settings when needed
Release and Debugging
- CI produces debug artifacts for branch validation
- Release workflow validates signing secrets before signed builds
📱 User Manual
1. First Launch
- Install a debug or release APK
- Grant media access permission when prompted
- If you enable
.nomediaoverride, also grant all-files access when Android asks for it
2. Browse Your Library
- Open the home screen and choose folder, tree, or video view
- Use search to find files quickly
- Open quick settings from the media screen to change sorting, layout, and view mode
- Hide folders you do not want to see from settings
3. Watch Videos
- Tap any video to open the player
- Swipe horizontally to seek
- Swipe vertically to control brightness or volume
- Double tap to trigger the configured skip action
- Pinch to zoom if zoom gestures are enabled
- Use PiP or background play if your settings allow it
4. Use Subtitles
- Open subtitle track selection inside the player for embedded tracks
- Use the subtitle picker to load an external subtitle file
- ASS subtitles support effect rendering, not only plain text display
- Fine-tune subtitle appearance and playback behavior from Settings > Subtitle
5. Back Up and Restore
- Open Settings > General
- Export current app and player settings to a backup file
- Import the backup later on the same or another device
- Use reset if you want a clean configuration again
6. Troubleshooting
- If the library looks incomplete, check folder exclusions and
.nomediabehavior - If playback fails, retry after granting media permissions again
- If subtitle appearance looks wrong, verify text encoding and ASS track selection
- If a signed release fails in CI, check the signing validation output first
🏗️ Project Structure
app/ Application entry points, manifest, release variants
core/common/ Logging, dispatchers, common helpers
core/data/ Repository implementations and mappers
core/database/ Room database, DAO, schema
core/datastore/ DataStore sources and serializers
core/domain/ Use cases
core/media/ Media scanning and playback services
core/model/ Shared models
core/ui/ Shared Compose UI, strings, theme
feature/player/ Player UI and playback flow
feature/settings/ Settings screens and preference logic
feature/videopicker/ Media library browsing, search, quick settings
.github/workflows/ CI, version, and release workflows
🔧 Build and Validation
Prerequisites
- Android Studio or Android SDK command-line tools
- JDK
25
Common Commands
./gradlew assembleDebug
./gradlew test
./gradlew ktlintCheck
./gradlew connectedAndroidTest
./gradlew ktlintCheck test assembleDebug --warning-mode=fail
🧑💻 Development Tutorial
Step 1: Clone and Open
git clone https://github.com/Kindness-Kismet/One-Player.git
cd One-Player
Open the project in Android Studio, let Gradle sync, and confirm JDK 25 is selected.
Step 2: Build a Debug APK
./gradlew assembleDebug
Install one of these outputs:
app/build/outputs/apk/debug/app-universal-debug.apkapp/build/outputs/apk/debug/app-arm64-v8a-debug.apkapp/build/outputs/apk/debug/app-x86_64-debug.apk
Step 3: Navigate the Codebase
Recommended reading order:
README.mdapp/src/main/java/one/next/player/MainActivity.ktfeature/videopicker/feature/player/feature/settings/core/modules for data, media, and shared UI
Step 4: Add or Change a Feature
A typical flow is:
- Add or adjust models in
core/model - Update repositories or persistence in
core/data,core/database, orcore/datastore - Add use-case logic in
core/domainwhen needed - Wire UI in the relevant
feature/*module - Verify strings and localization in
core/ui/src/main/res
Step 5: Validate Before Commit
./gradlew ktlintCheck test assembleDebug --warning-mode=fail
If the change touches player behavior, also run the app on a device or emulator and verify actual playback.
Step 6: Prepare a Release
- Update
app/build.gradle.ktswith the target version - Push a
release/vx.y.zbranch or run the release workflow manually - Let CI validate signing and build artifacts
- Review generated GitHub Release notes
