Skip to content

Commit 455163f

Browse files
committed
add android tv build api build script
1 parent 1312656 commit 455163f

7 files changed

Lines changed: 1097 additions & 0 deletions

File tree

.env.example

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@ JELLYFIN_SERVER_URL=http(s)://your.server.url
33
JELLYFIN_API_KEY=apikey
44
JELLYFIN_USERNAME=YourAdminUsername
55

6+
# Android TV APK Build Configuration
7+
# KARAOKE_SERVER_URL: The URL where your Karaoke server will be accessible from Android TV devices
8+
# This should be the IP address and port where your karaoke server runs on your local network
9+
# The Android TV app will connect to this URL to access the karaoke interface
10+
# Examples:
11+
# - Local network: http://192.168.1.100:3967 (replace with your server's IP)
12+
# - Docker host: http://192.168.1.50:3967 (if running in Docker)
13+
# - Different port: http://192.168.1.100:8080 (if using a different port)
14+
# Note: Use your server's actual IP address, not localhost, so Android TV can reach it
15+
KARAOKE_SERVER_URL=http://192.168.1.100:3967
16+
617
# TV Display Timing Configuration (in milliseconds)
718
RATING_ANIMATION_DURATION=15000
819
NEXT_SONG_DURATION=15000

.env.local.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ JELLYFIN_SERVER_URL=http://localhost:8096
33
JELLYFIN_API_KEY=your_jellyfin_api_key_here
44
JELLYFIN_USERNAME=your_jellyfin_username_here
55

6+
# Android TV APK Build Configuration
7+
# KARAOKE_SERVER_URL: The URL where your Karaoke server will be accessible from Android TV devices
8+
# This should be the IP address and port where your karaoke server runs on your local network
9+
# The Android TV app will connect to this URL to access the karaoke interface
10+
# Examples:
11+
# - Local network: http://192.168.1.100:3967 (replace with your server's IP)
12+
# - Docker host: http://192.168.1.50:3967 (if running in Docker)
13+
# - Different port: http://192.168.1.100:8080 (if using a different port)
14+
# - Reverse proxy: https://your.hostname.com (if using reverse proxy)
15+
# Note: Use your server's actual IP address, not localhost, so Android TV can reach it
16+
KARAOKE_SERVER_URL=http://192.168.1.100:3967
17+
618
# Playlist Filtering (optional)
719
# Only show playlists whose names match this regex pattern (case-insensitive)
820
# Example: PLAYLIST_FILTER_REGEX=^(Karaoke|Sing).*

