Skip to main content

Quickstart

This guide validates one complete playback path: create an application and SDK Key, establish a playback session, pass the SDK-returned URL to the existing player, and verify that playback remains available when acceleration is unavailable.

Prerequisites​

  • A playable HLS .m3u8, DASH .mpd, or an MP4/MP3 URL with Range support;
  • An application and platform-specific SDK Key created in the console;
  • A player that can play the original media URL without MeshStream;
  • The signed URL, Cookie, or request headers required by the origin.

SDK selection, released versions, and native dependency mappings are listed in Choose your SDK.

1. Create an application and SDK Key​

Create an application in the console, then create an SDK Key for each target platform. An SDK Key identifies the application and integration platform and may be distributed with the client. It does not grant console access; account credentials, administrative tokens, and origin secrets must never be embedded in a client.

The tenant home region is configured by the platform. Application code does not need to pass a region field during SDK initialization.

2. Integrate by platform​

Every platform follows the same contract: create one session per playback, pass the session's playbackUrl to the existing player, and release the session when playback ends or content changes.

Web​

import { attach } from "@meshstream/p2p-web";

const session = attach({
key: "your_sdk_key",
url: "https://cdn.example.com/video/master.m3u8",
video: document.querySelector("video")!,
contentId: "movie-2026-001",
});

const result = await session.start();
console.log(result.mode);

// On page unload or when changing media.
session.dispose();

Android​

Add the Maven repository to the project configuration:

maven {
url = uri("https://sdk.meshstream.net/maven")
content { includeGroup("io.meshstream") }
}

Declare the dependency in the application module:

implementation("io.meshstream:meshstream-android-sdk:1.0.9")

Create the client and session, then pass playbackUrl to Media3 / ExoPlayer:

val client = P2pSdk.create(
applicationContext,
P2pConfig(key = "your_sdk_key"),
)
val session = client.createPlaybackSession(
originUrl,
PlaybackOptions(contentId = "movie-2026-001"),
)

player.setMediaItem(MediaItem.fromUri(session.playbackUrl))
player.prepare()
player.play()

// When changing content or destroying the playback screen.
session.close()

iOS / macOS​

Install with CocoaPods:

pod 'MeshStreamKit', '1.0.8'

Run pod install --repo-update to install the dependency. Existing projects use the version recorded in Podfile.lock. To upgrade, first change the exact 1.0.8 pin in Podfile to your target published version, then run pod update MeshStreamKit --repo-update. See iOS / macOS installation and setup for other installation methods and app permissions.

Retain self.client, self.session, and self.player as properties in the playback manager, then run the following code. The SDK Key must match the target platform and registered Bundle ID. originURL is the original media URL:

#import <MeshStreamKit/MeshStreamKit.h>
#import <AVFoundation/AVFoundation.h>

P2PConfig *config = [[P2PConfig alloc] initWithKey:@"your_sdk_key"];
NSError *clientError = nil;
self.client = [P2PSDK clientWithConfig:config error:&clientError];
if (self.client == nil) {
// Apply the application's error or fallback policy.
return;
}

P2PPlaybackOptions *options = [[P2PPlaybackOptions alloc] init];
options.contentId = @"movie-2026-001";
NSError *playbackError = nil;
self.session = [self.client createPlaybackSessionWithURL:originURL
options:options
error:&playbackError];
if (self.session == nil) {
return;
}
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:self.session.playbackUrl];
self.player = [AVPlayer playerWithPlayerItem:item];
[self.player play];

Attach the player to the application's playback view. When playback ends or content changes, release the old media item and session in the corresponding lifecycle callback:

[self.player pause];
[self.player replaceCurrentItemWithPlayerItem:nil];
[self.session close];
self.session = nil;

Windows​

Include the C ABI header, create the client and session, and pass the returned URL to the desktop player:

#include "meshstream.h"

meshstream_config_t config;
meshstream_config_default(&config);
config.key = "your_sdk_key";

meshstream_client_t* client = NULL;
meshstream_client_create(&config, &client);

meshstream_session_t* session = NULL;
meshstream_playback_options_t options = {0};
options.struct_size = sizeof(options);
options.version = MESHSTREAM_PLAYBACK_OPTIONS_VERSION;
options.content_id = "movie-2026-001";

meshstream_client_create_playback_session(
client, playback_url, &options, &session, NULL);
const char* sdk_playback_url = meshstream_session_get_playback_url(session);
// Pass sdk_playback_url to VLC, ffplay, or the application player.

// At the end of playback, destroy the session before the client.
meshstream_session_destroy(session);
meshstream_client_destroy(client);

3. Validate the playback path​

Use the following acceptance criteria:

  1. The player loads the SDK-returned playbackUrl, not the original media URL.
  2. The old session is released when content changes, the page unloads, or playback ends.
  3. After P2P is disabled or acceleration traffic is blocked, playback still completes through the existing CDN path.
  4. The console shows the session and usage data. Reporting is asynchronous and may have a short delay.

An unavailable acceleration path is not a media playback failure. Application error handling should follow the actual player and media-source state rather than stopping playback because of a P2P status.