Official Documentation

Nova IPTV Player v1.0.0

Complete guide for buyers and developers · Current release: v1.0.0

Welcome to the official documentation for Nova IPTV Player v1.0.0. This guide is for buyers and developers who want to customize the app, change its identity (name, icon, package), and build a release-ready version.

Disclaimer: This app is only a media player. Users must provide their own content.

What is this app?

Nova IPTV Player is built with Flutter from Google, so it runs on Android (phones and TV) and iOS from a single codebase. The app supports:

Live TV

Channels, movies & series playback

Phone & TV UI

Optimized for mobile and Android TV

Xtream & M3U

Full playlist protocol support

Catch-up & VOD

Replay, VOD and Series ready

Dual Players

Better Player & VLC Player

Quick start
  1. 1Install requirements.
  2. 2Open the project and run: flutter pub get then flutter run.
  3. 3Customize identity: Change Package Name then App Name & Icon.
  4. 4Connect your panel: Panel connection and Control panel requirements.
  5. 5Publish: Build & Release.

Requirements

Everything you need to run, edit, and build the project.

1. General

RequirementVersionNotes
Flutter SDK3.7.0 or newer (< 4.0.0)Defined in pubspec.yaml
DartBundled with FlutterNo separate install
GitRecent versionFor clone and updates

Install Flutter: Download from flutter.dev and add flutter/bin to PATH. Verify with:

flutter doctor -v

2. Android

RequirementNotes
Android Studio or VS Code + FlutterTo edit and run the app
Android SDKcompileSdk 36, minSdk 24, targetSdk 36
JDK 11+For Android build (Java 11 in this project)

The project supports Android TV (Leanback).

3. iOS

RequirementNotes
macOSRequired to build iOS
XcodeLatest from App Store
CocoaPodsWith Xcode or sudo gem install cocoapods
Apple Developer AccountTo upload to App Store
cd ios && pod install && cd ..
flutter run

4. Verify commands

flutter doctor -v
flutter pub get
flutter run
flutter run -d <device_id>

5. Project structure

PathDescription
lib/App code (Dart)
lib/helpers/Constants, translations, helpers
android/Android config
ios/iOS config
assets/images/Images and app icon
pubspec.yamlProject name, version, packages

Buyer First Run

This source package is delivered clean (without build/cache folders) to reduce file size.

On a new machine, run these commands once from project root:

flutter doctor
flutter pub get
flutter run

Excluded folders like build, .dart_tool, Pods, and .gradle do not contain app features. They are regenerated automatically.


Change Package Name

The package name identifies the app uniquely on the store and device. Change it in all of the following places.

Android

File: android/app/build.gradle.kts

android {
    namespace = "com.mybrand.iptv"   // was: nova.iptv.player

    defaultConfig {
        applicationId = "com.mybrand.iptv"   // was: nova.iptv.player
        // ...
    }
}

iOS

From Xcode: Open ios/Runner.xcworkspace → Runner → Signing & Capabilities → change Bundle Identifier from nova.iptv.player to e.g. com.mybrand.iptv.

Or edit manually: In ios/Runner.xcodeproj/project.pbxproj search for PRODUCT_BUNDLE_IDENTIFIER = nova.iptv.player; and replace with the new identifier in all occurrences (Debug, Release, Profile).

Verify

flutter clean
flutter pub get
flutter run

Uninstall the old app from the device if it had the same Application ID / Bundle ID, then install again.


Change App Name & Icon

1. Display name

Android: File android/app/src/main/res/values/strings.xml — change <string name="app_name">Nova IPTV Player</string> to your branded name if needed. The default in the project is Nova IPTV Player.

iOS: File ios/Runner/Info.plist — find CFBundleDisplayName and change the value (e.g. to Nova IPTV Player).

Inside the app: In lib/helpers/constants.dart change const String kAppName = "Nova IPTV Player"; and in lib/helpers/app_translations.dart search for 'app_name': 'Nova IPTV Player' and update for the languages you use.

2. App icon

The app uses flutter_launcher_icons. Place your image in the project (e.g. assets/images/logo app.png) at 1024×1024 PNG.

In pubspec.yaml ensure:

flutter_launcher_icons:
  android: true
  ios: true
  image_path: "assets/images/logo app.png"
  remove_alpha_ios: true

Then run:

flutter pub get
dart run flutter_launcher_icons

Then flutter clean && flutter pub get && flutter run.

WhatFile
App name (Android)android/app/src/main/res/values/strings.xml
App name (iOS)ios/Runner/Info.plist → CFBundleDisplayName
In-app namelib/helpers/constants.dart and app_translations.dart
Icon sourcepubspec.yaml → flutter_launcher_icons.image_path

AdMob — change App ID & ad unit IDs (for buyers)

The app uses Google Mobile Ads (AdMob). Before publishing to Google Play or the App Store, the buyer must replace the seller’s AdMob identifiers with their own from AdMob. There are two kinds of values:

1. Android — App ID

File: android/app/src/main/AndroidManifest.xml

Inside <application>, find com.google.android.gms.ads.APPLICATION_ID and set android:value to your Android App ID from AdMob (starts with ca-app-pub- and contains ~).

<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-YOUR_PUBLISHER_ID~YOUR_ANDROID_APP_ID"/>

2. iOS — App ID

File: ios/Runner/Info.plist

Set GADApplicationIdentifier to your iOS App ID from AdMob (same ca-app-pub-...~... pattern).

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-YOUR_PUBLISHER_ID~YOUR_IOS_APP_ID</string>

3. Banner & interstitial — default ad units (Flutter)

File: lib/repository/locale/admob.dart

This file defines the fallback ad unit IDs when the control panel does not send overrides. Replace the default strings with your AdMob Banner and Interstitial unit IDs for Android and iOS (each is a ca-app-pub-.../... string without ~).

The app may also read these keys from local storage when your panel returns them on activation (see Control panel requirements): banner_ad_unit_android, banner_ad_unit_ios, interstitial_ad_unit_android, interstitial_ad_unit_ios. If present, they override the defaults in code until cleared.

4. Checklist for the buyer

StepWhere
Create apps & ad units in AdMobAdMob console → Apps → Ad units
Android App IDAndroidManifest.xmlAPPLICATION_ID
iOS App IDInfo.plistGADApplicationIdentifier
Banner / interstitial IDslib/repository/locale/admob.dart (and/or panel JSON fields)
Rebuildflutter clean then flutter pub get then release build

Do not ship with another seller’s ca-app-pub- IDs — use your own AdMob account so revenue and policy compliance are yours.


API keys — TMDB & OpenSubtitles (control panel)

The app uses two external APIs for movie/TV ratings (TMDB) and subtitle search inside the video player (OpenSubtitles). You manage both keys from the admin control panel — no app rebuild is required when you change them.

1. Where to set the keys in the panel

  1. Log in to your admin panel (the PHP panel included in this package).
  2. Open Settings from the sidebar.
  3. Scroll to the section API keys (TMDB & OpenSubtitles) (between server settings and AdMob).
  4. Paste your keys and click Save.

The panel stores credentials in the settings database table (tmdb_api_key, opensubtitles_api_key, opensubtitles_username, opensubtitles_password) and sends them to the app on every check-activation response.

2. How to get a TMDB API key

  1. Create a free account at themoviedb.org.
  2. Go to your profile → SettingsAPI.
  3. Request an API key (Developer / personal use).
  4. Copy the API Key (v3 auth) string.
  5. Paste it into TMDB API key in the panel Settings page.

Used for: TMDB ratings on movie/series detail pages when the IPTV server has no rating, and resolving tmdb_id when searching subtitles.

3. How to get OpenSubtitles credentials

  1. Create an account at opensubtitles.com.
  2. Go to your profile → API consumers and create a consumer to get your API key (sent as Api-Key header).
  3. Paste the API key into OpenSubtitles API key in panel Settings.
  4. Also enter your OpenSubtitles username and password in the panel — required for subtitle downloads (JWT login).

Used for: the Search subtitles feature in the player (Movies & Series → Audio & Subtitles).

4. How the app receives the keys

On each activation check (POST /api/check-activation.php), the panel JSON includes:

{
  ...
  "tmdb_api_key": "your_tmdb_key",
  "opensubtitles_api_key": "your_opensubtitles_key",
  "opensubtitles_username": "your_username",
  "opensubtitles_password": "your_password"
}

The Flutter app saves them in local storage (GetStorage) and uses them at runtime. Keys are read from:

lib/repository/locale/panel_api_keys.dart

Fallback constants in lib/core/tmdb_config.dart and lib/core/opensubtitles_config.dart are empty by default — configure keys in the panel.

5. When changes take effect

KeyPanel fieldFeature
TMDBsettings.tmdb_api_keyRatings, TMDB ID lookup
OpenSubtitles API keysettings.opensubtitles_api_keySubtitle search
OpenSubtitles usersettings.opensubtitles_username + passwordSubtitle download (JWT)

Connecting the app to the control panel

Nova IPTV Player can work in two ways: with a control panel (activation, playlist from panel, optional ads/blocking) or standalone (user enters server URL + username + password manually). To use your own panel, you must point the app to your panel URL and ensure your panel implements the required API.

1. Set the panel base URL in the app

The app talks to a control panel over HTTPS. Configure your panel URL in one place. Open:

lib/core/config.dart

Change the following to your panel domain:

const String kActivationPanelBaseUrl = 'https://panel.yourdomain.com/';

