EasyPlex PlayerVersion 1.0 handbook Professional servicesServices

Add-on for EasyPlex · 1.0

Play EasyPlex
in your own player.

EasyPlex Player is a native Android video player for phones, tablets and Android TV. Your EasyPlex users install it once; when they press play in the EasyPlex app, the movie, episode or channel opens in it. It is also a complete player on its own: device videos, network streams and M3U playlists.

Release-ready workflow
  1. 01
    Reskin the projectName · package · logo · colors
  2. 02
    Activate in the panelEasyPlex Player purchase code
  3. 03
    Publish the playerAndroid 7.0+ · Android TV
  4. 04
    Play from EasyPlex“EasyPlex External Player”

What's inside

Features

Built on Google's AndroidX Media3 (ExoPlayer), with the EasyPlex app's player design so a video looks the same in both apps.

01

EasyPlex player design

The same controls, panels and dialogs as the EasyPlex app's main player: volume and brightness sliders, scale modes, two-step lock, servers, subtitle style, up-next card and error screen.

02

Plays from the EasyPlex app

Movies, episodes, anime and live channels arrive with their title, artwork, servers, subtitles, headers and DRM. Supported hosts, embeds and YouTube servers play like in the app.

03

Android TV

A TV player with one row of remote-friendly controls, a visible focus everywhere, TV poster cards and a home-screen banner. The EasyPlex Android TV app hands videos to it too.

04

Every format

MP4, MKV, WebM, HLS, DASH, SmoothStreaming and RTSP. FFmpeg audio decoders for AC3, E-AC3, DTS and TrueHD. Widevine, PlayReady and ClearKey DRM.

05

Panel-driven

Ads (banner, interstitial, VAST/VMAP) and security options (flag secure, root, VPN, sniffer apps) follow your EasyPlex panel, like the app. Premium users see no ads.

06

A full player app

Device videos by folder, a Stream tab for any link, M3U/IPTV playlists, history and favorites, subtitles (files, OpenSubtitles), Chromecast, picture-in-picture and background audio.

EasyPlex Player phone player controls
Phone player. The EasyPlex app's player design, always in landscape.
EasyPlex Player options panel
Options panel. Servers, subtitles, audio, speed, Cast, picture-in-picture, sleep timer, repeat and background audio.
EasyPlex Player playlist screen
Playlists. M3U/M3U8 playlists with groups and search.
EasyPlex Player Android TV controls
Android TV player. Play/pause in the centre, the same number of actions on each side.
EasyPlex Player Android TV stream screen
Android TV app. Every screen works with the remote.

System map

How the pieces connect

The player is a separate app with its own purchase code. It never talks to the license server directly: your EasyPlex panel does that for it.

Intent actioncom.easyplexplayer.action.PLAY_STREAM
Default packagecom.easyplexplayer
Panel license routeapi/standalone-player/license

Before you begin

Requirements

ItemVersion / note
EasyPlex2.4 or newer: the admin panel and the Android app (and the Android TV app, if you use it) with standalone player support. Sold separately. The panel must be online over HTTPS: the player gets its license from it.
EasyPlex Player purchase codeYour Envato purchase code for this item. Your EasyPlex purchase code does not activate the player.
Android StudioA recent stable release that supports Android Gradle Plugin 9.2 (it bundles JDK 21).
Android SDKPlatform 37 (compile), target 36. Android Studio installs it on first sync.
GradleWrapper included (9.7.1). No separate install needed.
DevicesAndroid 7.0 (API 24) or newer phones and tablets; Android TV / Google TV.

Android Studio

Open and run the project

  1. Open the folder

    Unzip the package and open the Source/EasyPlexPlayer folder in Android Studio (File → Open). Let Gradle sync finish; accept if it asks to install SDK Platform 37.

  2. Run it

    Select a device and press Run. Without activation the player screen shows Player not activated: the home screens work, playback needs a license (see Activation).

    Terminal
    gradlew.bat :app:assembleDebug        # Windows
    ./gradlew :app:assembleDebug          # macOS / Linux
  3. Optional: develop without activation

    While you customize the player, debug builds can skip the license check. Add this line to local.properties (that file stays on your computer and is never part of a release):

    local.properties
    player.devNoLicense=true

    Release builds always check the license, whatever this file says.

