Menu

Expand
Rate this page:

Android Player SDK Overview

We are no longer allowing new customers to onboard to Twilio Live. Effective November 30, 2023, Twilio Live will End of Life. We have created this Migration Guide to help you identify an alternative solution for your use case.

The Twilio Live Player Android SDK lets you play a stream in your native Android application.

Prerequisites

  • Android Studio 3.0 or higher
  • Support for Android API level 21 or higher
  • Support for Java 8

Add the SDK

To get started with the Player Android SDK, add the following to your build.gradle file.

allprojects {
    repositories {
        /**
         * The Twilio Live Player Android SDK is hosted on Maven Central
         */
        mavenCentral()
    }
}

dependencies {
    implementation "com.twilio:live-player-android:1.0.0"
}

Usage

The following snippets provide demonstrations on how to use the Player Android SDK in an app. For more details about streaming content, visit the Twilio Live documentation.

Connecting a Player and Handling Events

Once your app acquires a Twilio access token, you can connect to a stream.


val player = Player.connect(context, "access token", object : PlayerListener {
    /**
     * The player instance is returned in the PlayerState.CONNECTING state after calling connect.
     */
    override fun onStateChanged(player: Player, playerState: PlayerState) {
        when (playerState) {
            PlayerState.IDLE -> {
                /**
                 * The player has successfully authenticated and is loading the stream. This
                 * state is also reached as a result of calling player.pause().
                 */
            }
            PlayerState.READY -> {
                /**
                 * The player is ready to playback the stream.
                 */
            }
            PlayerState.PLAYING -> {
                /**
                 * The player is now playing a stream. This state occurs as a result of calling
                 * player.play().
                 */
            }
            PlayerState.BUFFERING -> {
                /**
                 * The player is buffering content.
                 */
            }
            PlayerState.ENDED -> {
                /**
                 * The stream has ended.
                 */
            }
        }
    }

    override fun onFailed(player: Player, playerException: PlayerException) {
        /**
         * An error occurred connecting the player or loading a stream.
         */
    }
})

Managing Playback

The following snippets demonstrate how to manage playback in your app.


/**
 * Once the Player reaches the PlayerState.READY state after initially calling 
 * Player.connect(...), an application can invoke play(). The player will then transition to 
 * the PlayerState.PLAYING state once playback successfully begins.
 * 
 * play() can also be called during the PlayerState.IDLE state only after transitioning as a result
 * of calling pause().
 */
player.play()

/**
 * To pause playback, invoke pause(). The player will transition to PlayerState.IDLE
 * until playback is resumed with a subsequent call to play().
 */
player.pause()

/**
 * Playback audio can be muted by updating the isMuted property.
 */
player.isMuted = true

/**
 * The playback volume can also be adjusted. Updating the isMuted property has no effect
 * on the volume property. Once a stream is un-muted, playback will ensue with the last set
 * player volume.
 */
player.volume = 0.25f

Using the PlayerView

The PlayerView subclasses a TextureView. To render a stream in your app, instantiate a PlayerView and set the player.playerView property.


val player = Player.connect(...)

player.playerView = playerView

Handling TimedMetadata

When a Media Extension inserts TimedMetadata into a stream, the player will emit the onTimedMetadata callback if the player is in the PlayerState.PLAYING state. TimedMetadata will not be received if the player is paused and any data inserted while a player is paused will not be received once the player is resumed.


val playerListener = object : PlayerListener {
    override fun onTimedMetadata(player: Player, metadata: TimedMetadata) {
        /**
         * Handle the data
         */
    }
}

Disconnecting a Player

In order to free resources, the player should be disconnected when your application no longer requires the instance.


/**
* Disconnect the player and transition the player to the PlayerState.ENDED state. The player object
* is no longer usable.
*/
player.disconnect()

Telemetry

The Telemetry API enables applications to subscribe to event and metric data collected by the Player SDK. Telemetry data emitted by the Player SDK can be used to track stream quality, triage issues, and better understand your application's Player SDK usage.


Typed Data Events

The Player SDK represents telemetry data as strongly typed classes. Reference the table below for a summary of the currently reported events.

Type Reporting Details
Connection.Connecting Reported when Player.connect(...) is called
Connection.Connected Reported when the Player is connected to Twilio Media Service
Connection.NetworkUnavailable Reported when onNetworkUnavailable is invoked
Connection.Disconnected Reported when Player.disconnect() is called
Connection.Error Reported when onFailed is invoked in the CONNECTING state
Playback.Played Reported when player.play() is called
Playback.Paused Reported when player.pause() is called
Playback.VolumeSet Reported when player.volume is set
Playback.Muted Reported when player.isMuted is set to true
Playback.Unmuted Reported when player.isMuted is set to false
Playback.Error Reported when onFailed is invoked in the following states: IDLE, READY, PLAYING, BUFFERING
Playback.Rebuffering Reported when onRebuffering is invoked
PlaybackQuality.Summary Reported every three seconds while the player is BUFFERING or PLAYING
PlaybackQuality.QualitySet Reported when player.quality is set
PlaybackQuality.QualityChanged Reported when onQualityChanged is invoked
PlaybackQuality.VideoSizeChanged Reported when onVideoSizeChanged is invoked
PlaybackQuality.HighLatencyReductionApplied Reported when the SDK applies a high latency reduction strategy.
PlaybackQuality.HighLatencyReductionReverted Reported when the SDK reverts all high latency reduction strategies.
PlaybackState.Changed Each state is reported when onStateChanged is invoked
TimedMetadataTelemetry.Received Reported when onTimedMetadata is invoked

Usage

The following snippets demonstrate a few examples of how to use the Telemetry API.


Telemetry Logger

The following snippet demonstrates the simplest Telemetry example: Logging all Telemetry events emitted by the Player SDK


val telemetryLogger: TelemetrySubscriber = {
    Log.d("PlayerSdkTelemetry", it.toString())
}

// Subscribe the logger to events
Player.telemetry.subscribe(telemetryLogger)

// .. When your app no longer wants telemetry events, unsubscribe
Player.telemetry.unsubscribe(telemetryLogger)


Track High Latency

The following snippet demonstrates an example of checking experience quality by tracking any instances of high latency.


Player.telemetry.subscribe({
    if (it is TelemetryData.PlaybackQuality.Summary && it.playerLiveLatency > 3000) {
        yourAppsAnalytics.track("high-latency-detected")
    }
})


Track Connection Errors

The following snippet demonstrates an example of using TelemetryPredicate's to filter on specific Telemetry events.


Player.telemetry.subscribe({ yourAppAnalytics.track("connection-error-detected") }) {
    it is TelemetryData.Connection.Error
}

Threading Contract

The Player Android SDK does not provide thread safety. Developers should use a Player instance from a single thread. Typically, this will be the UI thread. All callbacks will be emitted on the same thread that called Player.connect(...). The SDK does log warnings if a threading violation is detected.


val player = Player.connect(...)

/**
 * This will result in a warning log!
 */
Thread {
    player.isMuted = true
}.start()
Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

Loading Code Sample...
        
        
        

        Thank you for your feedback!

        Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

        Sending your feedback...
        🎉 Thank you for your feedback!
        Something went wrong. Please try again.

        Thanks for your feedback!

        thanks-feedback-gif