Replace with your actual panel host (e.g. https://panel.yourdomain.com/). Use HTTPS and keep the trailing slash. The app will send requests to your panel API endpoints from this base URL (e.g. /api/check-activation.php).

2. How the app uses the panel

3. User flow summary

  1. User opens the app → app calls your panel check-activation with device ID.
  2. Panel returns status (e.g. active/inactive/expired) and optionally domain, username, password, app_name, ads settings, etc.
  3. If active and domain is set, the app uses that URL (and credentials if present) to connect to the IPTV server (player_api.php or M3U).
  4. If not active, user may need to “activate” (panel can provide an activate-device endpoint) or enter server URL + username + password manually.

For full request/response formats and all endpoints, see Control panel requirements below.


Control panel requirements

Your control panel must be hosted over HTTPS and expose the following API endpoints. All are POST (unless noted), with JSON body and JSON response.

1. Check activation

Endpoint: POST /api/check-activation.php

Request body:

{"device_id": "<device_id>"}

device_id is a unique device identifier (Android ID or iOS vendor ID).

Response (200 OK, JSON):

{
  "activated": true,
  "message": "",
  "expiry_date": "2026-12-31",
  "username": "optional_xtream_user",
  "domain": "https://iptv-server.com or https://iptv-server.com/playlist?username=u&password=p",
  "auto_activation_enabled": true,
  "ads_enabled": true,
  "banner_home_only": true,
  "banner_ad_unit_android": "ca-app-pub-xxx",
  "banner_ad_unit_ios": "ca-app-pub-xxx",
  "interstitial_ad_unit_android": "ca-app-pub-xxx",
  "interstitial_ad_unit_ios": "ca-app-pub-xxx",
  "app_name": "Nova IPTV Player",
  "block_vpn": false,
  "piracy_detection_enabled": false,
  "piracy_packages": ["com.screenrecorder.app", "com.videodownloader.app"],
  "piracy_message": "Please remove the app: {app_name}",
  "tmdb_api_key": "your_tmdb_api_key",
  "opensubtitles_api_key": "your_opensubtitles_api_key",
  "opensubtitles_username": "your_username",
  "opensubtitles_password": "your_password"
}

When activated is true, the app expects status in the format used in the app (e.g. “نشط” / “Active”); the app maps from activated: true to active status. domain is required for the app to load the playlist: either the Xtream panel base URL or a full M3U/playlist URL; optionally append ?username=...&password=... for auto-login. All other fields are optional.

2. Activate device

Endpoint: POST /api/activate-device.php

Request body: {"device_id": "<device_id>"}

Response: {"success": true, "already_active": false, "expiry_date": "...", "message": "..."}

Used when the user requests activation (e.g. after entering a code or from the panel).

3. Heartbeat

Endpoint: POST /api/heartbeat.php

Request body: {"device_id": "<device_id>"}

Called periodically when the user is active. Optional; used to track online devices.

4. Save playlist URL

Endpoint: POST /api/save-playlist.php

Request body: {"device_id": "<device_id>", "playlist_url": "<url>"}

Response: {"success": true}

Stores the user’s playlist/domain for that device so the panel can return it on next check-activation.

5. Delete playlist URL

Endpoint: POST /api/delete-playlist.php

Request body: {"device_id": "<device_id>"}

Response: {"success": true}

Clears the stored playlist for that device (e.g. on logout).

6. IPTV server (Xtream Codes / M3U)

The streaming data (live, VOD, series) is not served by your control panel. It is served by the user’s IPTV server. Your panel only returns the domain (and optionally credentials) that point to:

The Xtream server must respond to player_api.php with no action (or with user info) and return user_info (with username, password, status: "Active") and server_info (with server_url or equivalent). This is standard Xtream Codes API behavior.

Summary table

EndpointPurpose
POST /api/check-activation.phpReturn activation status and domain (playlist/XTREAM URL) for the device
POST /api/activate-device.phpActivate a device (e.g. after payment or code)
POST /api/heartbeat.phpOptional heartbeat to track active devices
POST /api/save-playlist.phpSave playlist/domain for the device
POST /api/delete-playlist.phpClear saved playlist for the device

You can use the included admin panel in this source package or your own backend implementation, as long as the required endpoints are available over HTTPS.


Admin Panel Setup (Buyer)

Follow the steps below to install and configure the PHP Admin Panel on your hosting server. No advanced PHP knowledge is required.

Step 1 — Prepare Your Hosting

Step 2 — Upload the Admin Panel Files

Step 3 — Create the Database

Step 4 — Import the Database

Step 5 — Configure Database Connection

Step 6 — Login to the Admin Panel

Step 7 — Connect the Flutter Application

Step 8 — Verify Installation


Admin Panel Guide

After completing the Admin Panel Setup, use this guide to manage your IPTV platform from the included admin panel. Each page below is designed for day-to-day administration.

Dashboard

The Dashboard provides a complete overview of your IPTV platform at a glance. Monitor key metrics, recent activity, and system health from one central page.

Admin panel dashboard overview
  • Total Users
  • Active Devices
  • Active Playlists
  • Recent Activations
  • System Statistics
  • Quick Overview

Account Management

Administrators can create and manage administrator accounts, control access levels, and keep the panel secure.

Admin account management page
  • Create Administrator
  • Edit Administrator
  • Delete Administrator
  • Manage Permissions
  • Secure Login

Playlist Codes

Create and manage playlist activation codes for your customers. Assign M3U or Xtream playlists, set device limits, and configure expiration dates.

Playlist activation codes management
  • Generate Random Codes
  • Create Custom Codes
  • Assign M3U Playlists
  • Assign Xtream Playlists
  • Configure Device Limits
  • Configure Expiration Dates
  • Edit Codes
  • Delete Codes

Manage Activation

View and manage all activated devices. Search activations, monitor device status, and track expiration dates.

Device activation management page
  • View Activation History
  • Search Activations
  • Activate Devices
  • Remove Devices
  • Monitor Device Status
  • Track Expiration

Settings

Configure application behavior, security options, API settings, and system preferences from a single settings page.

Admin panel settings page
  • General Settings
  • Security Settings (VPN block, piracy detection)
  • API Configuration
  • System Preferences

Post-Install Checklist

Before delivering to clients or publishing, confirm all items below.

ItemStatus Check
Panel URLApp points to your domain in kActivationPanelBaseUrl
HTTPSPanel endpoints open with valid SSL certificate
Admin securityDefault password changed; roles reviewed
App identityPackage name, app name, and icon updated
AdMobYour AdMob App IDs in AndroidManifest.xml + Info.plist; your ad units in admob.dart (see AdMob)
API keysTMDB & OpenSubtitles keys set in panel Settings (see API keys)
Settings linkssupport_contact_url and purchase_url configured
Activation testOne test device can activate and receive domain
Playback testLive/VOD/Series load correctly from IPTV source
Piracy detectionBlacklist configured in admin Settings if needed (see Piracy Detection)
Release signingProduction keystore/certificates configured (not debug signing)
Build outputFinal APK/AAB (and IPA if needed) generated successfully

Piracy Detection & Package Blacklist

Nova IPTV Player includes a piracy detection feature that helps protect your streams from screen recording, video downloading, and link-leaking apps. It also works with the license activation server to validate the app package name and reduce unauthorized clones or modified APKs.

What does this feature do?

When enabled from the admin panel, the app scans the device for installed applications whose package names appear on your blacklist. If a blocked app is found, the user cannot pass the login screen and sees a clear message naming the app that must be removed.

This is useful for blocking tools that can record the screen, capture streams, or leak playlist links to other users.

How the package blacklist works

  1. You enable Content piracy detection in the admin panel Settings page.
  2. You add one Android package name per line (for example, com.screenrecorder.app).
  3. When the app calls POST /api/check-activation.php, the panel returns piracy_detection_enabled, piracy_packages, and piracy_message in the JSON response.
  4. On Android, the app compares installed apps against that list. If a match is found, login is blocked until the user uninstalls the flagged app.
  5. The placeholder {app_name} in your custom message is replaced with the detected application name.

How administrators add package names

Open Admin Panel → Settings → Content piracy detection and follow these steps:

  1. Turn on Enable piracy / link-leak apps detection.
  2. In App package names — one per line, enter each package name on its own line. Example:
com.screenrecorder.app
com.videodownloader.app
com.linkleak.tool

To find a package name: on Android, open the app info page in system settings, or use adb shell pm list packages while testing on a device.

Optionally customize the user message, for example: Please remove the app: {app_name}

Click Save. The new list is sent to all devices on the next activation check.

How to remove package names

Edit the same textarea in Settings, delete the line you no longer want to block, and save. Removed package names stop blocking immediately on the next activation check.

To disable the feature entirely, turn off Enable piracy / link-leak apps detection and save.

Block cloned applications

Each buyer should publish the app under a unique package name (see Change Package Name). The Envato license check (see License) sends your app’s package_name to the activation server on launch.

The server registers the package name together with your purchase code and panel URL. If someone repackages the app under a different package name without a valid license, the app will not pass license verification.

Prevent unauthorized APK modifications

Release builds should always be signed with your own production keystore (see Build & Release). Combined with license verification and package-name registration, this reduces the risk of redistributed or tampered APKs being used with your panel.

Do not share your keystore file or key.properties credentials. Keep one official package name per published brand.

How the activation server validates package names

On every app launch, lib/services/seller_license_service.dart reads the installed app’s package name (for example, nova.iptv.player or your custom ID) and sends it to the license API together with:

The server verifies the Envato license and associates the package name with your purchase. If verification fails, the app shows the license error screen and does not continue.

Your control panel separately returns the piracy blacklist through check-activation.php so you can manage blocked apps without rebuilding the Flutter project.

Best practices


License (Envato / CodeCanyon)

To activate your source version inside the app, you only need to fill in your licensing details in one place inside the project.

1) Where do I put my info?