Branding

Name, package, logo and colors

WhatWhere
App name, AdMob App IDapp/src/main/res/values/config.xml
Package nameapplicationId in app/build.gradle
Colorsapp/src/main/res/values/colors.xml (brand_accent, bg_app, …)
Launcher icon (also the splash logo)app/src/main/res/drawable/ic_launcher_foreground.xml, or Android Studio New → Image Asset
Android TV bannerapp/src/main/res/drawable-xhdpi/tv_banner.png (320 × 180)
Logo sources, store graphicsbranding/ (SVG + PNG, Google Play icon and feature graphic)
Player, subtitles, Cast, ads, linksapp/src/main/assets/app_config.json
Texts and translationsapp/src/main/res/values*/strings.xml

Package name

Change only the applicationId; the Java packages (com.easyplex.player) can stay. Then enter the same value in your EasyPlex panel (Standalone player package name) or in the EasyPlex app's STANDALONE_PLAYER_PACKAGE_NAME. One purchase code activates one package name.

app/build.gradle
defaultConfig {
    applicationId "com.yourbrand.player"
    versionCode 1
    versionName "1.0.0"
}

Colors

brand_accent recolors buttons, progress bars, the seek bar, selected tabs and the TV focus ring across the app.

res/values/colors.xml
<color name="brand_accent">#BDAE8F</color>
<color name="brand_on_accent">#111111</color>
<color name="bg_app">#0B0B0B</color>
<color name="bg_card">#171818</color>
EasyPlex Player logo
Included logo. The EasyPlex mark with its orange chevron turned into a play button. Replace it with your own brand.

License · purchase code

Activate the player

The player plays only with a license for its package name. The license comes from your EasyPlex panel, which checks your EasyPlex Player purchase code with the license server. The purchase code never reaches the apps.

  1. Enter the code in the panel

    In your EasyPlex panel, open Settings → Player Settings → Playback:

    FieldValue
    Enable standalone EasyPlex PlayerOn. The apps then offer “EasyPlex External Player”.
    Standalone player package nameYour player's applicationId, exactly as published.
    EasyPlex Player purchase codeYour Envato purchase code for this item. After saving, the field shows “Configured”.

    Select Save Settings.

  2. Or set them in the EasyPlex Android project

    Instead of the panel fields, you can build them into the EasyPlex app. The panel fields take priority; you need only one of the two.

    EasyPlex app · gradle.properties
    PLAYER_PURCHASE_KEY=your-easyplex-player-purchase-code

    The package name is STANDALONE_PLAYER_PACKAGE_NAME in util/Constants.java. The code is obfuscated into the app at build time and handed to the player with each video. The panel checks it and saves it the first time.

  3. Open a video once

    The player learns your panel's address from the first video the EasyPlex app sends. To activate a player that is opened on its own first, set backend.api_base_url and backend.api_key in app_config.json.

app/src/main/assets/app_config.json

Configuration

Everything not needed at build time lives in this file. Every key is optional: a missing value falls back to the default shown. Users can change player options in the in-app Settings.

app

KeyDefaultDescription
privacy_policy_urlexample.comShown in Settings; empty hides it. Required by Google Play.
terms_urlexample.comTerms of use link (empty hides it).
support_email[email protected]“Contact support” opens an email to this address.
share_textPlay Store linkText shared by “Share the app”. Update it with your package name.
show_sample_playlisttrueAdds the bundled “Sample streams” playlist on first launch.

player

KeyDefaultDescription
seek_step_seconds10Rewind/forward buttons and double-tap step.
default_speed1.0Playback speed at start.
resume_playbacktrueContinue where the user stopped.
auto_play_nexttruePlay the next item of a folder or playlist.
auto_play_countdown_seconds8“Up next” countdown; 0 plays the next item immediately.
auto_pip_on_leavetruePicture-in-picture when the user leaves during playback.
background_audiofalseKeep audio playing in the background (with notification).
gestures_enabled, double_tap_seektrueSwipe for brightness, volume and seeking; double-tap to seek.
ffmpeg_audio_decoderstrueFFmpeg decoders for AC3, E-AC3, DTS, TrueHD.
prefer_software_decodersfalseTry software video decoders first.
default_resize_modefitfit, fill, zoom, 16_9 or 4_3.
default_user_agentEasyPlexPlayer/1.0…User-Agent for network requests (a stream can override it).
controller_timeout_seconds4Controls hide after this many seconds (at least 8 on TV).