docs/ANDROID_TV_BUILD.md

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
# Building Android TV APK
2+
3+
This guide explains how to build an Android TV APK for the Karaoke for Jellyfin project using Google's Bubblewrap.
4+
5+
## Prerequisites
6+
7+
Before building the APK, ensure you have the following installed:
8+
9+
1. **Node.js** (version 18 or higher)
10+
2. **npm** (comes with Node.js)
11+
3. **Java Development Kit (JDK)** (version 8 or higher)
12+
4. **Android SDK** (optional, for installing to device)
13+
14+
### Installing Java
15+
16+
**On macOS:**
17+
18+
```bash
19+
brew install openjdk@11
20+
```
21+
22+
**On Ubuntu/Debian:**
23+
24+
```bash
25+
sudo apt update
26+
sudo apt install openjdk-11-jdk
27+
```
28+
29+
**On Windows:**
30+
Download and install from [Oracle's website](https://www.oracle.com/java/technologies/downloads/) or use [OpenJDK](https://adoptium.net/).
31+
32+
### Installing Android SDK (Optional)
33+
34+
Only needed if you want to install the APK directly to a connected device:
35+
36+
1. Download [Android Studio](https://developer.android.com/studio)
37+
2. Install Android SDK through Android Studio
38+
3. Add `adb` to your PATH
39+
40+
## Building the APK
41+
42+
### Method 1: Using the Node.js Script (Recommended)
43+
44+
1. **Configure your server URL** in `.env.local`:
45+
46+
```bash
47+
# Copy the example file if you haven't already
48+
cp .env.local.example .env.local
49+
50+
# Edit .env.local and set your server URL
51+
KARAOKE_SERVER_URL=http://192.168.1.100:3967
52+
```
53+
54+
2. **Make the script executable:**
55+
56+
```bash
57+
chmod +x scripts/build-tv-apk.js
58+
```
59+
60+
3. **Run the build script:**
61+
62+
```bash
63+
npm run build:android-tv
64+
```
65+
66+
Or directly:
67+
68+
```bash
69+
node scripts/build-tv-apk.js
70+
```
71+
72+
4. **Follow the prompts:**
73+
- The script will automatically use your `KARAOKE_SERVER_URL` from `.env.local`
74+
- If not set, it will prompt you to enter the server URL
75+
- Choose whether to install to a connected device
76+
77+
### Method 2: Using the Bash Script
78+
79+
1. **Make the script executable:**
80+
81+
```bash
82+
chmod +x scripts/build-android-tv.sh
83+
```
84+
85+
2. **Run the script:**
86+
```bash
87+
./scripts/build-android-tv.sh
88+
```
89+
90+
## What the Build Process Does
91+
92+
1. **Dependency Check**: Verifies all required tools are installed
93+
2. **TV Manifest Creation**: Creates an Android TV-specific web app manifest
94+
3. **Next.js Build**: Builds the production version of your app
95+
4. **Bubblewrap Initialization**: Sets up the Trusted Web Activity project
96+
5. **Android TV Configuration**: Adds TV-specific features and permissions
97+
6. **APK Build**: Compiles the final APK file
98+
7. **Installation** (optional): Installs to connected Android TV device
99+
100+
## Output
101+
102+
After a successful build, you'll find:
103+
104+
- `karaoke-tv.apk` - The Android TV APK file in your project root
105+
- `android-tv-build/` - Temporary build directory (can be deleted)
106+
107+
## Android TV Specific Features
108+
109+
The generated APK includes:
110+
111+
### Required Features
112+
113+
- `android.software.leanback` - Identifies as Android TV app
114+
- `android.hardware.touchscreen` (not required) - Works without touchscreen
115+
116+
### Permissions
117+
118+
- `android.permission.INTERNET` - Network access
119+
- `android.permission.ACCESS_NETWORK_STATE` - Network state monitoring
120+
- `android.permission.WAKE_LOCK` - Prevent screen sleep during karaoke
121+
122+
### App Configuration
123+
124+
- **Display Mode**: Fullscreen for immersive experience
125+
- **Orientation**: Landscape (optimized for TV screens)
126+
- **Start URL**: `/tv` (opens directly to TV display interface)
127+
- **Launcher Category**: `LEANBACK_LAUNCHER` (appears in Android TV launcher)
128+
129+
## Installing on Android TV
130+
131+
### Method 1: ADB Installation (Recommended)
132+
133+
1. **Enable Developer Options on your Android TV:**
134+
- Go to Settings > Device Preferences > About
135+
- Click "Build" 7 times to enable Developer Options
136+
- Go back to Settings > Device Preferences > Developer Options
137+
- Enable "USB Debugging" and "Apps from Unknown Sources"
138+
139+
2. **Connect via ADB:**
140+
141+
```bash
142+
# Find your Android TV's IP address in Settings > Network
143+
adb connect YOUR_TV_IP_ADDRESS:5555
144+
```
145+
146+
3. **Install the APK:**
147+
```bash
148+
adb install karaoke-tv.apk
149+
```
150+
151+
### Method 2: USB Installation
152+
153+
1. Copy `karaoke-tv.apk` to a USB drive
154+
2. Insert USB drive into Android TV
155+
3. Use a file manager app to navigate to the APK
156+
4. Install the APK (you may need to enable "Unknown Sources")
157+
158+
### Method 3: Network Installation
159+
160+
1. Upload the APK to a cloud storage service
161+
2. Download and install a file manager on your Android TV
162+
3. Download and install the APK through the file manager
163+
164+
## Troubleshooting
165+
166+
### Build Issues
167+
168+
**"Java not found" error:**
169+
170+
- Ensure Java is installed and in your PATH
171+
- Try: `java --version` to verify installation
172+
173+
**"Bubblewrap command not found":**
174+
175+
- The script should auto-install Bubblewrap CLI
176+
- Manual install: `npm install -g @bubblewrap/cli`
177+
178+
**Build fails during APK generation:**
179+
180+
- Ensure you have sufficient disk space
181+
- Check that your server URL is accessible
182+
- Verify all dependencies are correctly installed
183+
184+
### Installation Issues
185+
186+
**"App not installed" on Android TV:**
187+
188+
- Enable "Unknown Sources" in Developer Options
189+
- Ensure the APK is not corrupted (try rebuilding)
190+
- Check available storage space on the TV
191+
192+
**ADB connection issues:**
193+
194+
- Ensure USB Debugging is enabled
195+
- Try disconnecting and reconnecting: `adb disconnect` then `adb connect IP:5555`
196+
- Restart ADB server: `adb kill-server` then `adb start-server`
197+
198+
### Runtime Issues
199+
200+
**App crashes on startup:**
201+
202+
- Verify your Karaoke server is running and accessible
203+
- Check the server URL is correct
204+
- Ensure the `/tv` endpoint is working in a browser
205+
206+
**Network connectivity issues:**
207+
208+
- Verify Android TV and server are on the same network
209+
- Check firewall settings on the server
210+
- Test connectivity by opening the server URL in the TV's browser
211+
212+
## Customization
213+
214+
### Changing App Details
215+
216+
Edit the configuration in `scripts/build-tv-apk.js`:
217+
218+
```javascript
219+
const CONFIG = {
220+
packageName: "com.jellyfin.karaoke.tv", // Android package name
221+
appName: "Karaoke TV", // Display name
222+
buildDir: "android-tv-build", // Build directory
223+
manifestFile: "public/manifest-tv.json", // TV manifest
224+
outputApk: "karaoke-tv.apk", // Output filename
225+
};
226+
```
227+
228+
### Adding Custom Icons
229+
230+
Replace the icons in the `public/icons/` directory with your custom icons. Ensure you have all required sizes:
231+
232+
- 48x48, 72x72, 96x96, 128x128, 144x144, 152x152, 192x192, 256x256, 384x384, 512x512
233+
234+
### Modifying TV-Specific Settings
235+
236+
Edit the TV manifest creation in the build script to customize:
237+
238+
- Theme colors
239+
- Orientation preferences
240+
- Display mode
241+
- App categories
242+
243+
## Security Considerations
244+
245+
### Keystore Management
246+
247+
For production builds, you should:
248+
249+
1. **Generate a keystore:**
250+
251+
```bash
252+
keytool -genkey -v -keystore android.keystore -alias android -keyalg RSA -keysize 2048 -validity 10000
253+
```
254+
255+
2. **Configure Bubblewrap to use your keystore:**
256+
- Edit `twa-manifest.json` in the build directory
257+
- Update the `signingKey` section with your keystore details
258+
259+
3. **Keep your keystore secure:**
260+
- Never commit keystores to version control
261+
- Store keystores in a secure location
262+
- Back up your keystore safely
263+
264+
### Network Security
265+
266+
- Use HTTPS for production deployments
267+
- Implement proper authentication if needed
268+
- Consider network restrictions for sensitive environments
269+
270+
## Advanced Configuration
271+
272+
### Custom Bubblewrap Settings
273+
274+
You can modify the `twa-manifest-template.json` file to customize advanced Bubblewrap settings:
275+
276+
- Minimum SDK version
277+
- Target SDK version
278+
- Additional permissions
279+
- Custom features
280+
- Splash screen settings
281+
282+
### Build Automation
283+
284+
For CI/CD integration, you can automate the build process:
285+
286+
```bash
287+
# Set environment variables
288+
export KARAOKE_SERVER_URL="http://your-server:3967"
289+
export SKIP_INSTALL="true"
290+
291+
# Run automated build
292+
node scripts/build-tv-apk.js
293+
```
294+
295+
## Support
296+
297+
If you encounter issues:
298+
299+
1. Check the [troubleshooting section](#troubleshooting) above
300+
2. Verify all prerequisites are installed correctly
301+
3. Ensure your Karaoke server is running and accessible
302+
4. Check the [Bubblewrap documentation](https://github.com/GoogleChromeLabs/bubblewrap) for advanced issues
303+
304+
For project-specific issues, please check the main project documentation or create an issue in the repository.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"dev": "node server.js",
77
"dev:next": "next dev --turbopack",
88
"build": "next build",
9+
"build:android-tv": "node scripts/build-tv-apk.js",
910
"start": "NODE_ENV=production node server.js",
1011
"start:next": "next start",
1112
"lint": "lint-staged",

0 commit comments

Comments
 (0)