Open this file in the project: lib/services/seller_license_service.dart

2) Set Envato Username

  • Find the line:
  • const String envatoUsername = '...';
  • Enter the Envato Username from the account you used to purchase the source.
How to get Envato username

3) Set Purchase Code

  • Find the line:
  • const String purchaseCode = '...';
  • Enter the Purchase Code (purchase key) from your Envato purchase.

If you don’t know where to find your Purchase Code in Envato: Where Is My Purchase Code?

4) After you update

  • Save the file.
  • Then do Build & Release (see the “Build & Release” section).

Troubleshooting

Common issues and solutions when deploying the admin panel or building the Flutter application. Start with the Flutter SDK section if the project fails during flutter pub get or flutter build.

Common Flutter SDK Build Errors

Use this checklist when setup or build fails on a new machine. Always run commands from the project root (the folder that contains pubspec.yaml).

1. Flutter doctor reports issues

Problem: flutter run or build fails and flutter doctor shows red/yellow warnings.

Cause

Android SDK, cmdline-tools, licenses, Xcode, or CocoaPods are not installed or not accepted.

Solution
flutter doctor -v
  • Install missing components reported by Flutter doctor.
  • Accept Android licenses:
flutter doctor --android-licenses
  • On macOS for iOS: install Xcode, open it once, then run sudo xcode-select --switch /Applications/Xcode.app and pod install inside ios/.