backend

Your EasyPlex panel. Videos from the EasyPlex app bring these values; set them only so the player can activate and load ads before the first video from the app.

KeyDefaultDescription
enabledtrueUse the panel at all.
api_base_urlemptyThe EasyPlex API, e.g. https://example.com/api/ (the EasyPlex app's SERVER_BASE_URL).
api_keyemptyThe panel's API key (the EasyPlex app's MOBILE_API_KEY).
refresh_minutes60How often the panel settings are fetched again.

subtitles · cast · providers

KeyDefaultDescription
subtitles.opensubtitles_api_keyemptyEnables “Search online” in the subtitle menu.
subtitles.preferred_languageenSubtitle language selected automatically when available.
cast.enabled, cast.receiver_application_idtrue, CC1AD845Cast button; Google's Default Media Receiver (or your own).
providers.api_base_url, hxfile_api_key, app_domainemptySupported-host and embed defaults. Videos from the app bring their own values.
providers.embed_trusted_hosts[]Extra embed providers the embed player may load.

Monetization

Ads

By default ("source": "panel") ads follow your EasyPlex panel with the same rules as the EasyPlex app. Users who are premium or ad-free in the app see no ads.

AdPanel settingsWhen
Home banner“Enable banner bottom”, then the first enabled banner network: AdMob, Unity Ads or AppLovinAbove the bottom navigation.
Interstitial“Enable player interstitial” and the player network (AdMob, AppLovin, Unity Ads or Meta), with its “show every N”When the user closes the player.
Video ads (VAST/VMAP)“Ads player” and the ad of Ads ManagerBefore and during movies and episodes; a single pre-roll on live channels.

Before publishing

  • The AdMob App ID in res/values/config.xml must belong to the same AdMob account as the panel's ad units.
  • The AppLovin SDK key is not stored in the panel: put it in ads.applovin.sdk_key.
  • Wortise, Vungle, IronSource and Appodeal are not bundled; if the panel selects one, that ad is skipped.

Local settings

  • Set "source": "local" and choose ads.network: admob, applovin, unity, facebook or none.
  • Fill that network's IDs and ads.vast.
  • "enabled": false turns all ads off.

Premium stays protected

Videos from the EasyPlex app

The player has no user session, so it can't check premium, credits or ad unlocks itself. The EasyPlex app checks access before it sends a video, and the player then plays only that video.

  • No Episodes panel, Next episode, auto-play, “More like this” or channel list: users pick the next video in the app.
  • Premium-only servers are hidden, except the one the app chose.
  • The video is not saved to the player's History or Favorites; the app's “Continue watching” keeps the position, in both directions.
  • When the video ends, the player closes and the user is back in the app.
  • Servers play like in the app: direct links, supported hosts (the same extractor), embeds (HTTPS, trusted providers only) and YouTube. In the panel's “full embed” mode, embed streams open in the player too.

Videos the user opens in the player itself (Videos, Stream, Playlists, other apps) keep every feature, including queues and auto-play.

EasyPlex app player choice with EasyPlex External Player first
In the EasyPlex app. “EasyPlex External Player” is listed first when the standalone player is enabled. If it isn't installed, the app opens its store page.

From the panel

Security options

The player applies the panel's security options like the EasyPlex app. All are off unless the panel turns them on.

Screen

Flag secure

Screenshots and screen recording are blocked on every screen of the player.

Device

Sniffer apps

With a packet sniffer, proxy or hooking tool installed (HTTP Canary, PCAPdroid, Frida, LSPosed…), the player shows a message and closes.

Device

Root detection

On a rooted device the player shows a message and closes. Root also adds to the VPN risk score.

Network

VPN

VPN blocking, or the risk score (VPN, proxy, private DNS, VPN apps, root, backend IP reputation) with Retry, Continue and Close, like the app.

The checks run when the home screen opens and before each video. The EasyPlex app also sends its copy of these settings with each video, so they apply even when the panel requires signed requests.

Big screen

Android TV

