PAL SDK integration
If using Google as ad provider, it requires few additional steps.
- Follow Setup ad insertion
- A player that supports ad tracking
- Use Google as ad provider
SmartLib supports versions:
- 22.1.0 for Android
- 2.9.1 for iOS & tvOS
- 1.87.0 for Web
1. Setup Google PAL SDK
- Android
- iOS & tvOS
- Web
Add the dependency either manually or through Google's repository: https://developers.google.com/ad-manager/pal/android/get-started#add_the_android_pal_sdk_as_a_library
implementation 'com.google.android.gms:play-services-pal:22.1.0'
We recommend to use PAL SDK 22.1.0.
If you're using ProGuard instead of R8, add the PAL SDK rules to the ProGuard file.
Add the dependency either manually or through SPM:
- iOS: https://developers.google.com/ad-manager/pal/ios/get-started#add_the_pal_sdk_to_your_project
- tvOS: https://developers.google.com/ad-manager/pal/tvos/get-started#add_the_pal_sdk_to_your_project
We recommend to use PAL SDK 2.9.1.
iOS and tvOS 14+ require an extra authorization regarding the app tracking transparency. Please follow the documentation on the Google PAL SDK website (prepare for iOS/tvOS 14+ and app store data disclosure).
Add the dependency either manually or through direct link in a <script> tag: https://developers.google.com/ad-manager/pal/html5/get-started#palhtml
We recommend to use PAL SDK 1.87.0.
2. Initialize the Google PAL SDK
- Android
- iOS & tvOS
- Web
First, you need to create a ConsentSettings and pass it to SmartLib. It has to be set before setPalParameters(...).
Find more details on the Google PAL documentation.
// The default value for allowStorage() is false, but can be
// changed once the appropriate consent has been gathered. The
// getConsentToStorage() method is a placeholder for the publisher's own
// method of obtaining user consent, either by integrating with a CMP or
// based on other methods the publisher chooses to handle storage consent.
boolean isConsentToStorage = getConsentToStorage();
ConsentSettings consentSettings = ConsentSettings.builder()
.allowStorage(isConsentToStorage)
.build();
AdManager.getInstance().setConsentSettings(consentSettings);
To enable nonce generation, the PAL parameters have to be initialized once, after SmartLib init.
If parameters are not yet known, set values to null.
Depending on your Google ad campaign, pal parameters may have to be set before each streaming session with ads.
/**
* Set Google PAL parameters
*
* @param descriptionURL Google PAL parameter, set null if not used
* @param partnerName Google PAL parameter, set null if not used
* @param partnerVersion Google PAL parameter, set null if not used
* @param omidVersion Google PAL parameter, set null if not used - Deprecated, use supportedApiFrameworks instead
* @param playerType Google PAL parameter, set null if not used
* @param playerVersion Google PAL parameter, set null if not used
* @param ppid Google PAL parameter, set null if not used
* @param videoPlayerHeight Google PAL parameter, set null if not used
* @param videoPlayerWidth Google PAL parameter, set null if not used
* @param willAdAutoPlay Google PAL parameter, set null if not used
* @param willAdPlayMuted Google PAL parameter, set null if not used
* @param supportedApiFrameworks Google PAL parameter, set null if not used
* @param sessionId Google PAL parameter, set null if not used
* @param continuousPlayback Google PAL parameter, set null if not used
* @param iconsSupported Google PAL parameter, set null if not used
*/
AdManager.getInstance().setPalParameters(descriptionURL, partnerName, partnerVersion,
omidVersion, playerType, playerVersion, ppid,
videoPlayerHeight, videoPlayerWidth, willAdAutoPlay, willAdPlayMuted,
supportedApiFrameworks, sessionId, continuousPlayback, iconsSupported);
Parameters are reset when SmartLib release is called.
First, you need to create a ConsentSettings and pass it to SmartLib. It has to be set before setPalParameters.
Find more details on the Google PAL documentation.
// The default value for 'allowStorage' and 'directedForChildOrUnknownAge' is
// 'NO', but should be updated once the appropriate consent has been gathered.
// Publishers should either integrate with a CMP or use a different method to
// handle storage consent.
PALSettings *settings = [[PALSettings alloc] init];
settings.allowStorage = YES;
settings.directedForChildOrUnknownAge = NO;
[[AdManager sharedManager] setConsentSettings:settings];
Then, you need to set the PAL parameters. Parameters have to be initialized once, after SmartLib init.
If parameters are not yet known, set values to nil.
Depending on your Google ad campaign, PAL parameters may have to be set before each streaming session with ads.
/**
* Set Google PAL parameters
*
* @param descriptionURL Google PAL parameter, set nil if not used
* @param partnerName Google PAL parameter, set nil if not used
* @param partnerVersion Google PAL parameter, set nil if not used
* @param omidVersion Google PAL parameter, set nil if not used - Deprecated, use supportedApiFrameworks instead
* @param playerType Google PAL parameter, set nil if not used
* @param playerVersion Google PAL parameter, set nil if not used
* @param ppid Google PAL parameter, set nil if not used
* @param videoPlayerHeight Google PAL parameter, set nil if not used
* @param videoPlayerWidth Google PAL parameter, set nil if not used
* @param willAdAutoPlay Google PAL parameter, set @NO for PALFlagOff, @YES for PALFlagOn, nil if not used
* @param willAdPlayMuted Google PAL parameter, set @NO for PALFlagOff, @YES for PALFlagOn, nil if not used
* @param supportedApiFrameworks Google PAL parameter, set nil if not used
* @param sessionId Google PAL parameter, set nil if not used
* @param continuousPlayback Google PAL parameter, set @NO for PALFlagOff, @YES for PALFlagOn, nil if not used
* @param iconsSupported Google PAL parameter, set @NO for NO, @YES for YES, nil if not used
*/
[[AdManager sharedManager] setPalParameters:descriptionURL
partnerName:partnerName
partnerVersion:partnerVersion
omidVersion:omidVersion
playerType:playerType
playerVersion:playerVersion
ppid:ppid
videoPlayerHeight:videoPlayerHeight
videoPlayerWidth:videoPlayerWidth
willAdAutoPlay:willAdAutoPlay
willAdPlayMuted:willAdPlayMuted
supportedApiFrameworks:supportedApiFrameworks
sessionId:sessionId
continuousPlayback:continuousPlayback
iconsSupported:iconsSupported];
Parameters are reset when SmartLib release is called.
First, attach the PAL SDK to SmartLib.
// goog is a global object registered with pal.js
AdManager.getInstance().attachPALSDK(goog);
Next, you need to create a ConsentSettings and pass it to SmartLib. It has to be set before setPalParameters(...).
Find more details on the Google PAL documentation.
// The default value for allowStorage() is false, but can be
// changed once the appropriate consent has been gathered. The
// getConsentToStorage() method is a placeholder for the publisher's own
// method of obtaining user consent, either by integrating with a CMP or
// based on other methods the publisher chooses to handle storage consent.
const isConsentToStorage = getConsentToStorage();
const consentSettings = new goog.pal.ConsentSettings();
consentSettings.allowStorage = isConsentToStorage;
AdManager.getInstance().setConsentSettings(consentSettings);
To enable nonce generation, the PAL parameters have to be initialized once, after SmartLib init.
If parameters are not yet known, set values to undefined.
Depending on your Google ad campaign, PAL parameters may have to be set before each streaming session with ads.
/**
* Set Google PAL parameters
*
* @param descriptionURL Google PAL parameter, set undefined if not used
* @param partnerName Google PAL parameter, set undefined if not used
* @param partnerVersion Google PAL parameter, set undefined if not used
* @param omidVersion Google PAL parameter, set undefined if not used - Deprecated, use supportedApiFrameworks instead
* @param playerType Google PAL parameter, set undefined if not used
* @param playerVersion Google PAL parameter, set undefined if not used
* @param ppid Google PAL parameter, set undefined if not used
* @param videoPlayerHeight Google PAL parameter, set undefined if not used
* @param videoPlayerWidth Google PAL parameter, set undefined if not used
* @param willAdAutoPlay Google PAL parameter, set undefined if not used
* @param willAdPlayMuted Google PAL parameter, set undefined if not used
* @param supportedApiFrameworks Google PAL parameter, set undefined if not used
* @param sessionId Google PAL parameter, set undefined if not used
* @param continuousPlayback Google PAL parameter, set undefined if not used
* @param iconsSupported Google PAL parameter, set undefined if not used
*/
AdManager.getInstance().setPalParameters(descriptionURL, partnerName, partnerVersion,
omidVersion, playerType, playerVersion, ppid,
videoPlayerHeight, videoPlayerWidth, willAdAutoPlay, willAdPlayMuted,
supportedApiFrameworks, sessionId, continuousPlayback, iconsSupported);
Parameters are reset when SmartLib release is called.
3. Notify Google PAL SDK of user events
Most of PAL SDK events are handled automatically by SmartLib :
- sendAdImpression: Informs PAL that an ad impression has occurred - not used in latest versions
- sendPlaybackStart: Informs PAL that playback has started
- sendPlaybackEnd: Informs PAL that playback has ended
The ad touch needs to be handled manually.
- Android
- iOS & tvOS
- Web
// Send touch when the player view is receiving a MotionEvent object
playerView.setOnTouchListener((view, motionEvent) -> {
session.adTouch(motionEvent);
return false;
});
The PAL SDK is requiring to access the view that show the ad (to add a gesture recognizer).
It has to be set before starting the session (i.e calling getURL).
/**
* Set ad view (PAL SDK)
* @param view view object
*/
[session setAdView:uiView];
// Send touch when the video element is clicked
videoElement.addEventListener('mousedown', (e) => onVideoTouch(e));
videoElement.addEventListener('touchstart', (e) => onVideoTouch(e));
function onVideoTouch(touchEvent) {
session.adTouch(touchEvent);
}
4. Full example
- Android
- iOS & tvOS
- Web
// Init SmartLib
SmartLib.getInstance().init(getApplicationContext(), ..., ..., ...);
// Set consent settings
boolean isConsentToStorage = getConsentToStorage();
ConsentSettings consentSettings = ConsentSettings.builder()
.allowStorage(isConsentToStorage)
.build();
AdManager.getInstance().setConsentSettings(consentSettings);
// Set PAL SDK parameters
AdManager.getInstance().setPalParameters(descriptionURL, partnerName, partnerVersion,
omidVersion, playerType, playerVersion, ppid,
videoPlayerHeight, videoPlayerWidth, willAdAutoPlay, willAdPlayMuted,
supportedApiFrameworks, sessionId, continuousPlayback, iconsSupported);
// Create a new session
StreamingSession session = SmartLib.getInstance().createStreamingSession();
// Attach the player
session.attachPlayer(player);
// Forward touch events to PAL SDK
playerView.setOnTouchListener((view, motionEvent) -> {
session.adTouch(motionEvent);
return false;
});
// Listen to ad events
session.setAdEventsListener(new AdManager.AdEventsListener() {
@Override
public void onAdBreakBegin(AdBreakData adBreak) {
// Lock player controls
mControlsLayout.setClickable(false);
}
@Override
public void onAdBegin(AdData adData, AdBreakData adBreakData) {
// Show ad link button if needed
mAdLink.setVisible(View.VISIBLE);
mAdLink.setClickURL(clickURL); // on click, it will call session.adUserInteraction(AdInteractionType.CLICK);
}
@Override
public void onAdSkippable(AdData adData, AdBreakData adBreakData, long adSkippablePosition, long adEndPosition, long adBreakEndPosition) {
// Show the skip message/button "skip ad in x seconds"
mAdSkipMessage.setVisibility(View.VISIBLE);
}
@Override
public void onAdEnd(AdData adData, AdBreakData adBreakData) {
// Hide ad link and ad skip button
mAdLink.setVisible(View.GONE);
mAdSkipMessage.setVisibility(View.GONE);
}
@Override
public void onAdBreakEnd(AdBreakData adBreakData) {
// Hide ad link and ad skip button
mAdLink.setVisible(View.GONE);
mAdSkipMessage.setVisibility(View.GONE);
// Unlock player controls
mControlsLayout.setClickable(true);
}
});
...
// Start the session with/without ads
if (contentContainsAds) { // To be adapted
session.activateAdvertising();
// Set ad parameters
session.setAdParameter("name1", "value1");
session.setAdParameter("name2", "value2");
}
// You must not call getURL on the main thread !
// Because of generation duration of the nonce and technical requirements, it has to be done on another thread
StreamingSessionResult result = session.getURL(CONTENT_URL);
...
// Notify that the user opened the ad link
session.adUserInteraction(AdInteractionType.CLICK);
// Stop the session
session.stopStreamingSession();
...
// Init SmartLib
[SmartLib initSmartLib:... nanoCDNHost:... broadpeakDomainNames:...];
// Set consent settings
PALSettings *settings = [[PALSettings alloc] init];
settings.allowStorage = YES;
settings.directedForChildOrUnknownAge = NO;
[[AdManager sharedManager] setConsentSettings:settings];
// Init PAL SDK
[[AdManager sharedManager] setPalParameters:descriptionURL
partnerName:partnerName
partnerVersion:partnerVersion
omidVersion:omidVersion
playerType:playerType
playerVersion:playerVersion
ppid:ppid
videoPlayerHeight:videoPlayerHeight
videoPlayerWidth:videoPlayerWidth
willAdAutoPlay:willAdAutoPlay
willAdPlayMuted:willAdPlayMuted
supportedApiFrameworks:supportedApiFrameworks
sessionId:sessionId
continuousPlayback:continuousPlayback
iconsSupported:iconsSupported];
// Create a session
StreamingSession *session = [SmartLib createStreamingSession];
// Attach the player
[session attachPlayer:player];
// Forward ad view to PAL SDK
[session setAdView:player.uiView];
// Listen to ad events
[session setAdEventsListener:self];
...
// Start the session with/without ads
if (contentContainsAds) { // To be adapted
[session activateAdvertising];
[session setAdView:player.view]
// Set ad parameters
[session setAdParameter:@"name1" value:@"value1"];
[session setAdParameter:@"name2" value:@"value2"];
}
// Start the session
StreamingSessionResult *result = [session getURL:CONTENT_URL];
...
// Notify that the user opened the ad link
[session adUserInteraction:BPAdInteractionTypeClick];
// Stop the session
[session stopStreamingSession];
...
// Init SmartLib
SmartLib.getInstance().init(...);
// Attach PAL SDK
AdManager.getInstance().attachPALSDK(goog);
// Set consent settings
const isConsentToStorage = getConsentToStorage();
const consentSettings = new goog.pal.ConsentSettings();
consentSettings.allowStorage = isConsentToStorage;
AdManager.getInstance().setConsentSettings(consentSettings);
// Set PAL SDK parameters
AdManager.getInstance().setPalParameters(descriptionURL, partnerName, partnerVersion,
omidVersion, playerType, playerVersion, ppid,
videoPlayerHeight, videoPlayerWidth, willAdAutoPlay, willAdPlayMuted,
supportedApiFrameworks, sessionId, continuousPlayback, iconsSupported);
// Create a session
const session = SmartLib.getInstance().createStreamingSession();
// Forward touch events to PAL SDK
videoElement.addEventListener('mousedown', (e) => onVideoTouch(e));
videoElement.addEventListener('touchstart', (e) => onVideoTouch(e));
// Attach the player
session.attachPlayer(player);
// Listen to ad events
session.setAdEventsListener({
onAdBreakBegin: (adBreakData) => {
// Lock player controls
},
onAdBegin: (adData, adBreakData) => {
// Show ad link button if needed
},
onAdSkippable: (adData, adBreakData, adSkippablePosition, adEndPosition, adBreakEndPosition) => {
// Show the skip message/button "skip ad in x seconds"
},
onAdEnd: (adData, adBreakData) => {
// Hide ad link, hide ad skip button
},
onAdBreakEnd: (adBreakData) => {
// Unlock player controls, hide ad link, hide ad skip button
}
});
...
// Start the session with/without ads
if (contentContainsAds) { // To be adapted
session.activateAdvertising();
// Set ad parameters
session.setAdParameter('name1', 'value1');
session.setAdParameter('name2', 'value2');
}
// Start the session
session.getURL(CONTENT_URL)
.then(result => {
...
});
...
// Notify that the user opened the ad link
session.adUserInteraction('click');
...
// Stop the session
session.stopStreamingSession();
...
function onVideoTouch(touchEvent) {
session.adTouch(touchEvent);
}