2. Flutter / Dart SDK version mismatch

Problem: pub get failed or messages like requires Flutter SDK version >= x.x.x / version solving failed.

Cause

Installed Flutter is older (or incompatible) with the SDK constraint in pubspec.yaml (this project needs Flutter 3.7.0+ and < 4.0.0).

Solution
flutter --version
flutter channel stable
flutter upgrade
flutter clean
flutter pub get

If it still fails, delete pubspec.lock and .dart_tool/, then run flutter pub get again. Prefer the stable channel.

3. Corrupted cache / stale build artifacts

Problem: Random compile errors after changing packages, icons, or package name.

Cause

Old build/, Gradle, or Dart tool cache.

Solution
flutter clean
flutter pub get
flutter run

Optional deep clean (close IDE first): delete build/, .dart_tool/, and on Android also android/.gradle/, then run flutter pub get.

4. Android Gradle / JDK errors

Problem: Messages such as Gradle build failed, Unsupported class file major version, or JDK / Java toolchain errors.

Cause

Wrong JDK for this project, or Gradle cache corruption. This project expects JDK 11+ (Java 11 used for Android builds).

Solution
  • Install JDK 11 or 17 and point Android Studio / JAVA_HOME to it.
  • In Android Studio: Settings → Build → Gradle → Gradle JDK.
  • Then:
cd android
./gradlew clean
cd ..
flutter clean
flutter pub get
flutter build apk

On Windows use gradlew.bat clean instead of ./gradlew clean.

5. Android SDK / compileSdk / licenses

Problem: Failed to install the following Android SDK packages, missing platforms, or license not accepted.

Cause

Android SDK Platform / Build-Tools not installed for the versions used by the project (compileSdk / targetSdk 36, minSdk 24).

Solution
  • Open Android Studio → SDK Manager → install Android SDK Platform 36 and recommended Build-Tools.
  • Run flutter doctor --android-licenses and accept all.
  • Confirm ANDROID_HOME / ANDROID_SDK_ROOT points to your SDK folder.

6. Package name / namespace / MainActivity path

Problem: Build fails after changing the application ID, or package does not match / MainActivity not found.

Cause

Incomplete package rename: applicationId, namespace, Kotlin package path, or iOS Bundle ID out of sync.

Solution

Follow Change Package Name completely, then:

flutter clean
flutter pub get
flutter run

7. Release signing / keystore errors

Problem: flutter build appbundle or release APK fails with signing / keystore errors.

Cause

Missing key.properties, wrong paths, or keystore password mismatch.

Solution

Configure signing as described in Build & Release. For a quick unsigned debug test use flutter run or flutter build apk --debug.

8. iOS CocoaPods / Xcode build errors

Problem: pod install fails, or Xcode reports missing modules / signing.

Cause

CocoaPods out of date, outdated Pods/, or missing Apple Team / Bundle Identifier.

Solution
sudo gem install cocoapods
cd ios
pod repo update
pod install
cd ..
flutter clean
flutter pub get
flutter build ios

Open ios/Runner.xcworkspace (not .xcodeproj), set Signing & Team, then build again.

9. Plugin / native dependency build failure

Problem: Errors from media plugins (e.g. Better Player / VLC), ads, or other native Android/iOS plugins.

Cause

Incomplete pub get, wrong Flutter version, or minSdk too low on a custom change.

