This document shows three integration patterns for StreaMix SDK, based on the demo applications included in the repository:
Minimal integration with StreaMixLauncher – SimpleDemo
Custom ExoPlayer + SDK‑provided playback screen – CustomExoDemo
Full custom Activity and layout with StreaMixSDK – FullDemo
All examples use only the public SDK API (as exported from the SDK AAR).
1. Minimal Integration – SimpleDemo
Goal: get ad‑enabled playback running as quickly as possible, without dealing with player layout or lifecycle.
Key public APIs used:
com.streamix.sdk.launcher.StreaMixLauncher
Init(Context, partnerId, distributionId, applicationName, exoFactory?, imaFactory?)
playVideo(Context, MediaItem, boolean adsEnabled)
com.streamix.sdk.model.MediaItem
SimpleDemo implements all integration logic in a small helper class (SDKIntegrator) and uses it from MainActivity.
1.1. One‑time SDK initialization
In SimpleDemo, initialization happens once during app startup via a static method:
public static synchronized boolean initializeSDK(Context context) {
try {
StreaMixLauncher.Init(
context,
"1",
"167",
"DemoApp",
null,
null
);
return true;
} catch (Exception e) {
return false;
}
}In MainActivity.onCreate(...) this method is called once, and the result is logged.
1.2. Converting your content model to MediaItem
The demo app has its own model AppMediaItem. A small converter adapts it to the SDK’s MediaItem:
private static MediaItem toSdkMediaItem(AppMediaItem appItem) {
String id = String.valueOf(appItem.id);
String catId = String.valueOf(appItem.categoryid);
Map<String, String> macros = new LinkedHashMap<>();
macros.put("NETWORK_NAME", "Disney");
macros.put("RATING", "16+");
return new MediaItem(
appItem.url,
appItem.title,
id,
catId,
3600,
macros
);
}In your app you typically map your own content model to MediaItem in a similar utility.
1.3. Starting playback via StreaMixLauncher
When the user selects an item in MainActivity, the demo calls:
MediaItem mediaItem = toSdkMediaItem(appMediaItem);
StreaMixLauncher.playVideo(context, mediaItem, true );
What happens next:
the SDK uses its own internal playback screen (Player Activity) with a pre‑configured layout;
the selected content is played with the current ad configuration (VMAP/VAST/distribution‑based);
lifecycle and player views are fully managed by the SDK.
When to use this pattern:
You want the fastest path to an ad‑enabled TV player.
You don’t need a custom player layout or complex control logic.
You are OK with the SDK’s built‑in playback UI.
2. Custom ExoPlayer + SDK‑Provided Playback Screen – CustomExoDemo
Goal: keep the convenience of the SDK’s playback screen while injecting your own ExoPlayer configuration (buffering, track selection, event logging, etc.).
Key public APIs used:
StreaMixLauncher (same as SimpleDemo)
MediaItem
ExoPlayerFactoryAdapter implementation from the app
CustomExoDemo extends the SimpleDemo pattern by providing a custom ExoPlayerFactoryAdapter implementation and passing it into StreaMixLauncher.Init(...).
2.1. Custom ExoPlayerFactoryAdapter
The demo defines ExoPlayerFactory in the app, implementing com.streamix.sdk.ads.factory.ExoPlayerFactoryAdapter:
creates a fully configured ExoPlayer instance;
configures DefaultTrackSelector for seamless adaptation;
configures DefaultLoadControl with tuned buffer durations;
enables decoder fallback via DefaultRenderersFactory;
attaches a Player.Listener for logging events.
Conceptually:
public class ExoPlayerFactory implements ExoPlayerFactoryAdapter {
@Override
public ExoPlayer createExoPlayer(
Context context,
DefaultTrackSelector trackSelector,
DefaultLoadControl loadControl,
DefaultRenderersFactory renderersFactory,
Player.Listener listener
) {
DefaultTrackSelector selector = trackSelector != null
? trackSelector
: createDefaultTrackSelector(context);
DefaultLoadControl lc = loadControl != null
? loadControl
: createDefaultLoadControl();
DefaultRenderersFactory rf = renderersFactory != null
? renderersFactory
: createDefaultRenderersFactory(context);
ExoPlayer player = new ExoPlayer.Builder(context)
.setLoadControl(lc)
.setTrackSelector(selector)
.setRenderersFactory(rf)
.build();
player.addListener(listener != null ? listener : new LoggingListener());
return player;
}
}This gives you full control over how ExoPlayer behaves while the SDK still drives the overall playback flow and ad integration.
2.2. Wiring the custom factory into the SDK
In CustomExoDemo’s SDKIntegrator.initializeSDK(...):
StreaMixLauncher.Init(
context,
"1",
"167",
"DemoApp",
new ExoPlayerFactory(),
null
);Everything else (conversion from AppMediaItem to MediaItem, calling playVideo(...)) stays almost identical to SimpleDemo.
What you gain:
You still use the SDK’s built‑in playback screen and ad orchestration.
You can:
tune buffering and track selection to your needs;
hook into ExoPlayer events for logging/analytics;
reuse your existing ExoPlayer configuration patterns.
When to use this pattern:
You like the SDK’s playback screen but need more control over ExoPlayer behavior.
You already have a tuned ExoPlayer setup and want to plug it into StreaMix.
3. Full Custom Activity and Layout – FullDemo
Goal: build a fully custom player screen and Activity while leveraging StreaMix SDK for playback + ad orchestration.
Key public APIs used:
StreaMixSDK
getInstance(...)
initialize(VideoPlayerConfiguration)
setupPlayer(PlayerView, VideoView, ViewGroup, View, ImageView)
playMedia(MediaItem, PlaybackListener)
release()
StreaMixSDK.DefaultVideoPlayerConfiguration
StreaMixSDK.SDKReadyListener
MediaItem
PlaybackListener
ExoPlayerFactoryAdapter (custom implementation)
FullDemo shows the “maximum control” scenario:
your own PlayerActivity with a custom layout (activity_player_streamix.xml);
your own ExoPlayerFactoryAdapter implementation, coupled with an SDKIntegrator helper;
explicit lifecycle management and custom key‑handling logic.
3.1. Custom layout
activity_player_streamix.xml defines all key components:
PlayerView (@+id/exoPlayerView) – main content video;
VideoView (@+id/adsVideoView) – video ads overlay;
ImageView (@+id/imContentImage) – static/on‑pause ads or background;
View (@+id/fadeOverlayView) – fade/dimming overlay;
ProgressBar (@+id/pbSpinner) – loading spinner.
This mirrors the view types used by StreaMixSDK.setupPlayer(...):
sdk.setupPlayer(
playerView,
adsVideoView,
mainLayout,
fadeOverlay,
adImageView
);
3.2. SDKIntegrator builder and initialization
FullDemo wraps SDK configuration into SDKIntegrator with a builder pattern. The builder allows you to set:
partner/distribution IDs;
application name;
ads configuration source (distribution ID);
SDKReadyListener for asynchronous initialization.
Simplified flow:
sdkIntegrator = SDKIntegrator.builder(context)
.setDistributionID("167")
.setAppName("StreamixDemo")
.setAdsEnabled(true)
.setSDKReadyListener(new StreaMixSDK.SDKReadyListener() {
@Override
public void onSDKReady() {
setupSDKPlayer();
}
@Override
public void onSDKError(String error, boolean fatalError) {
if (!fatalError) {
setupSDKPlayer();
}
}
})
.build();
sdkIntegrator.initializeSDK();Internally initializeSDK() calls:
StreaMixSDK.getInstance(...) with a custom ExoPlayerFactoryAdapter implementation;
builds a DefaultVideoPlayerConfiguration with ad settings;
invokes sdk.initialize(config);
lets SDKReadyListener know when configuration (e.g. via distribution ID) is ready.
3.3. Custom ExoPlayerFactoryAdapter (FullDemo)
Similar to CustomExoDemo, but here the factory also passes the created ExoPlayer instance back into SDKIntegrator so the Activity can:
inspect playback state directly;
implement custom D‑Pad handling (seek, pause/resume);
run its own UI update loop.
Conceptually:
public class ExoPlayerFactory implements ExoPlayerFactoryAdapter {
private final SDKIntegrator integrator;
private ExoPlayer exoPlayer;
public ExoPlayerFactory(SDKIntegrator integrator) {
this.integrator = integrator;
}
@Override
public ExoPlayer createExoPlayer(... ) {
exoPlayer = new ExoPlayer.Builder(context)
.setLoadControl(...)
.setTrackSelector(...)
.setRenderersFactory(...)
.build();
exoPlayer.addListener(new ExoPlayerEventListener());
integrator.setExoPlayer(exoPlayer);
return exoPlayer;
}
public ExoPlayer getExoplayer() { return exoPlayer; }
}
3.4. Wiring views into the SDK when ready
Once the SDK signals that configuration is ready (SDKReadyListener.onSDKReady()), the demo calls setupWithViews(...) on SDKIntegrator:
sdkIntegrator.setupWithViews(
playerView,
adsVideoView,
mainLayout,
fadeOverlay,
adImageView
);Inside setupWithViews(...) the integrator simply calls sdk.setupPlayer(...) with the provided views. At this point:
ad configuration has been loaded from API;
the SDK knows which ad schedule to run;
the SDK is bound to your custom layout.
3.5. Starting playback and handling callbacks
PlayerActivity then:
Extracts the MediaItem from the Intent (it was created earlier from AppMediaItem).
Calls sdkIntegrator.play(mediaItem, this) where this implements PlaybackListener.
Implements PlaybackListener methods to update UI:
show/hide spinner;
react to onPlaybackStarted(), onAdsStarted(), onPlaybackError().
Uses the injected ExoPlayer for direct control (key events, seeking, play/pause toggling).
Conceptual start of playback:
sdkIntegrator.play(currentMediaItem, new PlaybackListener() {
@Override
public void onPlaybackStarted() {
}
@Override
public void onPlaybackPaused() { }
@Override
public void onPlaybackResumed() { }
@Override
public void onPlaybackCompleted() { }
@Override
public void onAdsStarted() { }
@Override
public void onAdsFinished() { }
@Override
public void onPlaybackError(String error) { }
});
3.6. Lifecycle and resource management
The demo’s PlayerActivity is responsible for:
reacting to D‑Pad keys (seek, toggle play/pause);
updating a custom progress UI using the ExoPlayer instance;
releasing SDK resources via sdkIntegrator.release() in onDestroy().
In your own app you can simplify this if you do not need custom key handling or continuous progress updates.
When to use this pattern:
You need full control over the player UI and UX;
You want to tightly integrate the SDK with existing complex TV flows;
You are comfortable managing Activity/ExoPlayer lifecycle explicitly.
4. Summary and Recommendations
StreaMix SDK supports multiple integration depths:
SimpleDemo pattern (StreaMixLauncher only)
Easiest path; no custom Activity required.
Recommended for quick POCs, MVPs and simple TV apps.
CustomExoDemo pattern (custom ExoPlayer + SDK screen)
Use when you want to reuse or fine‑tune your ExoPlayer configuration but still rely on the SDK’s playback screen.
FullDemo pattern (custom Activity + layout + factories)
Use when you need a fully custom player screen, advanced key handling, and maximum control over how ads and content are presented.
This integration pattern assumes that you fully understand all the complexities of this pathway.
You can start with the SimpleDemo style integration and gradually move to CustomExoDemo or FullDemo as your requirements grow, reusing the same core SDK API (MediaItem, StreaMixSDK, PlaybackListener, configuration classes and factory adapters).