Introduction
This book describes how to work with AdPlayer Lite library.
Tags
AdPlayer Lite library works with publishers and tags. Publisher is a unique ID for the whole organization, while Tag is a placement configration on the screen. There can be any number of tags but only one publisher.
Tags can be created and configured by using the admin console.
Types of Tags
Tags can be split into to categories:
- Outstream - displays only a series of Ads
- Instream - displays video content interleaved with Ads
Running Example App
Running example application requires publisher
and tag
ids. They can be configured in the root local.properties
file like this:
sdk.dir=...
av_pub_id={published id goes here}
av_tag_id={tag id goes here}
After this project can simply be opened in the Android Studio and built.
Project Configuration
Before using AdPlayer Lite library project must be properly configured.
- Add Maven repository to
settings.gradle.kts
:
dependencyResolutionManagement {
repositories {
maven("https://us-central1-maven.pkg.dev/mobile-sdk-fd2e4/adservr-maven")
}
}
- Add library dependencies to the app's module
build.gradle.kts
:
dependencies {
implementation("com.adservrs:ad-player-lite:1.0.0")
}
- Add GMS configuration to the
AndroidManifest.xml
:
<application>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-6746653557725812~6678258028" />
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
android:value="true" />
<meta-data
android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
android:value="true" />
</application>
Now your project is configured and you can move to creating first in-read placement.
Creating In-Read Placement
Creating AdPlayerView
AdPlayerView
is the main View
that is responsible for displaying in-read ads.
This view can be added via code:
val view = AdPlayerView(context)
view.load(pubId = "PUBLISHER_ID", tagId = "TAG_ID")
addView(view)
Or though the layout xml files:
<com.adservrs.adplayer.lite.AdPlayerView
android:id="@+id/ad_player"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
It is not possible to load content from the xml file so it is still required to call AdPlayerView.load
from the code.
Releasing AdPlayerView
AdPlayerView
will try its best to release all used resources when GC-ed but it is highly recommended to explicitly release it to avoid unwanted side-effects:
val view: AdPlayerView = TODO()
view.release()
Releasing AdPlayerView
will immediately free all used resources (including attached AdPlayerInReadController
).
Layout Contract
AdPlayerView
will strictly follow any measuring specs provided. View will try to fit 16/9 video and any required decorations (like labels, close buttons, etc.) into given constraints.
In case both width
and height
constraint are unbounded it will fallback to the predefined hard-coded size.
Creating In-Read Placement
Creating AdPlayerView
AdPlayerView
is the main View
that is responsible for displaying in-read ads.
This view can be added via code:
val view = AdPlayerView(context)
view.load(pubId = "PUBLISHER_ID", tagId = "TAG_ID")
addView(view)
Or though the layout xml files:
<com.adservrs.adplayer.lite.AdPlayerView
android:id="@+id/ad_player"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
It is not possible to load content from the xml file so it is still required to call AdPlayerView.load
from the code.
Releasing AdPlayerView
AdPlayerView
will try its best to release all used resources when GC-ed but it is highly recommended to explicitly release it to avoid unwanted side-effects:
val view: AdPlayerView = TODO()
view.release()
Releasing AdPlayerView
will immediately free all used resources (including attached AdPlayerInReadController
).
Layout Contract
AdPlayerView
will strictly follow any measuring specs provided. View will try to fit 16/9 video and any required decorations (like labels, close buttons, etc.) into given constraints.
In case both width
and height
constraint are unbounded it will fallback to the predefined hard-coded size.
Launching Interstitials
Unlike in-read mode, interstitials don't require any placement view. Instead the are always displayed in fullscreen. Interstitials, unlike regular fullscreen, will also be automatically closed after the first video finishes.
Creating Interstitial Controller
An AdPlayerInterstitialController
must be created before launching interstitial:
val tag = AdPlayer.getTag(context, pubId = "...", tagId = "...")
val controller: AdPlayerInterstitialController = tag.newInterstitialController()
Additional configuration can also be provided during creation if needed:
val controller: AdPlayerInterstitialController = tag.newInterstitialController {
// change background color of the window
backgroundColor = Color.BLACK
// disable back buttons/gestures so interstitial cannot be skipped
dismissOnBack = false
// this callback will be triggered when interstitial is closed
onDismissListener = {
Log.d("TAG", "Interstitial was closed")
}
}
Some of these configurations above can be also configured on the admin portal. Values provided though the code will always override portal configuration.
Releasing Interstitial Controller
AdPlayerInterstitialController
, like any other controller, must be always released when no longer needed to release underlying resources:
val controller: AdPlayerInterstitialController = TODO()
controller.release()
Launching or Dismissing Interstitial
Interstitial can be launched after creating AdPlayerInterstitialController
:
val controller: AdPlayerInterstitialController = TODO()
controller.launchInterstitial()
Interstitial can also be forcibly closed if needed:
val controller: AdPlayerInterstitialController = TODO()
controller.dismissInterstitial()
It is important to remember that each controller can at most launch one interstitial at the same time.
Controlling Playback
What is Controller?
Controller is the main entity responsible for loading and controlling (pausing, skipping, unmuting, etc.) a content. All controllers inherit AdPlayerController
, which provides most common functionality.
There are also more specialized controllers available:
AdPlayerInReadController
- for working with in-read contentAdPlayerInterstitialController
- for displaying interstitials
Creating Controller
There are few ways to get controller instance:
- When loading content via
AdPlayerView
:
val view: AdPlayerView
val controller: AdPlayerInReadController = view.load(...)
- Reading already loaded controller from
AdPlayerView
:
val view: AdPlayerView
val controller: AdPlayerInReadController? = view.controller
- Creating controller manually:
val tag = AdPlayer.getTag(context, pubId = "...", tagId = "...")
val controller: AdPlayerInReadController = tag.newInReadController()
// or
val controller: AdPlayerInReadController = tag.newInterstitialController()
Releasing Controller
All controllers must be always released when no longer needed to free underlying resources:
val controller: AdPlayerController
controller.release()
In cases when AdPlayerInReadController
is attached to the AdPlayerView
, it will be automatically released with the view itself.
Controlling Video Playback
Most basic functionality, that controllers allow, is to control video playback:
val controller: AdPlayerController
// pause playback
controller.pause()
// resume playback
controller.resume()
// skip current Ad
controller.skipAd()
AdPlayerInReadController
also provides additional functinality:
val controller: AdPlayerInReadController
// toggle fullscreen mode
controller.toggleFullscreen()
Listening for State Changes / Events
One of the things controller provides is ability to listen for state changes and events:
val controller: AdPlayerController
// reading current state
Log.d("TAG", "Currect state is ${controller.state.value}")
// listening for state changes
coroutineScope.launch {
controller.state.collect {
if (it is AdPlayerState.Playing) {
Log.d("TAG", "AdPlayer started a playback")
}
}
}
// listening for events
coroutineScope.launch {
controller.events.collect {
if (it is AdPlayerEvent.AdImpression) {
Log.d("TAG", "Ad impressions was triggered")
}
}
}
Content and Playlist
Both content and playlists are only available for insteam tags.
Managing Playlist
Playlist contains list of content videos that are played one after the other. We can read current playlist like this:
val controller: AdPlayerController
val playlist = controller.playlist.value
Log.d("TAG", "playlist is $playlist")
One important note here is that playlist is loaded by the library asynchronously and might not be available right after the controller is created. This might result in the above API returning empty playlist. It is adviced, in most cases, for the application to track when playlist changes:
val controller: AdPlayerController
coroutineScope.launch {
controller.playlist.collect {
Log.d("TAG", "new playlist is $it")
}
}
Currently Played Content
AdPlayerController
can be used to track which content is currently playing:
val controller: AdPlayerController
// reading current content
Log.d("TAG", "${controller.content.value} is currently playing")
// tracking content changes
coroutineScope.launch {
controller.content.collect {
Log.d("TAG", "$it is now playing")
}
}
// reading playback progress
coroutineScope.launch {
val position = controller.getContentPosition()
val duration = controller.getContentDuration()
Log.d("TAG", "content at $position / $duration")
}
Choosing Content to Play
In order to play different video from the playlist we can use these functions:
val controller: AdPlayerController
// play next video
controller.playNextContent()
// play previous video
controller.playPrevContent()
// play specific video
controller.playContentByIndex(3)