Android Player SDK

Quickstart: Android Player

This guide will walk you through the steps to start a BlendVision One streaming playback on native Android application (mobile/tablet) using the Android player SDK.

 

Additionally, you can also check out the sample project for an even smoother start:
https://github.com/BlendVision/Android-Player-SDK/tree/main/samples

 

Before We Start

Before proceeding, ensure that you have prepared your BlendVision One streaming content. You can prepare your content in two ways:

Step 1: Obtain a Playback Token

  • Obtain a valid API token by following the authentication steps
  • Retrieve the resource_id and resource_type of the streaming content you would like to playback. There are two ways to obtain this information:
    • Retrieve using the API
    • Copy from your BlendVision One console
      • VOD > Publishing Tools > Player SDK > VOD ID
      • Live > Publishing Tools > Player SDK > Event ID
  •  

  • Obtain the playback token using the API: /bv/cms/v1/tokens, with the resource_id and resource_type as body parameters

    • You can also include customer_id in the body parameters if you want to track user playback with your own defined user ID

const val API_DOMAIN = "https://api.one.blendvision.com"

interface ApiService {
    @POST("bv/cms/v1/tokens")
    suspend fun getPlaybackToken(
        @Header("Authorization") cmsToken: String, // 'Bearer ${CMS token}'
        @Body request: PlaybackTokenRequest()
    }: PlaybackTokenResponse
}

data class PlaybackTokenRequest(
    @SerializedName("resource_id")
    val resourceId: String,
    @SerializedName("resource_type")
    val resourceType: String,
    @SerializedName("customer_id")
    val customerId: String
)

data class PlaybackTokenResponse(
    @SerializedName("token")
    val playbackToken: String
)

 

Step 2: Start a Playback Session

const val API_DOMAIN = "https://api.one.blendvision.com"

interface ApiService {
    @POST("bv/playback/v1/sessions/{deviceId}:start")
    suspend fun startPlaybackSession(
        @Header("Authorization") playbackToken: String,
        @Path("deviceId") deviceId: String
    ): StartSessionResponse
    
    @POST("bv/playback/v1/sessions/${deviceId}")
    suspend fun getStreamInfo(
        @Header("Authorization") playbackToken: String,
        @Path("deviceId") deviceId: String
    ): GetStreamInfoResponse
}

// data for start a session
data class StartSessionResponse(
    @SerializedName("drm_server_endpoint")
    val endPoint: String
)

// data for get stream information
data class GetStreamInfoResponse(
    @SerializedName("sources")
    val sources: List
)

data class Source(
    @SerializedName("manifests")
    val manifests: List,
    @SerializedName("thumbnail_seeking_url")
    val thumbnailSeekingUrl: String
)

data class Manifest(
    @SerializedName("protocol")
    val protocal: String,
    @SerializedName("url")
    val url: String,
    @SerializedName("resolutions")
    val resolutions: List
)

data class Resolution(
    @SerializedName("height")
    val height: String,
    @SerializedName("width")
    val width: String
)

 

Step 3: Initialize the Player

Obtain Player License Key

Obtain a valid player license key from your BlendVision One console

Install Player SDK

  • Download from https://github.com/BlendVision/Android-Player-SDK/releases
  • Create /libs folder in the project root path

  • Add below description in the gradle

    implementation fileTree(dir: 'libs', include: ['*.aar'])
    
  • Add following .aar files to libs/.

    // UniPlayer
    kks-playcraft-daas.aar
    kks-playcraft-paas.aar
    
    // KKSPlayer
    kksplayer.aar
    kksplayer-kkdrm.aar
    kksplayer-library-core-release.aar
    kksplayer-library-common-release.aar
    kksplayer-library-extractor-release.aar
    kksplayer-library-dash-release.aar
    kksplayer-library-ui-release.aar
    
    // KKS-network
    kks-network.aar
    
    • others (can be imported from public maven)
    plugins {
        ...
        id 'kotlin-kapt'
    }
    
    api ('com.google.guava:guava:' + guava_version) {
        // Exclude dependencies that are only used by Guava at compile time
        // (but declared as runtime deps) [internal b/168188131].
        exclude group: 'com.google.code.findbugs', module: 'jsr305'
        exclude group: 'org.checkerframework', module: 'checker-compat-qual'
        exclude group: 'com.google.errorprone', module: 'error_prone_annotations'
        exclude group: 'com.google.j2objc', module: 'j2objc-annotations'
        exclude group: 'org.codehaus.mojo', module: 'animal-sniffer-annotations'
    }
    
    //Google IMA SDK
    implementation "com.google.ads.interactivemedia.v3:interactivemedia:$google_ima_version"
    
    //Chromecast
    implementation "com.google.android.gms:play-services-cast-framework:$cast_version"
    
    //Coroutines
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
    
    //Okhttp
    implementation 'com.squareup.okhttp3:okhttp:' + okhttp_version
    implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version"
    
    // gson
    implementation 'com.google.code.gson:gson:' + gsonVersion
    
    // thumbnail
    implementation "com.github.bumptech.glide:glide:$glideVersion"
    kapt "com.github.bumptech.glide:compiler:$glideVersion"
    
  • Set gradle.properties

    android.enableDexingArtifactTransform.desugaring=false
    android.enableJetifier=true

Create a Player

To play the streaming content, create a player instance with the license key and stream information in the initialization configuration:

// create the player instance
private var player: UniPlayer? = null
player = UniPlayer.Builder(
        requireContext(),
        PlayerConfig(
            license = "YOUR_LICENSE_KEY"
        )
    ).build()
    
// set player view type
binding.kksPlayerServiceView.setupControlPanel(
    defaultContentType = ContentType.STANDALONE
)

// bind the new created player to player view
binding.playerView.setUnifiedPlayer(player)

// load stream information
player?.load(
    MediaConfig(
        source = listOf(
            MediaConfig.Source(
                url = streamInfoResponse.sources[0].manifests.filter { it.protocol == MediaConfig.Protocol.DASH }[0].url,
                protocal = MediaConfig.Protocol.DASH,
                drm = MediaConfig.DrmInfo.Widevine(
                    licenseUrl = startSessionResponse.endPoint,
                    headers = mapOf("" to "")
                )
            )
        ),
        title = "",
        imageUrl = "",
        thumbnailSeekingUrl = ""
    )
)

// start playback
player?.start()

// pause/play during playback
player?.pause()
player?.play()

// release the player
player?.release()

 

Step 4: Manage the Lifecycle of a Playback Session

const val API_DOMAIN = "https://api.one.blendvision.com"

interface ApiService {

    // post this API every 10 seconds
    @POST("bv/playback/v1/sessions/${deviceId}:heartbeat")
    suspend fun Heartbeat(
        @Header("Authorization") playbackToken: String,
        @Path("deviceId") deviceId: String
    )
    
    @POST("bv/playback/v1/sessions/${deviceId}:end")
    suspend fun EndPlaybackSession(
        @Header("Authorization") playbackToken: String,
        @Path("deviceId") deviceId: String
    )
}

 

What's More

Updated