Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Added support for the customData property on the Ad and AdBreak types.

### Fixed

- Fixed an issue on iOS where sideloaded texttracks were not stored for cached playout.
Expand Down
15 changes: 15 additions & 0 deletions android/src/main/java/com/theoplayer/ads/AdAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.theoplayer.android.api.ads.CompanionAd
import com.theoplayer.android.api.ads.ima.GoogleImaAd
import com.theoplayer.android.api.ads.UniversalAdId
import com.theoplayer.android.api.event.ads.AdIntegrationKind
import com.theoplayer.util.BridgeUtils
import org.json.JSONObject
import java.lang.Exception

private const val PROP_AD_SYSTEM = "adSystem"
Expand Down Expand Up @@ -49,6 +51,7 @@ private const val PROP_COMPANION_HEIGHT = "height"
private const val PROP_COMPANION_RESOURCEURI = "resourceURI"
private const val PROP_UNIVERSAL_AD_ID_REGISTRY = "adIdRegistry"
private const val PROP_UNIVERSAL_AD_ID_VALUE = "adIdValue"
private const val PROP_CUSTOM_DATA = "customData"

private const val INVALID_DOUBLE = -1.0
private const val INVALID_INT = -1
Expand Down Expand Up @@ -130,6 +133,12 @@ object AdAdapter {
}
adPayload.putArray(PROP_AD_WRAPPER_CREATIVE_IDS, wrapperCreativeIdsPayload)
}
val customData = ad.customData
Comment thread
wvanhaevre marked this conversation as resolved.
if (customData is JSONObject) {
adPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(customData))
} else if (customData is Map<*, *>) {
adPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(JSONObject(customData)))
}
return adPayload
}

