diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js
index 216b0371e93..05c176a814f 100644
--- a/modules/ixBidAdapter.js
+++ b/modules/ixBidAdapter.js
@@ -41,7 +41,7 @@ const VIDEO_TIME_TO_LIVE = 3600; // 1hr
const NET_REVENUE = true;
const MAX_REQUEST_SIZE = 8000;
const MAX_REQUEST_LIMIT = 4;
-const OUTSTREAM_MINIMUM_PLAYER_SIZE = [300, 250];
+const OUTSTREAM_MINIMUM_PLAYER_SIZE = [144, 144];
const PRICE_TO_DOLLAR_FACTOR = {
JPY: 1
};
@@ -177,7 +177,11 @@ function bidToVideoImp(bid) {
if (context === INSTREAM) {
imp.video.placement = 1;
} else if (context === OUTSTREAM) {
- imp.video.placement = 4;
+ if (deepAccess(videoParamRef, 'playerConfig.floatOnScroll')) {
+ imp.video.placement = 5;
+ } else {
+ imp.video.placement = 4;
+ }
} else {
logWarn(`IX Bid Adapter: Video context '${context}' is not supported`);
}
@@ -516,6 +520,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
}
const r = {};
+ const tmax = config.getConfig('bidderTimeout');
// Since bidderRequestId are the same for different bid request, just use the first one.
r.id = validBidRequests[0].bidderRequestId.toString();
@@ -534,6 +539,9 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
r.ext.ixdiag[key] = ixdiag[key];
}
+ if (tmax) {
+ r.ext.ixdiag.tmax = tmax
+ }
// Get cached errors stored in LocalStorage
const cachedErrors = getCachedErrors();
@@ -725,7 +733,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
currentRequestSize += currentImpressionSize;
- const fpd = bidderRequest.ortb2 || {};
+ const fpd = deepAccess(bidderRequest, 'ortb2') || {};
if (!isEmpty(fpd) && !isFpdAdded) {
r.ext.ixdiag.fpd = true;
@@ -1252,10 +1260,10 @@ export const spec = {
const videoImp = bidToVideoImp(bid).video;
if (deepAccess(bid, 'mediaTypes.video.context') === OUTSTREAM && isIndexRendererPreferred(bid) && videoImp) {
- const outstreamPlayerSize = deepAccess(videoImp, 'playerSize')[0];
+ const outstreamPlayerSize = [deepAccess(videoImp, 'w'), deepAccess(videoImp, 'h')];
const isValidSize = outstreamPlayerSize[0] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[0] && outstreamPlayerSize[1] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[1];
if (!isValidSize) {
- logError(`IX Bid Adapter: ${mediaTypeVideoPlayerSize} is an invalid size for IX outstream renderer`);
+ logError(`IX Bid Adapter: ${outstreamPlayerSize} is an invalid size for IX outstream renderer`);
return false;
}
}
diff --git a/modules/ixBidAdapter.md b/modules/ixBidAdapter.md
index 285f13547af..12f78536968 100644
--- a/modules/ixBidAdapter.md
+++ b/modules/ixBidAdapter.md
@@ -77,6 +77,9 @@ object are detailed here.
|video.minduration| Required | Integer | Minimum video ad duration in seconds.
|video.maxduration| Required | Integer | Maximum video ad duration in seconds.
|video.protocol / video.protocols| Required | Integer / Integer[] | Either a single protocol provided as an integer, or protocols provided as a list of integers. `2` - VAST 2.0, `3` - VAST 3.0, `5` - VAST 2.0 Wrapper, `6` - VAST 3.0 Wrapper
+| video.playerConfig | Optional | Hash | The Index specific outstream player configurations.
+| video.playerConfig.floatOnScroll | Optional | Boolean | A boolean specifying whether you want to use the player’s floating capabilities, where:
- `true`: Allow the player to float.
Note: If you set floatOnScroll to true, Index updates the placement value to `5`.
- `false`: Do not allow the player to float (default).
+| video.playerConfig.floatSize | Optional | Integer[] | The height and width of the floating player in pixels. If you do not specify a float size, the player adjusts to the aspect ratio of the player size that is defined when it is not floating. Index recommends that you review and test the float size to your user experience preference.
## Deprecation warning
@@ -247,13 +250,19 @@ var adUnits = [{
minduration: 5,
maxduration: 30,
mimes: ['video/mp4', 'application/javascript'],
- placement: 3
+ placement: 5
}
},
bids: [{
bidder: 'ix',
params: {
siteId: '715964'
+ video: {
+ playerConfig: {
+ floatOnScroll: true,
+ floatSize: [300,250]
+ }
+ }
}
}]
}];
diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js
index f06769445c5..80cf3ad09ff 100644
--- a/test/spec/modules/ixBidAdapter_spec.js
+++ b/test/spec/modules/ixBidAdapter_spec.js
@@ -582,10 +582,24 @@ describe('IndexexchangeAdapter', function () {
});
describe('isBidRequestValid', function () {
- it('should return false if outstream player size is less than 300x250 and IX renderer is preferred', function () {
+ it('should return false if outstream player size is less than 144x144 and IX renderer is preferred', function () {
const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]);
bid.mediaTypes.video.context = 'outstream';
- bid.mediaTypes.video.playerSize = [[300, 249]];
+ bid.mediaTypes.video.w = [[300, 143]];
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ bid.mediaTypes.video.w = [[143, 300]];
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ });
+
+ it('should return false if outstream video w & h is less than 144x144 and IX renderer is preferred', function () {
+ const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]);
+ bid.mediaTypes.video.context = 'outstream';
+ bid.mediaTypes.video.playerSize = [[300, 250]];
+ bid.mediaTypes.video.w = 300;
+ bid.mediaTypes.video.h = 142;
+ expect(spec.isBidRequestValid(bid)).to.equal(false);
+ bid.mediaTypes.video.h = 300;
+ bid.mediaTypes.video.w = 142;
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
@@ -1247,6 +1261,27 @@ describe('IndexexchangeAdapter', function () {
expect(r.ext.ixdiag.fpd).to.exist;
});
+ it('should set ixdiag.tmax value if it exists using tmax', function () {
+ config.setConfig({
+ bidderTimeout: 250
+ });
+
+ const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
+ const r = JSON.parse(request.data.r);
+
+ expect(r.ext.ixdiag.tmax).to.equal(250);
+ });
+
+ it('should not set ixdiag.tmax value if bidderTimeout is undefined', function () {
+ config.setConfig({
+ bidderTimeout: null
+ })
+ const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0];
+ const r = JSON.parse(request.data.r);
+
+ expect(r.ext.ixdiag.tmax).to.be.undefined
+ });
+
it('should not send information that is not part of openRTB spec v2.5 using ortb2', function () {
const ortb2 = {
site: {
@@ -2070,6 +2105,19 @@ describe('IndexexchangeAdapter', function () {
expect(videoImpression.video.w).to.equal(DEFAULT_VIDEO_VALID_BID_NO_VIDEO_PARAMS[0].mediaTypes.video.playerSize[0][0]);
expect(videoImpression.video.h).to.equal(DEFAULT_VIDEO_VALID_BID_NO_VIDEO_PARAMS[0].mediaTypes.video.playerSize[0][1]);
});
+
+ it('should set different placement for floating ad units', () => {
+ const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]);
+ bid.mediaTypes.video.context = 'outstream';
+ bid.params.video.playerConfig = {
+ floatOnScroll: true
+ };
+
+ const request = spec.buildRequests([bid]);
+ const videoImpression = JSON.parse(request[0].data.r).imp[0];
+
+ expect(videoImpression.video.placement).to.eq(5);
+ })
});
describe('buildRequestMultiFormat', function () {