Video Advertisements
A video ad (InStream Video Ad) is an advertisement form that is inserted before, during, or after the video content playback.
This page is a usage guide to GfpVideoAdScheduleManager
(VSM), a video schedule manager for calling pre/during/post advertisements.
The Player in which the video advertisement will be played is injected with the Player used by the service.
Please refer to player settings.
[Step 1] Add Dependency
- Kotlin DSL
- Groovy
dependencies {
implementation(platform("com.naver.gfpsdk:nam-bom:8.1.0"))
implementation("com.naver.gfpsdk:nam-core")
implementation("com.naver.gfpsdk:nam-ndavideo") // Naver InStream ads extension
}
dependencies {
implementation platform('com.naver.gfpsdk:nam-bom:8.1.0')
implementation 'com.naver.gfpsdk:nam-core'
implementation 'com.naver.gfpsdk:nam-ndavideo' // Naver InStream ads extension
}
[Step 2] Add ViewGroup that can contain Player layout
To display a video ad, a ViewGroup for the section where the video advertisement and the main video can be played must be added to the Activity or Fragment layout where the advertisement will be displayed.
In the example below, a video ad declared a Layout in the RelativeLayout ViewGroup with the ID video_ad_container
.
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/video_ad_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:layout_constraintDimensionRatio="16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
[Step 3] Create a layout to include the Player and advertising UI
Declare a layout to contain the Player (AdVideoPlayer must be implemented) and the advertising UI that is required to play video ads.
Below is an example of a layout that includes a frame layout with a player and advertising UI.
The created ad_video_player
and ad_ui_container
will be used in the creator of the ad loader, GfpVideoAdScheduleManager
.
Let’s name the xml file created below as video_ad_exoplayer_layout.xml
.
The outer_text_ad_container
is the section used for reminder advertisements which is used in SMR advertisements. It will be set separately as follows.
videoAdScheduleManager.setOuterRemindTextAdViewContainer(outerTextAdContainer);
However, it will not be used in this sample.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.naver.gfpsdk.adssample.video.SampleExoPlayerView
android:id="@+id/ad_video_player"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true" />
<FrameLayout
android:id="@+id/ad_ui_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/outer_text_ad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
[Step 4] Create AdParam and VideoAdScheduleParam
Configure advertising parameters (AdParam
) and schedule parameters (VideoAdScheduleParam
) for video ad requests.
4-1. AdParam
Refer to the ad request information to create AdParam for the ad request.
Unlike other advertisements, Ad Unit ID is not a required value. However, video-related parameters will be required. Please refer to the video-related parameters on the ‘AdParam’ information page above.
When configuring AdParam, the setAdUnitId setting is not required. If set, it will be ignored.
4-2 VideoAdScheduleParam
- Content length (
contentDuration
)
A required input value. The schedule operates only if it is entered accurately in seconds.
- Schedule ID(
adScheduleId
)
A required value that must be informed in advance by a NAM manager.
- Set schedule policy(
setAdSchedulePolicy
)
Pre/during/post advertisements can be selectively excluded.
As an additional value, each schedule ID has a policy set by the NAM Admin.
Although it is set by the Admin, it is used when the service wants it to be off.
- (For live content) Content starting point(
setContentStartOffset
)
The advertising schedule offset is adjusted based on the content start time.
- Kotlin
- Java
val adParam = AdParam.Builder()
.build()
val contentDuration = 653L // content duration with seconds
val adScheduleId = "NDP_ADSCHDL" // like a Ad Unit ID, need to get from GFP Admin
val pre = true
val mid = false // no ad in middle
val post = true
val videoAdScheduleParam = VideoAdScheduleParam.Builder(adScheduleId)
.setDuration(contentDuration)
.setAdSchedulePolicy(pre, mid, post)
.setAdNoticeDurationSec(5)
.build()
AdParam adParam = new AdParam.Builder()
.build();
long contentDuration = 653L; // content duration with seconds
String adScheduleId = "NDP_ADSCHDL"; // like a Ad Unit ID, need to get from GFP Admin
boolean pre = true;
boolean mid = false; // no ad in middle
boolean post = true;
VideoAdScheduleParam videoAdScheduleParam = new VideoAdScheduleParam.Builder(adScheduleId)
.setDuration(contentDuration)
.setAdSchedulePolicy(pre, mid, post)
.setAdNoticeDurationSec(5)
.build();
4-3 Set video advertising options
Set video ad options through GfpVideoAdScheduleManager
setVideoAdOptions()
The support for bitrateKbps
, videoLoadTimeout(ms)
, and hls can be set in GfpVideoAdOptions.
-
By default, hls is not supported.
(Only supports video/mp4)
-
BitrateKbps determines the ad quality.
The default value is -1. The advertisement is played with auto-play for IMA and with the lowest resolution (if HLS is not supported) for NAVER ads.
-
videoLoadTimeout generates an error if the actual playback does not occur until the specified time after the playback start request.
The default is 5 seconds (5000ms)
- Kotlin
- Java
val videoAdOptions = GfpVideoAdOptions().apply {
supportedStreamingHLS = false
bitrateKbps = -1
videoLoadTimeout = 5000
}
videoAdManager.setVideoAdOptions(videoAdOptions)
GfpVideoAdOptions videoAdOptions = new GfpVideoAdOptions();
videoAdOptions.setSupportedStreamingHLS(false);
videoAdOptions.setBitrateKbps(-1);
videoAdOptions.setVideoLoadTimeout(5000);
videoAdManager.setVideoAdOptions(videoAdOptions);
[Step 5] Create GfpVideoAdScheduleManager
Create GfpVideoAdScheduleManager
for calling video ads.
Transmit the advertising parameters (AdParam) and schedule parameters (VideoAdScheduleParam
) set above to the GfpVideoAdScheduleManager
creator.
Additionally, inflate the layout created above. Then, add it to the video_ad_container
created to include the player layout.
Please refer to the ad loading below for an example.
[Step 6] Receive schedule events
Video advertisement schedule events can be received through the VideoAdScheduleListener
interface.
Since an event is processed per the video advertisement schedule, the start/end of the content must be processed through the corresponding listener when the advertisement starts/ends.
Once the ad is loaded, the video will pause. When processing an error in the advertisement video, it must be processed so that the video plays.
- Kotlin
- Java
videoAdScheduleManager.setAdScheduleListener(object: VideoAdScheduleListener {
override fun onScheduleLoaded(schedule: VideoScheduleResponse) {
// ad schedule is loaded
}
override fun onContentResumeRequest() {
// time to resume the content (not an ad)
}
override fun onContentPauseRequest() {
// time to pause the content
}
override fun onScheduleCompleted() {
// every ad on scedule are finished
}
override fun onError(error: GfpError) {
// schedule request is failed
}
})
videoAdScheduleManager.setAdScheduleListener(new VideoAdScheduleListener() {
@Override
public void onScheduleLoaded(VideoScheduleResponse schedule) {
// ad schedule is loaded
}
@Override
public void onContentResumeRequest() {
// time to resume the content (not an ad)
}
@Override
public void onContentPauseRequest() {
// time to pause the content
}
@Override
public void onScheduleCompleted() {
// every ad on scedule are finished
}
@Override
public void onError(GfpError error) {
// schedule request is failed
}
});
[Step 7] Receiving advertising events
Events about the life cycle of a video ad (loading, playback preparation, playback, preparation for non-linear ads, click, completion of playback, and error) can be received through the VideoAdListener
interface.
- Kotlin
- Java
videoAdScheduleManager.setAdListener(object: VideoAdListener {
override fun onAdLoaded(ad: GfpVideoAd) {
// single ad loaded successfully
}
override fun onAdStartReady(ad: GfpVideoAd) {
// need to play ad
}
override fun onAdStarted(ad: GfpVideoAd) {
// ad is started
}
override fun onAdNonLinearStartReady(ad: GfpVideoAd) {
// time to show non-linear ad
}
override fun onAdClicked(ad: GfpVideoAd) {
// ad is clicked
}
override fun onAdCompleted(ad: GfpVideoAd) {
// ad is finished
}
override fun onError(ad: GfpVideoAd, error: GfpError) {
// load/play error
}
})
videoAdScheduleManager.setAdListener(new VideoAdListener() {
@Override
public void onAdLoaded(GfpVideoAd ad) {
// single ad loaded successfully
}
@Override
public void onAdStartReady(GfpVideoAd ad) {
// need to play ad
}
@Override
public void onAdStarted(GfpVideoAd ad) {
// ad is started
}
@Override
public void onAdNonLinearStartReady(GfpVideoAd ad) {
// time to show non-linear ad
}
@Override
public void onAdClicked(GfpVideoAd ad) {
// ad is clicked
}
@Override
public void onAdCompleted(GfpVideoAd ad) {
// ad is finished
}
@Override
public void onError(GfpVideoAd ad, GfpError error) {
// load/play error
}
});
7-1. About Quality of Experience (QOE)
Detailed events related to video ad playback can be received through setQoeListener of GfpVideoAdScheduleManager.
- Kotlin
- Java
videoAdManager.setQoeListener(object: GfpVideoAdQoeListener {
override fun onAdLoaded(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", String.format("GfpVideoAdQoeListener.onAdLoaded \tinfo:\n\t\tplacement: %s\n\t\tprovider: %s \n\t\tmedia_h: %d\n\t\tmedia_w: %d \n\t\tcurrent time: %f\n\t\tduration: %f\n\t\toffset: %f",
info.placementType,
info.provider,
info.mediaHeight,
info.mediaWidth,
info.currentTime,
info.duration,
info.skipOffset
))
}
override fun onAdStarted(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdStarted")
}
override fun onAdPaused(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdPaused")
}
override fun onAdSkipped(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdSkipped")
}
override fun onAdResumed(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdResumed")
}
override fun onAdClicked(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdClicked")
}
override fun onAdCompleted(info: GfpVideoAdQoeInfo) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdCompleted")
}
override fun onError(error: GfpError) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onError")
}
})
videoAdManager.setQoeListener(new GfpVideoAdQoeListener() {
@Override
public void onAdLoaded(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", String.format("GfpVideoAdQoeListener.onAdLoaded \tinfo:\n\t\tplacement: %s\n\t\tprovider: %s \n\t\tmedia_h: %d\n\t\tmedia_w: %d \n\t\tcurrent time: %f\n\t\tduration: %f\n\t\toffset: %f",
info.getPlacementType(),
info.getProvider(),
info.getMediaHeight(),
info.getMediaWidth(),
info.getCurrentTime(),
info.getDuration(),
info.getSkipOffset()
));
}
@Override
public void onAdStarted(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdStarted");
}
@Override
public void onAdPaused(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdPaused");
}
@Override
public void onAdSkipped(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdSkipped");
}
@Override
public void onAdResumed(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdResumed");
}
@Override
public void onAdClicked(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdClicked");
}
@Override
public void onAdCompleted(GfpVideoAdQoeInfo info) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onAdCompleted");
}
@Override
public void onError(GfpError error) {
Log.d("MainActivity", "GfpVideoAdQoeListener.onError");
}
});
[Step 8] Timeout settings
Set a timeout for each ad request through GfpVideoAdScheduleManager
.
If a separate timeout is not set through the GfpVideoAdScheduleManager
object, the default value will be the global settings of SdkProperties
(default: 60 seconds).
If the setting is not selected, the default value will use the global settings (Default: 60 seconds) through SdkProperties
.
- Kotlin
- Java
videoAdScheduleManager.setGfpVideoProperties(GfpVideoProperties(60_000L, null))
videoAdScheduleManager.setGfpVideoProperties(new GfpVideoProperties(60_000L, null));
[Step 9] Loading advertisement (Sample)
Advertisements can be loaded once the settings for GfpVideoAdScheduleManager have been completed.
The following is an example of how to load an advertisement in the onCreate() method of Activity.
- Kotlin
- Java
package ...
import ...
class MainActivity : AppCompatActivity() {
private lateinit var playerContainer: RelativeLayout
private lateinit var adVideoPlayer: AdVideoPlayer
private lateinit var videoAdScheduleManager: GfpVideoAdScheduleManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
playerContainer = findViewById(R.id.video_ad_container)
// When using VSM, setAdUnitId is not needed.
val adParam = AdParam.Builder().build()
// do inflate video_ad_exoplayer_layout
val playerLayout = layoutInflater.inflate(R.layout.video_ad_exoplayer_layout, null, false)
// Sample player for test
val exoPlayerView = playerLayout.findViewById<SampleExoPlayerView>(R.id.ad_video_player)
val adUiContainer = playerLayout.findViewById<FrameLayout>(R.id.ad_ui_container)
// assume that SampleExoPlayerView has AdVideoPlayer
adVideoPlayer = exoPlayerView.createAdVideoPlayer("YOUR_CONTENTS_URL")
// Schedule Param setting
val contentDuration: Long = ***L // content duration with seconds
val adScheduleId = "VIDEO_AD_SCHEDULE_ID"
val videoAdScheduleParam = VideoAdScheduleParam.Builder(adScheduleId)
.setDuration(contentDuration)
.setAdSchedulePolicy(true, false, true)
.setAdNoticeDurationSec(5)
.build()
// create manager
videoAdScheduleManager = GfpVideoAdScheduleManager(
this,
videoAdScheduleParam,
adParam,
adVideoPlayer,
adUiContainer
)
val videoAdOptions = GfpVideoAdOptions()
videoAdOptions.setSupportedStreamingHLS(true)
videoAdScheduleManager.setVideoAdOptions(videoAdOptions)
/**
* if you need the QOE
videoAdScheduleManager.setQoeListener(object: GfpVideoAdQoeListener {
override fun onAdLoaded(info: GfpVideoAdQoeInfo) {
...
}
...
})
*/
videoAdScheduleManager.setAdScheduleListener(object: VideoAdScheduleListener {
override fun onScheduleLoaded(schedule: VideoScheduleResponse) {
Log.d("MainActivity", String.format("onScheduleLoaded - AdBreak size: %d", schedule.adBreaks.size))
}
override fun onContentResumeRequest() {
Log.d("MainActivity", "play the content")
// 본 영상 재생
if (exoPlayerView.isPlaying.not()) {
exoPlayerView.resumeContentsRequest()
}
}
override fun onContentPauseRequest() {
Log.d("MainActivity", "pause the content")
exoPlayerView.pauseContentsRequest()
}
override fun onScheduleCompleted() {
Log.d("MainActivity", "all ads are finished in schedule")
if (exoPlayerView.isPlaying.not()) {
exoPlayerView.resumeContentsRequest()
}
}
override fun onError(gfpError: GfpError) {
Log.d("MainActivity", "schedule load is failed Error: $gfpError")
if (exoPlayerView.isPlaying.not()) {
exoPlayerView.resumeContentsRequest()
}
}
})
videoAdScheduleManager.setAdListener(object: VideoAdListener {
override fun onAdLoaded(ad: GfpVideoAd) {
// NonLinearAdInfo nonLinearAdInfo = ad.getNonLinearAdInfo();
// can check the remind
Log.d("MainActivity", "onAdLoaded()\tResponseInfo: ${ad.responseInfo}")
}
override fun onAdStartReady(ad: GfpVideoAd) {
ad.start(true) // have to call this
Log.d("MainActivity", "time to start ad")
}
override fun onAdNonLinearStartReady(ad: GfpVideoAd) {
Log.d("MainActivity", "show the Non Linear")
ad.showNonLinearAd(GfpNonLinearAdView.ContainerType.INNER)
}
override fun onAdStarted(ad: GfpVideoAd) {
Log.d("MainActivity", "ad is started")
}
override fun onAdClicked(ad: GfpVideoAd) {
Log.d("MainActivity", "ad is clicked")
}
override fun onAdCompleted(ad: GfpVideoAd) {
Log.d("MainActivity", "ad is finished")
// 본 영상 재생
if (exoPlayerView.isPlaying.not()) {
exoPlayerView.resumeContentsRequest()
}
}
override fun onError(ad: GfpVideoAd, error: GfpError) {
Log.e("MainActivity", "error\t" +
String.format(
"code[%d] subCode[%s] message[%s] responseInfo[%s]",
error.errorCode,
error.errorSubCode,
error.errorMessage,
ad.responseInfo.toString()
)
)
if (!exoPlayerView.isPlaying) {
exoPlayerView.resumeContentsRequest()
}
}
})
playerContainer.addView(playerLayout)
videoAdScheduleManager.load()
}
override fun onPause() {
super.onPause()
if (::videoAdScheduleManager.isInitialized) {
videoAdScheduleManager.pause()
}
}
override fun onResume() {
super.onResume()
if (::videoAdScheduleManager.isInitialized) {
videoAdScheduleManager.resume()
}
}
override fun onDestroy() {
super.onDestroy()
if (::videoAdScheduleManager.isInitialized) {
videoAdScheduleManager.destroy()
}
}
}
package ...
import ...
public class MainActivity extends AppCompatActivity {
private RelativeLayout playerContainer;
private AdVideoPlayer adVideoPlayer;
private GfpVideoAdScheduleManager videoAdScheduleManager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerContainer = findViewById(R.id.video_ad_container);
// When using VSM, setAdUnitId is not needed.
AdParam adParam = new AdParam.Builder().build();
// do inflate video_ad_exoplayer_layout
View playerLayout = getLayoutInflater().inflate(R.layout.video_ad_exoplayer_layout, null, false);
// Sample player for test
SampleExoPlayerView exoPlayerView = playerLayout.findViewById(R.id.ad_video_player);
FrameLayout adUiContainer = playerLayout.findViewById(R.id.ad_ui_container);
// assume that SampleExoPlayerView has AdVideoPlayer
adVideoPlayer = exoPlayerView.createAdVideoPlayer("YOUR_CONTENTS_URL");
// Schedule Param setting
long contentDuration = ***L; // content duration with seconds
String adScheduleId = "VIDEO_AD_SCHEDULE_ID";
VideoAdScheduleParam videoAdScheduleParam = new VideoAdScheduleParam.Builder(adScheduleId)
.setDuration(contentDuration)
.setAdSchedulePolicy(true, false, true)
.setAdNoticeDurationSec(5)
.build();
// create manager
videoAdScheduleManager = new GfpVideoAdScheduleManager(
this,
videoAdScheduleParam,
adParam,
adVideoPlayer,
adUiContainer
);
GfpVideoAdOptions videoAdOptions = new GfpVideoAdOptions();
videoAdOptions.setSupportedStreamingHLS(true);
videoAdScheduleManager.setVideoAdOptions(videoAdOptions);
/**
* if you need the QOE
videoAdScheduleManager.setQoeListener(new GfpVideoAdQoeListener() {
@Override
public void onAdLoaded(GfpVideoAdQoeInfo info) {
...
}
...
});
*/
videoAdScheduleManager.setAdScheduleListener(new VideoAdScheduleListener() {
@Override
public void onScheduleLoaded(VideoScheduleResponse schedule) {
Log.d("MainActivity", String.format("onScheduleLoaded - AdBreak size: %d", schedule.getAdBreaks().size()));
}
@Override
public void onContentResumeRequest() {
Log.d("MainActivity", "play the content");
if (!exoPlayerView.isPlaying()) {
exoPlayerView.resumeContentsRequest();
}
}
@Override
public void onContentPauseRequest() {
Log.d("MainActivity", "pause the content");
exoPlayerView.pauseContentsRequest();
}
@Override
public void onScheduleCompleted() {
Log.d("MainActivity", "all ads are finished in schedule");
if (!exoPlayerView.isPlaying()) {
exoPlayerView.resumeContentsRequest();
}
}
@Override
public void onError(GfpError gfpError) {
Log.d("MainActivity", "schedule load is failed Error: " + gfpError.toString());
if (!exoPlayerView.isPlaying()) {
exoPlayerView.resumeContentsRequest();
}
}
});
videoAdScheduleManager.setAdListener(new VideoAdListener() {
@Override
public void onAdLoaded(GfpVideoAd ad) {
// NonLinearAdInfo nonLinearAdInfo = ad.getNonLinearAdInfo();
// can check the remind
Log.d("MainActivity", "onAdLoaded()\tResponseInfo: " + ad.getResponseInfo().toString());
}
@Override
public void onAdStartReady(GfpVideoAd ad) {
ad.start(true); // have to call this
Log.d("MainActivity", "time to start ad");
}
@Override
public void onAdNonLinearStartReady(GfpVideoAd ad) {
Log.d("MainActivity", "show the Non Linear");
ad.showNonLinearAd(GfpNonLinearAdView.ContainerType.INNER);
}
@Override
public void onAdStarted(GfpVideoAd ad) {
Log.d("MainActivity", "ad is started");
}
@Override
public void onAdClicked(GfpVideoAd ad) {
Log.d("MainActivity", "ad is clicked");
}
@Override
public void onAdCompleted(GfpVideoAd ad) {
Log.d("MainActivity", "ad is finished");
if (!exoPlayerView.isPlaying()) {
exoPlayerView.resumeContentsRequest();
}
}
@Override
public void onError(GfpVideoAd ad, GfpError error) {
Log.e("MainActivity", "error\t" + String.format(
"code[%d] subCode[%s] message[%s] responseInfo[%s]",
error.getErrorCode(),
error.getErrorSubCode(),
error.getErrorMessage(),
ad.getResponseInfo().toString()
));
if (!exoPlayerView.isPlaying()) {
exoPlayerView.resumeContentsRequest();
}
}
});
playerContainer.addView(playerLayout);
videoAdScheduleManager.load();
}
@Override
public void onPause() {
super.onPause();
if (videoAdScheduleManager != null) {
videoAdScheduleManager.pause();
}
}
@Override
public void onResume() {
super.onResume();
if (videoAdScheduleManager != null) {
videoAdScheduleManager.resume();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (videoAdScheduleManager != null) {
videoAdScheduleManager.destroy();
}
}
}
[Step 10] Advertisement removal
If all advertisements registered in the schedule have terminated or exited the advertisement screen, the schedule manager must be removed to ensure that the advertisements are disposed of properly.
The removal of the schedule manager can be done by calling destroy()
provided by GfpVideoAdScheduleManager
as shown below.
- Kotlin
- Java
if (::videoAdScheduleManager.isInitialized) {
videoAdScheduleManager.destroy()
}
if (videoAdScheduleManager != null) {
videoAdScheduleManager.destroy();
}