Solution
  • Do not lower minSdk below 24.
  • Keep Flutter on stable 3.7+ as in Requirements.
  • Re-run clean + pub get, then rebuild.

Quick recovery sequence (most setup issues)

If you are unsure which error applies, run this full recovery sequence once:

flutter channel stable
flutter upgrade
flutter doctor -v
flutter doctor --android-licenses
flutter clean
flutter pub get
flutter run

Database Connection Failed

Problem: The admin panel cannot connect to the database.

Cause

Incorrect database credentials.

Solution

Verify database host, database name, username, and password in admin panel/config/database.php.

API Not Working

Problem: The app cannot communicate with the control panel API.

Cause

Incorrect API URL or HTTPS is not configured.

Solution

Verify the API URL in lib/core/config.dart. Enable HTTPS on your domain. Use PHP 8.1 or later.

Activation Failed

Problem: Device activation fails in the app.

Cause

Invalid activation code or device limit reached.

Solution

Verify the activation code in the admin panel. Check the internet connection on the device. Confirm the device limit has not been exceeded for that code.

Permission Denied

Problem: The admin panel returns permission errors or cannot write files.

Cause

Incorrect folder permissions.

Solution

Verify file and folder permissions on the server and ensure PHP has read/write access to the admin panel directories.

Required PHP Extensions

Problem: The admin panel fails to load, returns errors, or API endpoints do not respond correctly.

Cause

Required PHP extensions are disabled on the server. Missing extensions may prevent the Admin Panel from working correctly.

Solution

Ensure the following PHP extensions are enabled on your hosting (PHP 8.1 or later recommended):

  • cURL
  • PDO
  • PDO MySQL
  • OpenSSL
  • JSON
  • MBString
  • FileInfo

Contact your hosting provider or enable them in your PHP configuration (php.ini) if any extension is missing.

Common PHP Configuration Issues

If you encounter memory or timeout errors during installation or large playlist imports, adjust your PHP configuration:

memory_limit = 256M (or higher)

max_execution_time = 300

max_input_time = 300post_max_size = 64M

post_max_size = 64M

upload_max_filesize = 64M

After making changes, restart your web server (Apache/Nginx) if required.

HTTP 500 Internal Server Error

Problem: The Admin Panel displays a 500 Internal Server Error.

Cause

Unsupported PHP version, missing extensions, or server configuration issues.

Solution
  • Use PHP 8.1 or later.
  • Enable all required PHP extensions.
  • Check the web server error logs for more details.
  • Restart Apache or Nginx after updating PHP settings.

SSL Certificate Error

Problem: The application cannot connect to the API over HTTPS.

Cause

Invalid or expired SSL certificate.

Solution
  • Install a valid SSL certificate.
  • Verify the API URL uses HTTPS.
  • Ensure the server certificate is trusted.

Common API Response Errors

HTTP status codes returned by the admin panel API or your hosting server. Each card below lists the problem, typical cause, and recommended fix.

401 Unauthorized

Problem: The API rejects the request because authentication is missing or invalid.

Cause

Wrong admin credentials, expired session, or protected endpoint called without authorization.

Solution

Log in to the admin panel again. For API calls from the app, confirm the endpoint is public (activation routes do not require admin login). Check server auth rules (for example, .htaccess or HTTP Basic Auth) that may block requests.

403 Forbidden

Problem: The server understood the request but refuses to allow it.

Cause

File permissions, mod_security rules, IP blocking, or WAF (Web Application Firewall) restrictions.

Solution

Verify folder permissions on admin panel/api/. Ask your host to whitelist your domain or disable false-positive firewall rules. Ensure PHP can execute files in the API directory.

404 Not Found

Problem: The requested API URL does not exist on the server.

Cause

Incorrect kActivationPanelBaseUrl, missing uploaded files, or wrong subfolder path.

Solution

Confirm the panel files are uploaded completely. Test https://panel.yourdomain.com/api/check-activation.php in a browser or API client. Match the base URL in lib/core/config.dart exactly (HTTPS, with trailing slash).

405 Method Not Allowed

Problem: The HTTP method used is not supported for that endpoint.

Cause

Activation endpoints expect POST with a JSON body. A GET request or wrong method triggers 405.

Solution

Ensure the app and any custom integrations send POST to endpoints such as /api/check-activation.php. Do not call these URLs from a browser address bar (which uses GET).

408 Request Timeout

Problem: The server did not receive a complete request in time.

Cause

Slow hosting, high server load, or unstable network on the device.

Solution

Retry on a stable connection. Upgrade hosting or increase PHP / web server timeout limits. Check that MySQL is running and responsive.

422 Unprocessable Entity

Problem: The server received the request but the data format is invalid.

Cause

Missing device_id, malformed JSON, or empty required fields.

Solution

Send valid JSON, for example {"device_id": "your_device_id"}. Ensure Content-Type: application/json is set. Check API logs for validation errors.