The same app runs on Android TV / Google TV. On a TV the player switches to a TV interface automatically; the files are in res/layout-television/, with the same view ids as the phone layouts.

  • Home-screen banner (res/drawable-xhdpi/tv_banner.png).
  • The selected control always shows a ring or outline in your brand color.
  • OK, Up, Down or Menu show the controls on play/pause; Left/Right seek while the controls are hidden; Back hides the controls, then closes. Media keys work everywhere.
  • Episode, channel and related panels use the EasyPlex TV app's poster cards.
  • The EasyPlex Android TV app hands videos to the player like the phone app.

More features

Chromecast, subtitles and playlists

Chromecast

The Cast button appears when a Cast device is on the same Wi-Fi. Network streams are sent to the TV; files stored on the phone can't be cast. The default receiver doesn't send custom headers, so streams that need them may not play on Cast.

OpenSubtitles

Create an API key at opensubtitles.com (API consumers), put it in subtitles.opensubtitles_api_key, and users get Subtitles → Search online. Free keys have a daily limit.

Orientation

The player screen is always landscape; the other screens follow the device. Change android:screenOrientation of .player.PlayerActivity in AndroidManifest.xml to allow portrait.

M3U playlists

playlist.m3u
#EXTM3U
#EXTINF:-1 tvg-logo="https://example.com/logo.png" group-title="News",My Channel
#EXTVLCOPT:http-user-agent=MyAgent/1.0
#EXTVLCOPT:http-referrer=https://example.com/
https://example.com/live/stream.m3u8

#EXTINF:5400 group-title="Movies",My Movie
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=https://license.example.com/widevine
https://example.com/movie/manifest.mpd

#EXTINF:0,Channel with headers
https://example.com/live.m3u8|User-Agent=MyAgent&Referer=https://example.com/

A duration of -1 or 0 marks a live channel. To ship your own default playlist, replace assets/sample_playlist.m3u and its name in strings.xml (sample_playlist_name).

Integration reference

Open the player from other apps

The EasyPlex app sends com.easyplexplayer.action.PLAY_STREAM to com.easyplexplayer.ui.player.activities.EasyPlexMainPlayer (an alias of the player). Nothing has to change in the EasyPlex app as long as the package names match.

ExtraUsed for
media_url / Intent dataThe stream to play.
media_title, media_serie_name, media_typeTitles and layout: 0 movie, 1 series, anime, streaming (live).
player_payload_jsonThe title with its servers and subtitles; the current episode is found in its seasons.
Headers (android.media.intent.extra.HTTP_HEADERS), media_drm*, subtitle extrasRequest headers, DRM, a subtitle loaded with the video.
easyplex_api_base_url, easyplex_api_keyThe panel the player activates and loads ads from.
easyplex_ads_free, easyplex_settings_json, easyplex_security_jsonNo ads for premium users; the panel's ad and security settings as the app read them.
easyplex_player_purchase_codeThe player's purchase code from the app's build (PLAYER_PURCHASE_KEY), forwarded to the panel.
position, easyplex_progress_package, easyplex_progress_actionStart position, and where the player reports the position back (“Continue watching”).

Any app

Java
Intent i = new Intent("com.easyplexplayer.action.PLAY_STREAM");
i.setPackage("com.easyplexplayer");
i.setDataAndType(Uri.parse("https://example.com/v.m3u8"), "video/*");
i.putExtra("title", "My video");
i.putExtra("subtitles", "https://example.com/en.srt");
i.putExtra("position", 60000L);
startActivity(i);

A whole list: queue_json = {"title","start_index","items":[{"uri","title",…}]}.

MX Player / VLC style

A plain ACTION_VIEW with a video link opens the player. It understands title, headers, position, subs, video_list and from_start, and returns position, duration and end_by like MX Player.

Release

Build and publish

  1. Create your keystore

    In Android Studio choose Build → Generate Signed App Bundle / APK → Android App Bundle and create a keystore. Keep it and its passwords safe: every update needs the same key.

  2. Build the bundle

    Terminal
    gradlew.bat :app:bundleRelease
    # Or an APK:
    gradlew.bat :app:assembleRelease

    Release builds are minified with R8 (rules in app/proguard-rules.pro) and always check the license.

  3. Upload and update

    Upload the .aab to the Google Play Console. Before each update, increase versionCode (and usually versionName) in app/build.gradle.

Store policy

