Getting started with the Android SDK
Overview
The Android SDK is available on Nexus.
Key Features
- Developed in
Kotlin 1.9.0
(compatible with version1.8.20
and above) - Remote player management
- Verified Google IMA integration
- OMSDK support
- TCF2 support
- Access to Player events and state facilitated
- Fullscreen playback management
- Chromecast support
Supported versions & requirements
minSdk set to 21 (Lollipop) |
Dependencies
The following dependencies are required:
- For the Player:
androidx.fragment:fragment:1.5.7 |
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 |
- For advertising:
com.google.ads.interactivemedia.v3:interactivemedia:3.33.0 |
Sample applications
To help you learn about our Android SDK and to facilitate testing, discover our sample SDK applications:
- Android sample app: Download the sample app here directly on your device and explore the functionalities of the SDK in a user-friendly UI
- Source code: Access the source code of the sample app here, customize as you wish and easily integrate the SDK into your projects
Getting started
1 – Create an Android Player configuration
As a first step you need to create a custom player configuration for your Android application in your Dailymotion account. A unique Player Id will be generated which will be required for player initialization in-app, accurate monetization, targeting and attribution.
The custom player configuration can be created and managed either through the “Players” tab in the Dailymotion Studio or programmatically via the Platform API.
2 – Add the SDK to your project
- Add our Nexus repository to your
settings.gradle
file by adding the lines below to therepositories
block within thedependencyResolutionManagement
block.
maven {
name = "DailymotionMavenRelease"
url = "https://mvn.dailymotion.com/repository/releases/"
}
The resulting settings.gradle
should look like this:
dependencyResolutionManagement {
...
repositories {
...
maven {
name = "DailymotionMavenRelease"
url = "https://mvn.dailymotion.com/repository/releases/"
}
...
}
...
}
- Add dependencies inside your application
build.gradle
file:
dependencies {
...
implementation 'com.dailymotion.player.android:sdk:1.2.7'
implementation 'androidx.fragment:fragment:1.5.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'com.dailymotion.player.android:ads:1.2.7'
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.33.0'
...
}
3 – Create and add PlayerView to view hierarchy
Create a PlayerView
using Dailymotion.createPlayer(...)
method:
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
}
)
Explore the Android SDK Reference
Now that you’ve learned more about how to embed content using the Android SDK, you can dive deeper and see what’s possible to do to improve your integration and customize it to fit your needs with the following elements:
- Advanced runtime parameters: On top of your Player configuration, you can add extra parameters that can change at runtime.
- Methods: Our methods allow you to control the Player behavior, customize the user experience and create dynamic interactions.
- Events: Work with events to capture user interactions with the Player and trigger custom actions.
- State: Retrieve the data of your Player state
Add runtime Player parameters
While the main Player experience is controlled using the settings defined in your Player configuration from the Dailymotion Studio (Players tab) or the Platform API, additional runtime customization is achievable using client-side parameters. They allow you to specify additional Player behavior or pass in required values to a specific Player embed.
In the example below, we’re adding the following runtime parameters to the existing Player config defined in the {Player ID} placeholder:
startTime=15
: video will start playing from second 15mute=true
: video will start muted
Find all available runtime parameters in the Android SDK Reference.
val playerParameters = PlayerParameters(
startTime = 15,
mute = true,
defaultFullscreenOrientation = Orientation.Portrait // Set the default fullscreen orientation to portrait
)
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playlistId = "A_PLAYLIST_ID", // replace by desired playlist id
playerParameters = playerParameter,
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
}
)
Use methods
Methods enable you to initialize and control Players programmatically. Find all available methods in the Android SDK Reference.
Example to initialize a Player:
You can initialize a Player on your app using the createPlayer()
method and include your Player ID, Video ID and any other element you need.
val playerParameters = PlayerParameters(
mute = false,
)
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playlistId = "A_PLAYLIST_ID", // replace by desired playlist id
playerParameters = playerParameter,
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
playerListener = object : PlayerListener {
...
}
videoListener = object : VideoListener {
...
}
adListener = object : AdListener {
...
}
)
Manage event listeners
Pass object implementing interface PlayerListener
, VideoListener
, AdListener
to Dailymotion.create(...)
method to listen to Player, Video, Ad events.
Find all available events in the Android SDK Reference.
Player events
To listen to Player events, pass an object implementing PlayerListener
interface to Dailymotion.createPlayer(...)
.
PlayerListener
interface provide an empty default implementation for all its method. This allows overriding / implementation of only wanted method instead of implementing all methods just for compilation sake (it also improve code readability).
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
playerListener = object : PlayerListener {
...
}
)
For example, to listen to onPlayerEnd
event, just implement the method onPlayerEnd()
:
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
playerListener = object : PlayerListener {
override fun onPlayerEnd(playerView: PlayerView) {
// player end event
}
}
)
Video events
To listen to Video events, pass an object implementing VideoListener
interface to Dailymotion.createPlayer(...)
.
VideoListener
interface provide an empty default implementation for all its method. This allows overriding / implementation of only wanted method instead of implementing all methods just for compilation sake (it also improve code readability).
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
videoListener = object : VideoListener {
...
}
)
For example, to listen to onVideoEnd
event, just implement the method onVideoEnd
():
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
videoListener = object : VideoListener {
override fun onVideoEnd(playerView: PlayerView) {
// video end event
}
}
)
Ad events
To listen to Ad events, pass an object implementing AdListener
to Dailymotion.createPlayer(...)
.
AdListener
interface provide an empty default implementation for all its method. This allows overriding / implementation of only wanted method instead of implementing all methods just for compilation sake (it also improve code readability).
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
adListener = object : AdListener {
...
}
)
For example, to listen to onAdStart
event, just implement the method onAdStart
():
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
....
},
adListener = object : AdListener {
override fun onAdStart(playerView: PlayerView, type: String, position: String) {
// ad start event
}
}
)
Retrieve Player state
To retrieve the player state, pass an object implementing PlayerView.PlayerStateCallback
to PlayerView#queryPlayerState(...)
method.
playerView.queryPlayerState(object: PlayerView.PlayerStateCallback {
fun onPlayerStateReceived(playerView: PlayerView, playerState: PlayerEvent.PlayerState)
// Use playerState
}
)
Find all available states in the Android SDK Reference.
Implement fullscreen
The Android SDK provides an out-of-the-box fullscreen implementation supporting navigation stack using either Android standard FragmentManager
or Android Jetpack Navigation library
.
The out-of-the-box implementation handles:
- Orientation change: portrait, reverse portrait, landscape and reverse landscape
- Native back button support: fullscreen can be exited when user taps on the device software / physical back button or by tapping on the exit fullscreen button from the player controls
- Fullscreen will start in landscape mode
PlayerView
controls button fullscreen state change from enter fullscreen icon from/to exit fullscreen icon
Sample applications showcasing implementation of fullscreen are available here: https://github.com/dailymotion/player-sdk-android-samples
Out-of-the-box implementation
To use the out-of-the-box implementation:
- Make the device rotation a configuration change.
Add the following code to the<activity>
tag of theActivity
hosting thePlayerView
in theAndroidManifest.xml
file.
android:configChanges="orientation|screenSize"
It’s more efficient to handle the orientation change as a device configuration change. This keeps the Activity
instantiated and only invalidate the Activity
layout.
Be sure to re-use the created PlayerView
and avoid creating a new PlayerView
on a state change: this will optimize the device battery life, bandwidth and memory consumption.
To handle correctly state management refer to: https://developer.android.com/topic/libraries/architecture/saving-states
- Pass an object implementing
PlayerListener.onFullscreenRequested(playerDialogFragment: DialogFragment)
method.
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
},
playerListener = object : PlayerListener {
override fun onFullscreenRequested(playerDialogFragment: DialogFragment) {
// Show the playerDialogFragment on screen
}
}
)
The code to display playerDialogFragment
on screen will depend on the navigation stack used by the application. See the 2 available options below: Using FragmentManager
or using Android JetPack Navigation
.
Using FragmentManager
If the application is using FragmentManager
, display playerDialogFragment
like a standard android dialog fragment.
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
},
playerListener = object : PlayerListener {
override fun onFullscreenRequested(playerDialogFragment: DialogFragment) {
// Show the playerDialogFragment on screen
playerDialogFragment.show(this@MainActivity.supportFragmentManager, "dmPlayerFullscreenFragment")
}
}
)
Using Android Jetpack Navigation
If the application is using Android Jetpack Navigation library
, you will need to add the fullscreen dialog fragment to navigation graph before being able to navigate to it.
1. Add fullscreen dialog fragment to navigation graph
- Add the fullscreen dialog fragment to your navigation graph file:
<dialog
android:id="@+id/FullscreenPlayerWebViewFragment" android:name="com.dailymotion.player.android.sdk.webview.fullscreen.FullscreenPlayerWebViewDialogFragment"
android:label="FullscreenPlayerWebViewFragment"
tools:layout="@layout/dm_sdk_fragment_dialog_fullscreen_player_webview" />
- Add the
navigation action
to display the fullscreen dialog fragment inside the hosting fragment. Be sure insert the correct value of theaction id
attribute.
<action android:id="action_MainFragment_to_FullscreenPlayerWebViewFragment"
app:destination="@id/FullscreenPlayerWebViewFragment" />
The resulting navigation graph file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/MainFragment">
<fragment
android:id="@+id/MainFragment"
android:name="com.dailymotion.player.android.jetpackfullscreen.MainFragment"
android:label="@string/fragment_main_label"
tools:layout="@layout/fragment_main">
<!-- Action to Fullscreen dialog fragment -->
<action android:id="@+id/action_MainFragment_to_FullscreenPlayerWebViewFragment"
app:destination="@id/FullscreenPlayerWebViewFragment" />
</fragment>
<!-- Fullscreen dialog fragment -->
<dialog
android:id="@+id/FullscreenPlayerWebViewFragment" android:name="com.dailymotion.player.android.sdk.webview.fullscreen.FullscreenPlayerWebViewDialogFragment"
android:label="FullscreenPlayerWebViewFragment"
tools:layout="@layout/dm_sdk_fragment_dialog_fullscreen_player_webview" />
</navigation>
2. Display fullscreen dialog fragment
To display the fullscreen dialog fragment, use the action
generated by Android Jetpack Navigation library
:
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
},
playerListener = object : PlayerListener {
override fun onFullscreenRequested(playerDialogFragment: DialogFragment) {
// Show the playerDialogFragment on screen
findNavController()
.navigate(MainFragmentDirections.actionMainFragmentToFullscreenPlayerWebViewFragment())
}
}
)
Custom implementation
To implement a custom fullscreen, pass an object implementing both PlayerListener.onFullscreenRequested(playerDialogFragment: DialogFragment)
and PlayerListener.onFullscreenExit(playerView: PlayerView)
methods:
Dailymotion.createPlayer(
context = context,
playerId = "MY_PLAYER_ID", // replace by desired player id
videoId = "A_VIDEO_ID", // replace by desired video id
playerSetupListener = object : Dailymotion.PlayerSetupListener {
override fun onPlayerSetupSuccess(player: PlayerView) {
// Add PlayerView to view hierarchy
}
override fun onPlayerSetupFailed(error: PlayerError) {
// PlayerView setup failed
}
},
playerListener = object : PlayerListener {
override fun onFullscreenRequested(playerDialogFragment: DialogFragment) {
super.onFullscreenRequested(playerDialogFragment)
// Resize PlayerView to take whole screen space
// Notify PlayerView that we entered fullscreen: this will change PlayerView fullscreen button state.
playerView.notifyFullscreenChanged()
}
override fun onFullscreenExit(playerView: PlayerView) {
super.onFullscreenExit(playerView)
// Resize PlayerView to take whole screen space
// Notify PlayerView that we exited fullscreen: this will change PlayerView fullscreen button state.
playerView.notifyFullscreenChanged()
}
}
)
A call to playerView.notifyFullscreenChanged()
is necessary after entering or exiting fullscreen to update the PlayerView
controls fullscreen button state.
Programmatic trigger
By default, fullscreen behaviour is triggered when an user taps on the fullscreen button from the Player controls. The SDK allows fullscreen behaviour to be triggered programatically by using playerView#setFullscreen(...)
method.
playerView.setFullscreen(fullscreen = true) // Enter fullscreen
playerView.setFullscreen(fullscreen = false) // Exit fullscreen
playerView.setFullscreen(fullscreen = true, orientation = Orientation.Portrait) // Enter fullscreen in portrait
By default, fullscreen orientation is Landscape but it can be changed while creating PlayerView
by setting the runtime parameter defaultFullscreenOrientation
to another available value within the PlayerParameters
object. Check the dedicated guide to see how to use runtime parameters on the Android SDK.
Implement Chromecast
The Dailymotion Cast SDK allows you to easily integrate a casting feature on your Dailymotion Player with minimum requirements.
Prerequisites
- Google Cast SDK for Android must be integrated as the Dailymotion Cast SDK relies on it
- Your Player must be integrated using our Android SDK
1. Add Cast SDKs dependencies
Add Dailymotion Cast SDK and Google Cast SDK dependencies in your build.gradle
:
dependencies {
...
implementation 'com.dailymotion.player.android:cast:1.2.7'
implementation 'androidx.mediarouter:mediarouter:1.6.0'
implementation 'com.google.android.gms:play-services-cast-framework:21.4.0'
...
}
In addition to those dependencies, you may need to include additional dependencies needed by the Google Cast SDK. Please check Google Cast documentation to make sure to include them all.
2. Create an Expanded Controller
To improve the casting experience, create an expanded controller using Google Cast SDK’s widget ExpandedControlsActivity
.
Refer to Google Cast SDK documentation to see this step in more details.
You can create a simple ExpandedControlsActivity
as shown below:
package com.dailymotion.sample.player.sdk.cast
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import android.view.Menu
import com.dailymotion.sample.player.sdk.R
import com.google.android.gms.cast.framework.CastButtonFactory
/**
* An example of extending [ExpandedControllerActivity] to add a cast button.
*/
class ExpandedControlsActivity : ExpandedControllerActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.menu_cast_expanded_controller, menu)
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
return true
}
}
With menu_cast_expanded_controller
being:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/media_route_menu_item"
android:orderInCategory="101"
android:title="@string/cast_media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always" />
</menu>
3. Modify your CastOptionsProvider
In your CastOptionsProvider
class used to create the OptionsProvider
, call DailymotionCast.castOptionsBuilder()
to get a pre-built CastOptions.Builder
that already includes a receiver application id.
An example CastOptionsProvider
using our Dailymotion Cast SDK would look like this:
package com.dailymotion.sample.player.sdk.cast
import android.content.Context
import com.dailymotion.player.android.sdk.cast.DailymotionCast
import com.google.android.gms.cast.LaunchOptions
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.SessionProvider
import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.MediaIntentReceiver
import com.google.android.gms.cast.framework.media.NotificationOptions
class CastOptionsProvider : OptionsProvider {
override fun getCastOptions(context: Context): CastOptions {
val buttonActions = listOf(
MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK,
MediaIntentReceiver.ACTION_STOP_CASTING
)
// Showing "play/pause" and "stop casting" in the compat view of the notification.
val compatButtonActionsIndices = intArrayOf(0, 1)
// Use our sample ExpandedControlsActivity
val notificationOptions = NotificationOptions.Builder()
.setActions(buttonActions, compatButtonActionsIndices)
.setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
// Use our sample ExpandedControlsActivity
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
val launchOptions = LaunchOptions.Builder()
.setAndroidReceiverCompatible(true)
.build()
// Call DailymotionCast.castOptionsBuilder() to have a pre-built CastOptions.Builder
// with an already set receiver application id
return DailymotionCast.castOptionsBuilder()
.setLaunchOptions(launchOptions)
.setCastMediaOptions(mediaOptions)
.build()
}
override fun getAdditionalSessionProviders(context: Context): MutableList<SessionProvider>? {
return null
}
}
4. Add Cast button
The Dailymotion Cast SDK handles communication between a casting device and the Dailymotion Player. However, in order to initiate a casting session, you need to add a Cast button in the UI.
Refer to the Google Cast SDK documentation to see how to add a Cast button.
5. Customize the UI (Optional)
If you want to customize the appearance of the Cast button, Mini Controller and Expanded Controller, please refer to the Google Cast SDK documentation to customize the UI.
Destroy/Release the Player
The Player instance can be automatically destroyed by the Android System garbage collector by setting the Player view to null
or by removing all references to the Player.
However, in some cases, the Android garbage collector may take some time to run, you can manually destroy the Player using the destroy
method.
After invoking PlayerView#destroy()
, PlayerView
object will become useless since the underlying Player is destroyed. All PlayerView
method calls will then result in doing nothing except printing a log in Logcat to warn about illegal usage of a destroyed Player:
“Tried to perform command with a destroyed player. Ignoring command.”
To invoke PlayerView#destroy()
method, simply call it:
playerView.destroy()