429 Too Many Requests

Problem: Too many requests were sent in a short period.

Cause

Rate limiting on the host, CDN, or security plugin.

Solution

Wait and retry. Reduce rapid repeated calls during testing. Contact your host to adjust rate limits for your panel domain.

500 Internal Server Error

Problem: The server encountered an unexpected error while processing the request.

Cause

PHP errors, database connection failure, or missing PHP extensions.

Solution

Check admin panel/config/database.php credentials. Enable required PHP extensions (cURL, PDO, PDO MySQL, OpenSSL, JSON, MBString, FileInfo). Review server error logs in cPanel or hosting panel.

502 Bad Gateway

Problem: A gateway or proxy server received an invalid response from the upstream server.

Cause

PHP-FPM crash, overloaded server, or misconfigured reverse proxy (Nginx → Apache).

Solution

Restart PHP-FPM or the web server. Check hosting status. If you use Cloudflare or a CDN, verify origin server health.

503 Service Unavailable

Problem: The server is temporarily unable to handle the request.

Cause

Maintenance mode, database downtime, or resource limits exceeded.

Solution

Confirm MySQL is online. Disable maintenance plugins. Upgrade hosting plan if traffic exceeds limits. Retry after a few minutes.

Flutter Version Constraints — Extra Notes

For the full checklist (doctor, Gradle, JDK, licenses, CocoaPods, signing), see Common Flutter SDK Build Errors above. Typical version-constraint messages include:

Best practices: use the Stable channel, keep Flutter updated, avoid mixing dependency sets from different Flutter releases, and read package compatibility notes before flutter pub upgrade.


FAQ

Frequently asked questions about this package.

Does this package include IPTV content?

No. This application is only a media player and does not include IPTV channels, movies, series, or subscriptions.

Does it include hosting?

No. Hosting, VPS, domains, and servers are not included.

Can I customize the application?

Yes. The full source code is included and can be customized.

Can I publish it under my own brand?

Yes. You can change the application name, package name, logo, colors, and publish it under your own brand.

Does it support Android TV?

Yes. The application is fully optimized for Android TV and Android Mobile.

Does it support M3U and Xtream Codes?

Yes. Both M3U playlists and Xtream Codes API are fully supported.


Application Screens

Preview of the main application screens included in this package.

Login

Application login screen

Secure login screen supporting Username/Password and Activation Code.

Home

Application home screen

Modern IPTV home screen with Live TV, Movies and Series.

Player

Application video player screen

Professional video player with Better Player (ExoPlayer-based) & VLC Player support.

Settings

Application settings screen

Application settings including language, theme, player selection and parental control.


Build & Release

How to create a release build for Android (APK / AAB) and iOS. Nova IPTV Player current release: v1.0.0 (version: 1.0.0+1 in pubspec.yaml).

1. Update version

In pubspec.yaml, set version: 1.0.0+1. The part before + is the user-facing version (1.0.0); the number after + is the build number (1). Increase both when you publish an update (for example, 1.0.1+2 for the next patch).

2. Android production signing

Google Play and production distribution require a signed release build. Debug signing is only for local testing. Follow every step below before uploading to a store.

2.1 What is a keystore?

A keystore is a secure file that stores your app’s signing key (certificate). Android uses it to prove that updates come from the same publisher. If you lose the keystore or its passwords, you cannot publish updates to the same Play Store listing — keep backups in a safe place.

2.2 Generate a keystore

Run this command from your project root (or any folder where you want to store the file). keytool ships with the JDK:

keytool -genkeypair -v \
-keystore upload-keystore.jks \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-alias upload

You will be prompted for a keystore password, key password, and certificate details (name, organization, country). Remember these values — you need them in key.properties.

ParameterMeaning
-genkeypairCreates a new public/private key pair for signing.
-vVerbose output — shows what the tool is doing.
-keystore upload-keystore.jksOutput file name. .jks is the Java Keystore format.
-keyalg RSAEncryption algorithm for the key (RSA is standard for Android).
-keysize 2048Key strength in bits. 2048 is the recommended minimum.
-validity 10000Certificate validity in days (~27 years). Must cover the app’s lifetime.
-alias uploadName of the key entry inside the keystore. Use upload for Play App Signing upload key.

Move upload-keystore.jks into the android/ folder (same level as app/). Never commit this file to Git.

2.3 Create android/key.properties

Create a new file at android/key.properties (not inside app/). Add your credentials:

storePassword=YOUR_KEYSTORE_PASSWORD
keyPassword=YOUR_KEY_PASSWORD
keyAlias=upload
storeFile=upload-keystore.jks

storeFile is relative to the android/ folder. Add key.properties and *.jks to .gitignore so they are never uploaded to a repository.

2.4 Configure signingConfigs in android/app/build.gradle.kts