Google Play notes

  • Content rights. The app ships without content. Don't preload playlists with channels or movies you don't own or license.
  • Privacy policy. Required: set privacy_policy_url.
  • Data safety. Declare what your ad network collects. The player stores history, favorites and playlists only on the device.
  • Permissions. Video library access is asked only on the Videos tab. Background audio uses the mediaPlayback foreground service type; declare it when the Console asks.
  • Families. If your app targets children, use only certified ad networks and settings.

Source map

Project structure

app/src/main/
assets/app_config.json            buyer configuration
assets/sample_playlist.m3u        default playlist
java/com/easyplex/player/
  ads/          AdMob, AppLovin, Unity, Meta behind one AdsManager
  cast/         Chromecast options and expanded controls
  config/       AppConfig, RemoteSettings (panel), PlayerLicense
  data/         Room database, M3U parser, playlists, device videos
  player/       PlayerActivity, PlayerFactory, gestures, tracks, service
  player/launch Intent contract (EasyPlex app, MX/VLC style callers)
  player/ui     EasyPlex player dialogs, list panel, scale modes
  security/     panel security options (root, VPN, sniffers)
  ui/           home tabs, settings, splash, TV focus
res/layout/ui_controller_view.xml             phone player controls
res/layout-television/ui_controller_view.xml  TV player controls
res/values/config.xml, colors.xml, strings.xml

Diagnostics

Common problems

SymptomCheck
“Player not activated”Purchase code missing or wrong, package name different from the panel's, or the panel not reached yet (open a video from the EasyPlex app once, or set backend). “Already used by another app”: the code is bound to another package name.
The EasyPlex app opens the store pageThe player isn't installed, or its applicationId differs from the panel's package name.
“EasyPlex External Player” isn't offeredEnable standalone EasyPlex Player is off, or the app hasn't reloaded its settings (restart it).
A stream plays elsewhere but not hereAdd the User-Agent and Referer the server expects (Stream tab → Advanced options).
“Your device can't decode this video”Turn on Settings → Prefer software video decoders.
No sound in some MKV filesKeep FFmpeg audio decoders on (Settings → Decoding).
Ads don't showFilter Logcat by AdsManager: one line shows what will be shown and whether the panel was reached. New ad units can take hours to serve. Never for premium users.
An embed stream stays blackEmbed providers are third-party websites; try another server and test on a real device.
Gradle sync failsUse Android Studio's bundled JDK and install SDK Platform 37.

Open source

Credits and licenses

Full notices are in THIRD_PARTY_NOTICES.md.

LibraryLicense
AndroidX Media3 (ExoPlayer, IMA, Cast, Session, UI), AndroidX, Material ComponentsApache 2.0
OkHttp, Retrofit, Gson, Glide, Timber, RxJava 3, Volley, Fast Android NetworkingApache 2.0 / BSD-style
BouncyCastle (license signature check)MIT-style
jsoup, android-youtube-playerMIT
Mozilla RhinoMPL 2.0
Inter, Cairo, Open Sans fontsSIL OFL 1.1
NextLib (FFmpeg decoders)GPL 3.0 (FFmpeg: LGPL 2.1+)
EasyPlex supported-hosts extractorPart of EasyPlex

The sample playlist uses Blender Foundation open movies (CC BY 3.0) and public test streams, for demonstration only.

Release notes

Version 1.0.0

First release.

  • Standalone player for EasyPlex 2.4: movies, series, anime and live channels from the EasyPlex app and the EasyPlex Android TV app, with all server types and subtitles.
  • Activation with the EasyPlex Player purchase code through the EasyPlex panel (or the app's PLAYER_PURCHASE_KEY), bound to the player's package name.
  • Premium protection: videos from the app play alone, premium-only servers hidden, nothing saved locally, back to the app at the end.
  • “Continue watching” in step with the EasyPlex app in both directions.
  • Ads and security options from the EasyPlex panel.
  • Android TV interface with remote navigation, TV poster cards and home-screen banner.
  • Landscape-only player screen; full player app with device videos, streams, M3U playlists, history, favorites, Chromecast, picture-in-picture and background audio.

Final pass

Launch checklist

Ready when every layer agrees.

Panel. App. Player.
One release.

Back to the beginning ↑
Copied to clipboard