Android SDK quick integration
MeshStream Android SDK adds P2P media delivery to an Android player. Your app keeps its existing player; the SDK manages playback sessions, media request routing, and CDN fallback.
Before running the code, complete Installation and setup, prepare your SDK Key and playable media URL, and configure the application network policy.
Quick start
Follow four steps: initialize the Client, create a playback session, pass the session playback URL to the player, then release the session when playback ends.
1. Initialize the Client
val client = P2pSdk.create(
applicationContext,
P2pConfig(key = "your_sdk_key"),
)
2. Create a session and pass it to the player
originUrl is the original media URL. Create one session for each playback and always pass session.playbackUrl to the player. The session URL preserves the existing media path; P2P availability changes acceleration state, not whether that URL is used.
val session = client.createPlaybackSession(
originUrl,
PlaybackOptions(contentId = "movie-2026-001"),
)
player.setMediaItem(MediaItem.fromUri(session.playbackUrl))
player.prepare()
player.play()
3. Release the session when playback ends
session?.close()
4. Release the Client when the app no longer uses the SDK
P2pSdk.shutdown()
Temporary acceleration unavailability does not interrupt playback; the player continues using the session's playbackUrl. Only when SDK initialization or session creation throws because of a local configuration, resource, or programming error may the application explicitly log the error and play originUrl directly. That is an application fallback, bypasses the SDK, and is not included in SDK usage reporting.
Preload the next item
For a likely next HLS or DASH item, create its session first and call preload(). It asynchronously warms the manifest and first segment without waiting for network I/O or controlling a player. Reuse that same session when the user switches items; close it when the candidate is discarded:
val nextSession = client.createPlaybackSession(nextOriginUrl)
nextSession.preload()
player.setMediaItem(MediaItem.fromUri(nextSession.playbackUrl))
player.prepare()
player.play()
// When the candidate is no longer needed.
nextSession.close()
Configuration
| Field | Default | Description |
|---|---|---|
key | Required | SDK Key issued by the console |
playbackUrl | Empty | Legacy bootstrap identity hint only; it does not create a session or select the player URL. New integrations should use createPlaybackSession(originUrl) with a stable contentId |
contentId | Empty | Stable content identity; recommended for URLs with rotating signatures |
mimeType | Empty | m3u8, mpd, mp4, or mp3; use when the extension is not clear |
originHeaders | Empty map | Headers sent to the origin media request; never sent to other devices |
p2pEnabled | true | Local P2P switch; platform policy has higher priority |
maxPeerConnections | 12 | Maximum simultaneous peer connections |
maxUploadPeers | 4 | Maximum devices this device shares content with at once |
maxDownloadPeers | 5 | Maximum peers this device downloads from at once |
requestTimeoutMs | 8000 | P2P segment request timeout before CDN fallback |
maxMemoryBytes | 64 MiB | Media cache limit used by the SDK |
logLevel | NONE | Log level: NONE / ERROR / INFO / DEBUG |
The SDK reads the package name and signing information automatically. Your app does not need to configure them. Service discovery addresses are also built into the SDK.
The SDK does not accept a client-selected region. The service resolves the SDK Key's tenant home region (homeRegion) and derives access-side locality (edgeRegion) from trusted request-network signals for Tracker and ICE scheduling. This is separate from data residency. Do not add areaCode, area_code, or region to the client configuration. In multi-center strict mode, an unresolved home region returns 503 HOME_REGION_UNRESOLVED; a request sent to the wrong center returns 421. The SDK does not switch centers itself, and all acceleration failures retain the CDN playback path.
Dynamic URLs and origin headers
When playback URLs contain short-lived signatures, pass a stable contentId:
P2pConfig(
key = "your_sdk_key",
contentId = "asset-12345",
mimeType = "m3u8",
originHeaders = mapOf(
"Authorization" to "Bearer $originToken",
),
)
originHeaders are used only for requests to your origin and are never sent to other devices. Origin authorization remains your responsibility through signed URLs, cookies, or request-header policies.
Playback session API
| Method | Description |
|---|---|
createPlaybackSession(originUrl) | Creates a playback session and returns the SDK playback URL |
preload() | Asynchronously warms an HLS/DASH manifest and first segment without playing media; returns true only when this call queued a warmup |
setP2pEnabled(enabled) | Enables or disables P2P at runtime without affecting CDN playback |
updateBufferedDurationMs(value) | Reports the time from the current position to the buffer edge so background P2P prefetch can be adjusted |
updateCurrentPositionMs(value) | Reports the current playback position; VOD uses it to match peers at a similar position and it should be called immediately after a seek |
statistics() | Returns a snapshot of current traffic and peer counts |
close() | Ends the session and releases its resources |
One P2pClient can manage multiple independent playback sessions. Call P2pSdk.shutdown() when the app no longer needs the SDK.
Events and statistics
client.addEventListener(object : P2pEventListener {
override fun onP2pReady(sessionId: Long) {}
override fun onPeerCountChanged(sessionId: Long, peerCount: Int) {}
override fun onStatistics(sessionId: Long, stats: P2pStats) {}
override fun onP2pUnavailable(sessionId: Long, reason: P2pUnavailableReason) {}
override fun onCdnFallback(sessionId: Long, bytes: Long) {}
})
Every callback includes a sessionId, allowing one client to distinguish multiple players. P2P state events describe acceleration only and must not be used as a reason to stop playback.
HLS, DASH, and direct MP4/MP3 playback
- The SDK supports HLS, DASH, and direct MP4/MP3 media requests with Range support; it does not decode media formats.
- MP4/MP3 require the origin to support a single Range request and return a valid
Content-Range. Otherwise playback remains on CDN. For an extensionless direct-media URL, setmimeType = "mp4"ormimeType = "mp3"inPlaybackOptions; the host player must still support that format. - Android apps need a player that supports the corresponding format, such as Media3 HLS or Media3 DASH.
- Maven
1.0.9is a four-ABI universal AAR:armeabi-v7a/x86target API 17 andarm64-v8a/x86_64target API 21. - Devices must meet the minimum system version for their ABI as well as the player’s requirements.
- The SDK package declares
INTERNETandACCESS_NETWORK_STATE; confirm network permissions according to your app's project policy.
Playback resilience
The following conditions only disable or reduce P2P acceleration; they never block media playback:
- SDK Key or application validation failure;
- No available peers;
- Network conditions unsuitable for P2P;
- P2P segment request timeout or failure;
- Temporary service unavailability.
Next steps
Quick start · Best practices · Troubleshooting
Related guides: Installation and setup · Advanced usage.