Expand All @@ -146,6 +155,12 @@ object AdAdapter {
adbreakPayload.putInt(PROP_ADBREAK_MAXDURATION,adbreak.maxDuration)
adbreakPayload.putInt(PROP_ADBREAK_TIMEOFFSET, adbreak.timeOffset)
adbreakPayload.putDouble(PROP_ADBREAK_MAXREMAININGDURATION, adbreak.maxRemainingDuration)
val customData = adbreak.customData
if (customData is JSONObject) {
adbreakPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(customData))
} else if (customData is Map<*, *>) {
adbreakPayload.putMap(PROP_CUSTOM_DATA, BridgeUtils.fromJSONObjectToBridge(JSONObject(customData)))
}
val adsPayload = Arguments.createArray()
for (ad in adbreak.ads) {
// Some ads in the ad break are possibly not loaded yet.
Expand Down
2 changes: 2 additions & 0 deletions android/src/main/java/com/theoplayer/util/BridgeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ object BridgeUtils {
// null -> putNull(key)
is Boolean -> putBoolean(key, value)
is Int -> putInt(key, value)
is Long -> putDouble(key, value.toDouble())
is Double -> putDouble(key, value)
is String -> putString(key, value)
is JSONObject -> putMap(key, fromJSONObjectToBridge(value))
Expand All @@ -53,6 +54,7 @@ object BridgeUtils {
// null -> writableArray.pushNull()
is Boolean -> pushBoolean(value)
is Int -> pushInt(value)
is Long -> pushDouble(value.toDouble())
is Double -> pushDouble(value)
is String -> pushString(value)
is JSONObject -> pushMap(fromJSONObjectToBridge(value))
Expand Down
7 changes: 7 additions & 0 deletions ios/ads/THEOplayerRCTAdAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
let PROP_ADBREAK_ADS: String = "ads"
let PROP_ADBREAK_INTEGRATION: String = "integration"
let PROP_ADBREAK_CUSTOM_INTEGRATION: String = "customIntegration"
let PROP_CUSTOM_DATA: String = "customData"
let PROP_COMPANION_AD_SLOT_ID: String = "adSlotId"
let PROP_COMPANION_ALT_TEXT: String = "altText"
let PROP_COMPANION_CLICK_THROUGH: String = "clickThrough"
Expand All @@ -49,6 +50,9 @@
if let customIntegration = ad.customIntegration {
adData[PROP_AD_CUSTOM_INTEGRATION] = customIntegration
}
if let customData = ad.customData as? [String: Any] {

Check warning on line 53 in ios/ads/THEOplayerRCTAdAdapter.swift

View workflow job for this annotation

GitHub Actions / Build for tvOS using XCode version 26.2.0

conditional downcast from '[String : Any]?' to '[String : Any]' does nothing
adData[PROP_CUSTOM_DATA] = customData
}
Comment thread
wvanhaevre marked this conversation as resolved.
Comment thread
wvanhaevre marked this conversation as resolved.
adData[PROP_AD_TYPE] = ad.type
if let adId = ad.id {
adData[PROP_AD_ID] = adId
Expand Down Expand Up @@ -180,6 +184,9 @@
adBreakData[PROP_ADBREAK_MAX_REMAINING_DURATION] = adBreak.maxRemainingDuration
adBreakData[PROP_ADBREAK_INTEGRATION] = adBreak.integration
adBreakData[PROP_ADBREAK_CUSTOM_INTEGRATION] = adBreak.customIntegration
if let customData = adBreak.customData as? [String: Any] {

Check warning on line 187 in ios/ads/THEOplayerRCTAdAdapter.swift

View workflow job for this annotation

GitHub Actions / Build for tvOS using XCode version 26.2.0

conditional downcast from '[String : Any]?' to '[String : Any]' does nothing
adBreakData[PROP_CUSTOM_DATA] = customData
}
Comment thread
wvanhaevre marked this conversation as resolved.
// process adds when adbreak contains them
if !adBreak.ads.isEmpty {
var adList: [[String:Any]] = []
Expand Down
4 changes: 4 additions & 0 deletions ios/ads/THEOplayerRCTAdsNative.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class NativeAd: THEOplayerSDK.Ad {
var clickThrough: String? = nil
/**The type of custom ad integration.*/
var customIntegration: String? = nil
/** Additional integration-specific data associated with this ad.*/
var customData: [String: Any]? = nil

init(adBreak: AdBreak, companions: [THEOplayerSDK.CompanionAd], type: String, id: String? = nil, skipOffset: Int? = nil, resourceURI: String? = nil, width: Int? = nil, height: Int? = nil, isSlate: Bool = false, integration: THEOplayerSDK.AdIntegrationKind, duration: Int? = 0, clickThrough: String?, customIntegration: String?) {
self.adBreak = adBreak
Expand Down Expand Up @@ -134,6 +136,8 @@ class NativeAdBreak: THEOplayerSDK.AdBreak {
- For other integrations, this may be `nil`.
*/
var id: String? = nil
/** Additional integration-specific data associated with this ad break.*/
var customData: [String: Any]? = nil

init(ads: [Ad], id: String? = nil, maxDuration: Int, maxRemainingDuration: Double, timeOffset: Int, integration: THEOplayerSDK.AdIntegrationKind, customIntegration: String? = nil) {
self.ads = ads
Expand Down
8 changes: 8 additions & 0 deletions src/api/ads/Ad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ export interface Ad {
* <br/> - Only supported for `'theo'` and `'google-ima'`.
*/
universalAdIds: UniversalAdId[];

/**
* Additional integration-specific data associated with this ad.
*
* @remarks
* <br/> - The value depends on the ad integration. It may be `undefined` if the integration does not provide any custom data.
*/
customData?: Record<string, unknown>;
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/api/ads/AdBreak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,12 @@ export interface AdBreak {
* <br/> - This feature is not available in the Google IMA integration and will default to -1.
*/
maxRemainingDuration: number | undefined;

/**
* Additional integration-specific data associated with this ad break.
*
* @remarks
* <br/> - The value depends on the ad integration. It may be `undefined` if the integration does not provide any custom data.
*/
customData?: Record<string, unknown>;
}
Loading