This project uses Kotlin DSL (build.gradle.kts). The file already loads key.properties when it exists. Confirm these sections are present:

val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(keystorePropertiesFile.inputStream())
}

android {
    signingConfigs {
        create("release") {
            if (keystoreProperties["storeFile"] != null) {
                storeFile = file(keystoreProperties["storeFile"] as String)
                storePassword = keystoreProperties["storePassword"] as String
                keyAlias = keystoreProperties["keyAlias"] as String
                keyPassword = keystoreProperties["keyPassword"] as String
            }
        }
    }
    buildTypes {
        release {
            signingConfig = if (keystorePropertiesFile.exists()) {
                signingConfigs.getByName("release")
            } else {
                signingConfigs.getByName("debug")  // local testing only
            }
        }
    }
}

If you use Groovy (build.gradle), the same logic applies: load properties before android { }, define signingConfigs.release, and set buildTypes.release.signingConfig signingConfigs.release.

2.5 Release signing explained

When key.properties exists, Flutter’s release build is signed with your production key. Without it, the project falls back to debug signing — acceptable for testing on your own device, but not accepted by Google Play for production uploads.

After configuring signing, always run flutter clean before the first signed release build.

2.6 Build a signed APK

An APK can be installed directly on devices (sideloading, testers, or stores that accept APK).

flutter clean
flutter pub get
flutter build apk --release

Output: build/app/outputs/flutter-apk/app-release.apk

Verify signing before distribution:

keytool -printcert -jarfile build/app/outputs/flutter-apk/app-release.apk

2.7 Build a signed AAB

An AAB (Android App Bundle) is the required format for Google Play. Google generates optimized APKs per device from your bundle.

flutter build appbundle --release

Output: build/app/outputs/bundle/release/app-release.aab — upload this file in Google Play Console.

2.8 When to upload APK vs AAB

FormatUse when
AABPublishing or updating on Google Play (required for new apps).
APKDirect install on test devices, third-party stores that require APK, or internal QA sideloading.

For Play Store production, always prefer AAB. Keep your keystore backed up — you need the same key for all future updates.

3. iOS production signing & App Store

Requirements: a Mac, an active Apple Developer Account (paid membership), and Xcode. Follow these steps in order.

3.1 Apple Developer Account

Enroll at developer.apple.com/programs. You need this to create certificates, register an App ID, and submit to the App Store. Sign in with the same Apple ID in Xcode (Xcode → Settings → Accounts).

3.2 Certificates

A certificate proves you are an authorized Apple developer. For App Store distribution you need an Apple Distribution certificate. With automatic signing enabled, Xcode creates and manages certificates for you. You can also create them manually in the Apple Developer portal under Certificates, Identifiers & Profiles.

3.3 App ID

An App ID uniquely identifies your app on Apple’s systems. It must match your Bundle Identifier (for example, com.mybrand.iptv). Register it in the Developer portal or let Xcode create it when you enable automatic signing.

3.4 Bundle Identifier

In Xcode, select the Runner target → General → set Bundle Identifier to your unique ID. It must match the value you set in Change Package Name (default in source: nova.iptv.player). Each published app needs a globally unique bundle ID.

3.5 Provisioning Profiles

A provisioning profile links your App ID, distribution certificate, and (for development) allowed test devices. For App Store release you need an App Store distribution profile. Xcode downloads and installs the correct profile when automatic signing is on.

3.6 Automatic signing (recommended)

Open ios/Runner.xcworkspaceRunner target → Signing & Capabilities → enable Automatically manage signing → choose your Team. Xcode handles certificates and profiles. Confirm there are no red signing errors before archiving.

3.7 Manual signing (brief)

Disable automatic signing and select a specific Provisioning Profile and Signing Certificate manually. Use this only if your organization requires fixed profiles or CI/CD with exported certificates. Most buyers should use automatic signing.

3.8 Archive

Select a real device or Any iOS Device (arm64) as the build destination (not a simulator). Menu: Product → Archive. Wait until Xcode finishes — this creates a release build stored in the Organizer.

3.9 Validate Archive

In the Organizer window, select your archive → Validate App. Xcode checks signing, entitlements, and common App Store issues before upload. Fix any errors shown, then archive again if needed.

3.10 Upload to App Store Connect

Still in Organizer: Distribute AppApp Store Connect → follow the wizard. After upload, open App Store Connect, select your app, attach the build, complete metadata (description, screenshots, privacy), and submit for review.

3.11 Common signing mistakes

Alternative (command line): After signing is configured, run flutter build ipa from the project root — output is in build/ios/ipa/.

4. Command reference

GoalCommand
Clean + build signed APKflutter clean && flutter pub get && flutter build apk --release
Build signed AABflutter build appbundle --release
Build iOS IPAflutter build ipa or Xcode: Product → Archive

5. Optional

Last updated: July 2026 — Nova IPTV Player v1.0.0 Documentation