Files
iptv-app/README.md

557 lines
16 KiB
Markdown

# IPTV Player
A modern, feature-rich Android IPTV streaming application built with Jetpack Compose and Media3 ExoPlayer. This app allows users to stream live TV channels from M3U/M3U8 playlists with a beautiful Material Design 3 interface.
## Features
### Core Features
- **IPTV Streaming**: Stream live TV channels from M3U/M3U8 playlists
- **Channel Categories**: Automatic grouping of channels by category (Sports, News, Movies, Kids, etc.)
- **Search Functionality**: Real-time search with debouncing for quick channel discovery
- **Favorites Management**: Mark channels as favorites for quick access
- **Offline Caching**: 24-hour channel cache for offline browsing
- **Pull-to-Refresh**: Swipe down to refresh channel list
### Player Features
- **Media3 ExoPlayer**: Modern, extensible media player with HLS/DASH support
- **Fullscreen Mode**: Immersive landscape playback with gesture controls
- **Audio Focus Management**: Proper audio focus handling with ducking support
- **Multiple Audio Tracks**: Support for multi-language audio streams
- **Video Quality Selection**: Auto and manual quality selection
- **Subtitle Support**: Multi-language subtitle track selection
- **Picture-in-Picture**: Background playback support (Android O+)
### UI/UX Features
- **Material Design 3**: Modern, responsive UI with dynamic theming
- **Jetpack Compose**: Declarative UI with smooth animations
- **Responsive Grid Layout**: Adaptive channel grid (2 columns)
- **Category Filter Chips**: Horizontal scrolling category selection
- **Loading States**: Skeleton screens and progress indicators
- **Error Handling**: User-friendly error messages with retry options
### TV Support
- **Android TV Compatible**: Leanback launcher support
- **D-Pad Navigation**: Full remote control support
- **TV-Optimized UI**: Large, focusable UI elements
## Screenshots
> **Note**: Add your screenshots to the `screenshots/` directory and update the paths below.
| Channels List | Player | Categories |
|--------------|--------|------------|
| ![Channels](screenshots/channels.png) | ![Player](screenshots/player.png) | ![Categories](screenshots/categories.png) |
| Search | Favorites | Settings |
|--------|-----------|----------|
| ![Search](screenshots/search.png) | ![Favorites](screenshots/favorites.png) | ![Settings](screenshots/settings.png) |
## Prerequisites
Before building the project, ensure you have the following installed:
### Required
- **Android Studio Hedgehog (2023.1.1)** or later
- **JDK 17** or later
- **Android SDK** with the following:
- SDK Platform API 34 (Android 14)
- Build-Tools 34.0.0
- Android SDK Command-line Tools
### Optional
- **Git** for version control
- **Android Device** or **Emulator** running Android 7.0 (API 24) or higher
## Installation
### 1. Clone the Repository
```bash
git clone https://github.com/yourusername/iptv-app.git
cd iptv-app
```
### 2. Open in Android Studio
1. Launch Android Studio
2. Select "Open an existing Android Studio project"
3. Navigate to the cloned directory and click "OK"
4. Wait for Gradle sync to complete
### 3. Build the Project
```bash
# Build debug APK
./gradlew assembleDebug
# Build release APK (requires signing configuration)
./gradlew assembleRelease
```
### 4. Run on Device
```bash
# Connect your Android device or start an emulator
# Run the app
./gradlew installDebug
```
## Configuration
### Changing the M3U Playlist URL
The default M3U URL can be configured in the following locations:
#### Option 1: Build Configuration (Recommended)
Edit `app/build.gradle.kts` and add a build config field:
```kotlin
android {
defaultConfig {
buildConfigField("String", "DEFAULT_M3U_URL", "\"https://your-playlist-url.com/playlist.m3u\"")
}
}
```
Then access it in code:
```kotlin
val m3uUrl = BuildConfig.DEFAULT_M3U_URL
```
#### Option 2: Constants File
Create or edit `app/src/main/java/com/iptv/app/Constants.kt`:
```kotlin
package com.iptv.app
object Constants {
const val DEFAULT_M3U_URL = "https://your-playlist-url.com/playlist.m3u"
// Optional: Multiple playlist support
val PLAYLISTS = mapOf(
"Default" to "https://example.com/playlist1.m3u",
"Sports" to "https://example.com/sports.m3u",
"News" to "https://example.com/news.m3u"
)
}
```
#### Option 3: Settings UI (User-Configurable)
The app supports runtime playlist URL changes through the Settings screen. Users can:
1. Open Settings
2. Tap "Playlist URL"
3. Enter a new M3U/M3U8 URL
4. Tap "Save" to apply changes
### Supported Playlist Formats
The app supports standard M3U/M3U8 playlist formats:
```m3u
#EXTM3U
#EXTINF:-1 tvg-id="channel1" tvg-logo="http://logo.png" group-title="News",CNN
http://stream-url.com/cnn.m3u8
#EXTINF:-1 tvg-id="channel2" tvg-logo="http://logo.png" group-title="Sports",ESPN
http://stream-url.com/espn.m3u8
```
**Supported Attributes:**
- `tvg-id`: Channel identifier
- `tvg-logo`: Channel logo URL
- `group-title`: Category/group name
- `tvg-language`: Channel language
- `tvg-country`: Channel country
## Architecture Overview
### MVVM Architecture
The app follows the Model-View-ViewModel (MVVM) architecture pattern:
```
UI Layer (Compose Screens)
|
v
ViewModel Layer (State Management)
|
v
Repository Layer (Data Operations)
|
v
Data Layer (Models, Parsers, Network)
```
### Repository Pattern
The `ChannelRepository` acts as a single source of truth for channel data:
- **Data Fetching**: Fetches from network with Retrofit/OkHttp
- **Caching**: Local cache with 24-hour expiration
- **Favorites**: Persistent storage with SharedPreferences
- **Search**: Debounced search with Flow operators
- **Filtering**: Category-based filtering
### Media3 ExoPlayer Integration
The `PlayerManager` class provides:
- **Player Lifecycle**: Proper creation and disposal
- **Audio Focus**: System audio focus handling
- **Track Selection**: Quality and audio track switching
- **State Management**: Playback state observation
## Project Structure
```
IPTVApp/
├── app/
│ ├── src/main/java/com/iptv/app/
│ │ ├── data/
│ │ │ ├── model/
│ │ │ │ ├── Channel.kt # Channel data class
│ │ │ │ └── Category.kt # Category data class
│ │ │ └── repository/
│ │ │ └── ChannelRepository.kt # Data repository
│ │ ├── ui/
│ │ │ ├── components/ # Reusable UI components
│ │ │ │ ├── ChannelCard.kt
│ │ │ │ ├── CategoryChip.kt
│ │ │ │ ├── VideoPlayer.kt
│ │ │ │ └── PlayerControls.kt
│ │ │ ├── screens/ # Screen composables
│ │ │ │ ├── ChannelsScreen.kt
│ │ │ │ └── PlayerScreen.kt
│ │ │ ├── theme/ # Material 3 theme
│ │ │ │ ├── Color.kt
│ │ │ │ ├── Type.kt
│ │ │ │ └── Theme.kt
│ │ │ └── viewmodel/ # ViewModels
│ │ │ ├── ChannelsViewModel.kt
│ │ │ └── PlayerViewModel.kt
│ │ └── utils/
│ │ ├── M3UParser.kt # M3U playlist parser
│ │ └── PlayerManager.kt # ExoPlayer wrapper
│ ├── src/main/res/
│ │ ├── values/
│ │ │ ├── strings.xml # App strings
│ │ │ ├── colors.xml # Color resources
│ │ │ └── themes.xml # Theme resources
│ │ └── xml/
│ │ └── network_security_config.xml
│ └── build.gradle.kts # App-level build config
├── build.gradle.kts # Project-level build config
├── settings.gradle.kts # Project settings
└── gradle.properties # Gradle properties
```
## Dependencies
### Core Android
| Dependency | Version | Purpose |
|------------|---------|---------|
| `core-ktx` | 1.12.0 | Kotlin extensions |
| `lifecycle-runtime-ktx` | 2.6.2 | Lifecycle awareness |
| `activity-compose` | 1.8.1 | Compose activity |
### Jetpack Compose
| Dependency | Version | Purpose |
|------------|---------|---------|
| `compose-bom` | 2023.10.01 | Bill of Materials |
| `material3` | - | Material Design 3 |
| `material-icons-extended` | - | Extended icons |
| `lifecycle-viewmodel-compose` | 2.6.2 | ViewModel integration |
| `navigation-compose` | 2.7.5 | Navigation |
### Media Playback
| Dependency | Version | Purpose |
|------------|---------|---------|
| `media3-exoplayer` | 1.2.0 | Core player |
| `media3-exoplayer-hls` | 1.2.0 | HLS streaming |
| `media3-exoplayer-dash` | 1.2.0 | DASH streaming |
| `media3-ui` | 1.2.0 | Player UI |
| `media3-session` | 1.2.0 | Media session |
### Networking
| Dependency | Version | Purpose |
|------------|---------|---------|
| `retrofit` | 2.9.0 | HTTP client |
| `okhttp` | 4.12.0 | HTTP engine |
| `logging-interceptor` | 4.12.0 | Request logging |
### Image Loading
| Dependency | Version | Purpose |
|------------|---------|---------|
| `coil-compose` | 2.5.0 | Image loading |
### Coroutines
| Dependency | Version | Purpose |
|------------|---------|---------|
| `kotlinx-coroutines-android` | 1.7.3 | Async operations |
### JSON Parsing
| Dependency | Version | Purpose |
|------------|---------|---------|
| `gson` | 2.10.1 | JSON serialization |
### Testing
| Dependency | Version | Purpose |
|------------|---------|---------|
| `junit` | 4.13.2 | Unit testing |
| `espresso-core` | 3.5.1 | UI testing |
| `compose-ui-test-junit4` | - | Compose testing |
## Building the APK
### Debug APK
```bash
# Build debug APK
./gradlew assembleDebug
# Output location:
# app/build/outputs/apk/debug/app-debug.apk
```
### Release APK
1. **Create a signing keystore** (if not exists):
```bash
keytool -genkey -v -keystore iptv-release.keystore -alias iptv -keyalg RSA -keysize 2048 -validity 10000
```
2. **Configure signing** in `app/build.gradle.kts`:
```kotlin
android {
signingConfigs {
create("release") {
storeFile = file("iptv-release.keystore")
storePassword = System.getenv("STORE_PASSWORD") ?: "your-password"
keyAlias = "iptv"
keyPassword = System.getenv("KEY_PASSWORD") ?: "your-password"
}
}
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("release")
}
}
}
```
3. **Build release APK**:
```bash
# Build release APK
./gradlew assembleRelease
# Output location:
# app/build/outputs/apk/release/app-release.apk
```
### App Bundle (Google Play)
```bash
# Build AAB for Google Play
./gradlew bundleRelease
# Output location:
# app/build/outputs/bundle/release/app-release.aab
```
## Installing on Android Device
### Method 1: Android Studio
1. Connect your Android device via USB
2. Enable USB debugging in Developer Options
3. Click "Run" (green play button) in Android Studio
4. Select your device from the deployment target dialog
### Method 2: ADB (Android Debug Bridge)
```bash
# Install debug APK
adb install app/build/outputs/apk/debug/app-debug.apk
# Install release APK
adb install app/build/outputs/apk/release/app-release.apk
# Install with replacement (if already installed)
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
### Method 3: Direct Download
1. Transfer the APK file to your device
2. Open a file manager on your device
3. Navigate to the APK file location
4. Tap the APK to install
5. Allow installation from unknown sources if prompted
### Method 4: Wireless ADB
```bash
# Connect to device over WiFi
adb tcpip 5555
adb connect <device-ip-address>:5555
# Install APK
adb install app/build/outputs/apk/debug/app-debug.apk
```
## Troubleshooting
### Build Issues
#### Gradle Sync Failed
```
Solution: File -> Invalidate Caches / Restart -> Invalidate and Restart
```
#### Out of Memory Error
Add to `gradle.properties`:
```properties
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
org.gradle.caching=true
```
#### Kotlin Version Mismatch
Ensure Kotlin version matches in `build.gradle.kts`:
```kotlin
plugins {
id("org.jetbrains.kotlin.android") version "1.9.20"
}
```
### Runtime Issues
#### App Crashes on Launch
- Check that `INTERNET` permission is in `AndroidManifest.xml`
- Verify minimum SDK version (API 24+)
- Check for ProGuard obfuscation issues
#### Channels Not Loading
- Verify the M3U URL is accessible
- Check network connectivity
- Review logcat for parsing errors: `adb logcat | grep M3UParser`
#### Video Not Playing
- Ensure stream URL is valid and accessible
- Check if stream format is supported (HLS, DASH, Progressive)
- Verify codec support on device
- Check logcat for ExoPlayer errors
#### Audio Issues
- Check audio focus is being requested properly
- Verify audio track selection in PlayerManager
- Test with different audio formats
### Streaming Issues
#### Buffering Problems
```kotlin
// Increase buffer size in PlayerManager
val player = ExoPlayer.Builder(context)
.setLoadControl(
DefaultLoadControl.Builder()
.setBufferDurationsMs(
5000, // minBufferMs
50000, // maxBufferMs
1000, // bufferForPlaybackMs
5000 // bufferForPlaybackAfterRebufferMs
)
.build()
)
.build()
```
#### SSL/Certificate Errors
Update `network_security_config.xml`:
```xml
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
```
### Development Tips
#### Enable Debug Logging
```kotlin
// In PlayerManager
exoPlayer.addAnalyticsListener(EventLogger())
```
#### View Compose Layout Bounds
Enable in Developer Options:
```
Settings -> Developer Options -> Show layout bounds
```
#### Profile Performance
Use Android Studio Profiler:
```
View -> Tool Windows -> Profiler
```
## License
```
Copyright 2024 IPTV Player
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
## Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## Acknowledgments
- [ExoPlayer](https://github.com/google/ExoPlayer) - Media player library
- [Jetpack Compose](https://developer.android.com/jetpack/compose) - UI toolkit
- [Material Design 3](https://m3.material.io/) - Design system
- [IPTV Org](https://github.com/iptv-org) - Public IPTV playlists
## Support
For issues, questions, or feature requests, please open an issue on GitHub.
---
**Disclaimer**: This application is for educational purposes. Users are responsible for complying with local laws and regulations regarding IPTV streaming. The developers do not provide any IPTV content or playlists.