Session handling
In the SmartLib lifecycle, a few methods have to be called:
- init: initialization of the library with your environment (CDN used, analytics server, nanoCDN...)
- createStreamingSession: create a StreamingSession object that handle the session lifecycle
- attachPlayer: attach a player to the session in order to compute metrics (mandatory only if an analytics integration is required)
- getURL and stopStreamingSession: start and stop the streaming session
If you are implementing an Analytics only integration, follow Analytics only guide instead of this guide
1. Initialization
The initial step requires to call the init
method. This action should be performed once during the application's startup phase.
The method cannot be called right before starting a session due to asynchronous internal processing that might not have finished.
- Android
- iOS & tvOS
- Web
/**
* Use the init generator (bellow) to get your specific parameters
*
* @param applicationContext Application context
* @param analyticsAddress Address of the analytics server (i.e. "https://server-host") or
* an analytics server list (i.e. "http://server-host,https://server-host-2,http://server-host-3") or
* an empty string for no analytics server.
* Add "nocache=" as prefix to prevent caching failed reports (i.e. "nocache=http://server-host:8080")
* @param nanoCDNHost The nanoCDN host or ip address (i.e "192.168.1.1") or
* an empty string for no nanoCDN or
* "discover" to enable discovery on the local network or
* "127.0.0.1" to enable discovery on the local device or
* "*" to enable discovery on the local network and the local device or
* a nanoCDN host list (i.e "192.168.1.1,192.168.1.10")
* @param broadpeakDomainNames The domain name list to use to identify url(s) using broadpeak product (i.e "cdn.broadpeak.com,cdn2.broadpeak.com")
* "*" specific value is used to declare that all sessions are using a Broadpeak CDN or
* an empty string is used to declare that all given url are not hosted on a Broadpeak CDN
*/
SmartLib.getInstance().init(context.getApplicationContext(), ..., ..., ...);
@import SmartLib; // on iOS
@import SmartLib_tvOS; // on tvOS
/**
* Use the init generator (bellow) to get your specific parameters
*
* @param analyticsAddress Address of the analytics server (i.e. "https://server-host") or
* an analytics server list (i.e. "http://server-host,https://server-host-2,http://server-host-3") or
* an empty string for no analytics server.
* Add "nocache=" as prefix to prevent caching failed reports (i.e. "nocache=http://server-host:8080")
* @param nanoCDNHost The nanoCDN host or ip address (i.e "192.168.1.1") or
* an empty string for no nanoCDN or
* "discover" to enable discovery on the local network or
* "127.0.0.1" to enable discovery on the local device or
* "*" to enable discovery on the local network and the local device or
* a nanoCDN host list (i.e "192.168.1.1,192.168.1.10")
* @param broadpeakDomainNames The domain name list to use to identify url(s) using broadpeak product (i.e "cdn.broadpeak.com,cdn2.broadpeak.com")
* "*" specific value is used to declare that all sessions are using a Broadpeak CDN or
* an empty string is used to declare that all given url are not hosted on a Broadpeak CDN
*/
[SmartLib initSmartLib:...
nanoCDNHost:...
broadpeakDomainNames:...];
/**
* Use the init generator (bellow) to get your specific parameters
*
* @param analyticsAddress Address of the analytics server (i.e. "https://server-host") or
* an analytics server list (i.e. "http://server-host,https://server-host-2,http://server-host-3") or
* an empty string for no analytics server.
* Add "nocache=" as prefix to prevent caching failed reports (i.e. "nocache=http://server-host:8080")
* @param nanoCDNHost The nanoCDN host or ip address (i.e "192.168.1.1") or
* an empty string for no nanoCDN or
* "127.0.0.1" to enable discovery on the local device or
* a nanoCDN host list (i.e "192.168.1.1,192.168.1.10")
* @param broadpeakDomainNames The domain name list to use to identify url(s) using broadpeak product (i.e "cdn.broadpeak.com,cdn2.broadpeak.com")
* "*" specific value is used to declare that all sessions are using a Broadpeak CDN or
* an empty string is used to declare that all given url are not hosted on a Broadpeak CDN
*/
SmartLib.getInstance().init(..., ..., ...);
-
On web platforms, the nanoCDN auto-discovery is not available due to a technical limitation. The resolving has to use a hostname or an ip address.
-
On iOS & tvOS, if nanoCDNHost is set to
discover
or*
, an extra permission needs to be set in the app: iOS 14 and local network privacy
- Add "nocache=" as prefix to an analytics address to prevent caching failed reports (i.e. "nocache=http://server-host:8080")
2. Create a streaming session
For each video session, it is required to create a StreamingSession
object and to store it.
This object handles the session lifecycle and will be used in different parts of your code.
For instance, call the following code when the user entered the UI that will show a content:
- Android
- iOS & tvOS
- Web
// Create a new streaming session object (1 per video session) and store it
StreamingSession session = SmartLib.getInstance().createStreamingSession();
// Create a new streaming session object (1 per video session) and store it
StreamingSession *session = [SmartLib createStreamingSession];
// Create a new streaming session object (1 per video session) and store it
const session = SmartLib.getInstance().createStreamingSession();
Multiple session objects can be handled at the same time. It can be useful for PIP or zapping optimization purposes.
3. Attach a player
This step is mandatory only if a player integration is required. In that case, follow one of the guide in the Player integration section too.
The following code uses a mocked player API. To get the actual API, refer to Player integration.
Please find which integration types require a player integration in Getting started.
When creating the player instance, attach it to the current session.
- Android
- iOS & tvOS
- Web
// Create your player
MyPlayer player = new MyPlayer(); // to be adapted with your player API
// Attach your player to the current session
session.attachPlayer(player);
// Create your player
MyPlayer *player = [[MyPlayer alloc] init]; // to be adapted with your player API
// Attach your player to SmartLib
[session attachPlayer:player];
// Create your player
const player = new MyPlayer(); // to be adapted with your player API
// Attach your player to the current session
session.attachPlayer(player);
4. Start a streaming session
The getURL
method is used to get the actual streaming URL and start the streaming session. This method is also the starting point of the analytics calculation, for instance the startup time starts from this method.
The returned URL can be different for every video session. In case of using a Broadpeak CDN or a nanoCDN, it includes a unique token. It can be used only once per session object, once called the session is actually started.
When getURL
returns an error, it means no streaming URL can be found. It has to trigger a specific behaviour on the application (error message, dialog...) and stopStreamingSession
has to be called. Find more details about getURL
errors on the session errors page.
It is recommended to perform this call on a different thread than the main thread, the method runs HTTP requests.
This method has to be called even for non-Broadpeak content URLs. In this case, the method will return the same URL.
- Android
- iOS & tvOS
- Web
// Start the session and get the final stream URL
StreamingSessionResult result = session.getURL(...);
if (!result.isError()) {
// Load the stream URL into your player
player.playURL(result.getURL()); // to be adapted with your player API
} else {
// Stop the session
session.stopStreamingSession();
// Process the loading error
}
// Get the stream URL from SmartLib
StreamingSessionResult *result = [session getURL:...];
if (![result isError]) {
// Load the stream URL into your player
[player playURL:[result getURL]]; // to be adapted with your player API
} else {
// Stop the session
[session stopStreamingSession];
// Process the loading error
}
// Get the stream URL from SmartLib
session.getURL(contentURL)
.then(result => {
if (!result.isError()) {
// Load the stream URL into your player
player.playURL(result.getURL()); // to be adapted with your player API
} else {
// Stop the session
session.stopStreamingSession();
// Process the loading error
}
});
5. Stop a streaming session
The stopStreamingSession
method must be called each time the session is stopped:
- end users: when the playback is stopped by a user action
- loading errors: when the streaming session cannot be started through the
getURL
method - player errors: when the player triggers a non-recoverable error during the playback (as a decoding error)
- application or any others actions: when the app is killed
- Android
- iOS & tvOS
- Web
// Stop the session
session.stopStreamingSession();
player.stop(); // to be adapted with your player API
// Stop the session
[session stopStreamingSession];
[player stop]; // to be adapted with your player API
// Stop the session
session.stopStreamingSession();
player.stop(); // to be adapted with your player API
6. Full example
The sample code does not implement an actual player API, it has to be adapted depending on your player API.
All related codes to a player is mandatory only if a player integration is required.
- Android
- iOS & tvOS
- Web
// When the app is starting, init the lib
protected void initApp() {
...
SmartLib.getInstance().init(context.getApplicationContext(), ..., ..., ...);
...
}
// Your player object
private MyPlayer mPlayer;
// SmartLib StreamingSession
private StreamingSession mSession;
// It is recommended to use a different thread to start a session
private ExecutorService mExecutor = Executors.newSingleThreadExecutor();
...
// When creating a video session
protected void startSession() {
// Create the player
mPlayer = new MyPlayer();
// Registering to player error events
mPlayer.setOnErrorEvent(this);
// Create a StreamingSession object
mSession = SmartLib.getInstance().createStreamingSession();
// Attach the player to the session
mSession.attachPlayer(mPlayer);
// Start the session in a different thread, getURL can make requests to the Broadpeak CDN, nanoCDN...
mExecutor.submit(() -> {
StreamingSessionResult result = mSession.getURL(...);
if (!result.isError()) {
mPlayer.playURL(result.getURL());
} else {
mSession.stopStreamingSession();
// Process the loading error
showNoSessionCreatedMessage();
}
});
}
@Override
public void onPlayerError(PlaybackException error) {
// If the playback has been canceled because of a player error
// (i.e. non-recoverable error), stop the streaming session
if (error.playbackCanceled) {
mSession.stopStreamingSession();
showPlayerTriggeredAnErrorMessage();
}
}
// When the app is starting, init the lib
- (void)initApp {
...
[SmartLib initSmartLib:... nanoCDNHost:... broadpeakDomainNames:...];
...
}
// Your player object
@property (nonatomic,strong) MyPlayer *player;
// SmartLib StreamingSession
@property (nonatomic,strong) StreamingSession *session;
...
// When creating a video session
protected void startSession() {
// Start the session in a different thread, getURL can make requests to the Broadpeak CDN, nanoCDN...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
// Create the player
self.player = [[MyPlayer alloc] init];
// Registering to player error events
[self.player setOnErrorEvent:self];
// Create a StreamingSession object
self.session = [SmartLib createStreamingSession];
// Attach the player to the session
[self.session attachPlayer:self.player];
// Start the session
StreamingSessionResult *result = [self.session getURL:...];
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (![result isError]) {
[self.player playURL:[result getURL]];
} else {
[self.session stopStreamingSession];
// Process the loading error
[self showNoSessionCreatedMessage];
}
});
});
}
- (void)onPlayerError:(PlayerError *)error {
// If the playback has been canceled because of a player error
// (i.e. non-recoverable error), stop the streaming session
if (error.playbackCanceled) {
[self.session stopStreamingSession];
[self showPlayerTriggeredAnErrorMessage];
}
}
// When the app is starting, init the lib
function initApp() {
...
SmartLib.getInstance().init(..., ..., ...);
...
}
// Your player object
let player;
// SmartLib StreamingSession
let session;
...
// When creating a video session
function startSession() {
// Create the player
player = new MyPlayer();
// Registering to player error events
player.setOnErrorEvent(onPlayerError);
// Create a StreamingSession object
session = SmartLib.getInstance().createStreamingSession();
// Attach the player to the session
session.attachPlayer(player);
// Get the stream URL from SmartLib
session.getURL(...)
.then(result => {
if (!result.isError()) {
// Load the stream URL into the player
player.setURL(result.getURL());
player.play();
} else {
// Stop the session
session.stopStreamingSession();
// Process the loading error
showNoSessionCreatedMessage();
}
});
}
function onPlayerError(error) {
// If the playback has been canceled because of a player error
// (i.e. non-recoverable error), stop the streaming session
if (error.playbackCanceled) {
session.stopStreamingSession();
showPlayerTriggeredAnErrorMessage();
}
}