@dicetechnology/react-native-vesper-sdk - v0.5.1

react-native-vesper-sdk

React native wrapper for iOS/Android native VesperSDK

Installation

npm install @dicetechnology/react-native-vesper-sdk

The @dicetechnology/react-native-vesper-sdk is a wrapper around native iOS/Android VesperSDK which are hosted in private repositories. It requires basic authentication to download and install.

iOS VesperSDK auth

You will need to provide your credentials in ~/.netrc file to be able to authenticate during pod install phase. Add this inside your ~/.netrc file or create new file if you do not have one:

machine d1st2jzonb6gjl.cloudfront.net
login <login>
password <password>

Android VesperSDK auth

You will need to provide your Cloudfront authorisation token in the project level build.gradle file and have the Google, Central, Mux, and Endeavor Streaming Maven repositories included.

allprojects {
repositories {
google()
mavenCentral()
maven {
// Mux repository
url "https://muxinc.jfrog.io/artifactory/default-maven-release-local"
content {
includeGroupByRegex "com\\.mux.*"
}
}
maven {
// Endeavor Streaming repository
url "https://d1yvb7bfbv0w4t.cloudfront.net/"
credentials { username authToken }
}
}
}

Once you have your authorisation token, add it to $HOME/.gradle/gradle.properties

authToken=your_auth_token

Note: Adding your authorisation token directly to the build.gradle file in the root of your project will also work, but this is not recommended. The build.gradle file in the root of your project is typically committed to your source control (Git) repository and this will expose your authorisation token.

Android Gradle configuration

Add the following property to your gradle.properties file to disable the dexing artifact transform:

For Gradle versions earlier than 8.4:
android.enableDexingArtifactTransform=false
For Gradle versions 8.4 and later:
android.useFullClasspathForDexingTransform=true

Usage

Initialization

import { PlayerViewEvent, PlayerView, VesperSdk, AuthManager } from '@dicetechnology/react-native-vesper-sdk';

class VesperAuthManager implements AuthManager {
public async getAuthToken(): Promise<string> {
//return authToken from internal storage, after any token refresh return the new fresh one here
return 'auth_token';
}

public async getRefreshToken(): Promise<string> {
return 'refresh_token';
}

public async refreshAuthToken(authToken: string): Promise<string> {
//refresh and store authToken then return refreshed one here
return 'refreshed_auth_token';
}
}

VesperSdk.setup({
apiConfig: {
realm: 'dce.REALM_HERE',
environment: Environment.PRODUCTION,
apiKey: 'API_KEY_HERE',
},
authManager: new VesperAuthManager(),
});

Authentication

You may have noticed that the SDK takes an AuthManager as part of its configuration.

Ownership of the authentication flow is left to the application using the Vesper SDK. Once the app has authenticated with the user's credential, the SDK via the AuthManager will retrieve the user's authToken and refreshToken to facilitate interactions with the Vesper platform.

Token Refresh

When the authToken expires, the SDK will use the refreshAuthToken method on the AuthManager to request a new token from the application. It is the application's responsibility to request and provide the updated token back to the Vesper SDK.

In the event of an authToken refresh error, the current playback session will be stopped. The expectation will be on the app to prompt the user to sign in again.

The SDK offers a mechanism to listen for this event. We'll take a closer look at this in the Listen section.

Creating the Player

Once the Vesper SDK has been configured, you may move on to the PlayerView and create it for managing playback.

The PlayerView will be our entry point for everything playback-related--as we will see throughout this guide. The simplest way to create it is as follows:

export default function App() {
const ref = React.createRef<PlayerView>();

return (
<View style={styles.container}>
<PlayerView
ref={ref}
style={styles.box}
/>
</View>
);
}

Load a video

export default function App() {
const ref = React.createRef<PlayerView>();

const handleLoadPress = () => {
ref.current?.load({ id: '12345', isLive: false });
};

return (
<View style={styles.container}>
<PlayerView
ref={ref}
style={styles.box}
/>
<View style={{ flexDirection: 'row' }}>
<Button
title="Load"
onPress={() => {
handleLoadPress();
}}
/>
</View>
</View>
);
}

Load a collection (playlist | season | watchlist)

const handleLoadPress = () => {
ref.current?.load({
id: '<video_id>',
isLive: false,
watchContext: {
id: '<playlist_id>',
type: WatchContextType.PLAYLIST
}
});
};

Take control

ref.current?.play();
ref.current?.pause();
ref.current?.unload();
ref.current?.seekTo(100);

Listen

The SDK has a event-based system. It sends PlayerViewEvent which you can listen to by passing callback to a PlayerView, PlayerViewEvent contains type which can be either player or view, amount of events will be increased with future versions

export default function App() {
const ref = React.createRef<PlayerView>();

const handlePlayerViewEvent = (event: PlayerViewEvent) => {
console.log(
'onPlayerViewEvent ==> ' +
'type:' +
event.type +
' ,name:' +
event.name +
' ,data:' +
event.data
);
};

return (
<View style={styles.container}>
<PlayerView
ref={ref}
style={styles.box}
onPlayerViewEvent={handlePlayerViewEvent}
/>
</View>
);
}

Picture in Picture(PIP)

iOS

To make PIP work for your app you need to add corresponding Background Mode to you xCode project this will allow player to automatically switch to PIP mode when app is backgrounded.

Android

The SDK supports the picture-in-picture feature. To enable this, the hosting activity must declare support for the feature by adding android:supportsPictureInPicture="true" in the AndroidManifest.xml file:

<activity
android:name=".MainActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:supportsPictureInPicture="true" />

You also need to notify the SDK when to enter picture-in-picture mode and when the mode has changed via the VesperPlayerPipService. This is typically done within the following callbacks of the hosting activity:

import com.dice.vesper.rn.android.VesperPlayerPipService;

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
VesperPlayerPipService.onPictureInPictureModeChanged(isInPictureInPictureMode);
}

@Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
VesperPlayerPipService.onUserLeaveHint();
}

Chromecast

iOS

Add NSBonjourServices to your Info.plist Specify NSBonjourServicesin yourInfo.plist` to allow local network discovery to succeed on iOS 14.

You will need to add both _googlecast._tcp and _<cast_receiver_id>._googlecast._tcp as services for device discovery to work properly.

Vesper SDK will parse Info.plist and configure Google cast context

Update the following example NSBonjourServices definition and replace ABCD1234 with your cast receiver id.

<key>NSBonjourServices</key>
<array>
<string>_googlecast._tcp</string>
<string>_ABCD1234._googlecast._tcp</string>
</array>

Add NSLocalNetworkUsageDescription to your Info.plist We strongly recommend that you customize the message shown in the Local Network prompt by adding an app-specific permission string in your app's Info.plist file for the NSLocalNetworkUsageDescription such as to describe Cast discovery and other discovery services, like DIAL.

<key>NSLocalNetworkUsageDescription</key>
<string>${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi
network.</string>
This message will appear as part of the iOS Local Network Access dialog as shown in the mock.

After this configurations are done casting with Vesper SDK is trivial. Once the player has been created and the content is loaded, all you need to do is tap on cast button in the right corner of player UI.

Android

Add the cast_receiver_id to your strings.xml resource:

<resources xmlns:tools="http://schemas.android.com/tools">
<string name="vesper_cast_receiver_id">ABCD1234</string>
</resources>