stormcloud-video-player 0.6.8 → 0.6.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -937,6 +937,7 @@ function createVastAdLayer(contentVideo, options) {
937
937
  var adHls;
938
938
  var adContainerEl;
939
939
  var currentAd;
940
+ var currentMediaFile;
940
941
  var sessionId;
941
942
  var destroyed = false;
942
943
  var tornDown = false;
@@ -1183,7 +1184,12 @@ function createVastAdLayer(contentVideo, options) {
1183
1184
  adContainerEl.style.display = "none";
1184
1185
  adContainerEl.style.pointerEvents = "none";
1185
1186
  }
1186
- emit("ad_impression");
1187
+ emit("ad_impression", {
1188
+ adId: currentAd === null || currentAd === void 0 ? void 0 : currentAd.id,
1189
+ adTitle: currentAd === null || currentAd === void 0 ? void 0 : currentAd.title,
1190
+ adUrl: currentMediaFile === null || currentMediaFile === void 0 ? void 0 : currentMediaFile.url,
1191
+ mediaType: currentMediaFile === null || currentMediaFile === void 0 ? void 0 : currentMediaFile.type
1192
+ });
1187
1193
  emit("content_resume");
1188
1194
  }
1189
1195
  function handleAdError() {
@@ -1205,6 +1211,7 @@ function createVastAdLayer(contentVideo, options) {
1205
1211
  adHls.destroy();
1206
1212
  adHls = void 0;
1207
1213
  }
1214
+ currentMediaFile = void 0;
1208
1215
  if (adVideoElement) {
1209
1216
  if (singleElementMode && adVideoElement === contentVideo) {
1210
1217
  contentVideo.pause();
@@ -1369,6 +1376,7 @@ function createVastAdLayer(contentVideo, options) {
1369
1376
  adVideoElement.volume = Math.max(0, Math.min(1, adVolume2));
1370
1377
  adVideoElement.muted = false;
1371
1378
  mediaFile2 = selectBestMediaFile(ad.mediaFiles);
1379
+ currentMediaFile = mediaFile2;
1372
1380
  if (debug) console.log("".concat(LOG, " Loading ad from: ").concat(mediaFile2.url));
1373
1381
  startPlayback(mediaFile2);
1374
1382
  return [
@@ -1415,6 +1423,7 @@ function createVastAdLayer(contentVideo, options) {
1415
1423
  }
1416
1424
  emit("content_pause");
1417
1425
  mediaFile = selectBestMediaFile(ad.mediaFiles);
1426
+ currentMediaFile = mediaFile;
1418
1427
  if (debug) console.log("".concat(LOG, " Loading ad from: ").concat(mediaFile.url));
1419
1428
  startPlayback(mediaFile);
1420
1429
  return [
@@ -1580,6 +1589,7 @@ function createVastAdLayer(contentVideo, options) {
1580
1589
  ];
1581
1590
  mainHlsInstance === null || mainHlsInstance === void 0 ? void 0 : mainHlsInstance.detachMedia();
1582
1591
  teardownCurrentPlayback();
1592
+ currentMediaFile = slot.mediaFile;
1583
1593
  adVideoElement = contentVideo;
1584
1594
  adHls = void 0;
1585
1595
  adPlaying = true;
@@ -1614,6 +1624,7 @@ function createVastAdLayer(contentVideo, options) {
1614
1624
  case 2:
1615
1625
  if (smartTVMode && !slot.videoEl) {
1616
1626
  teardownCurrentPlayback();
1627
+ currentMediaFile = slot.mediaFile;
1617
1628
  if (adVideoElement) {
1618
1629
  adVideoElement.remove();
1619
1630
  adVideoElement = void 0;
@@ -1645,6 +1656,7 @@ function createVastAdLayer(contentVideo, options) {
1645
1656
  ];
1646
1657
  }
1647
1658
  teardownCurrentPlayback();
1659
+ currentMediaFile = slot.mediaFile;
1648
1660
  if (adVideoElement && adVideoElement !== slot.videoEl) {
1649
1661
  adVideoElement.remove();
1650
1662
  }
@@ -1776,6 +1788,7 @@ function createVastAdLayer(contentVideo, options) {
1776
1788
  }
1777
1789
  }
1778
1790
  currentAd = void 0;
1791
+ currentMediaFile = void 0;
1779
1792
  tornDown = false;
1780
1793
  return [
1781
1794
  2
@@ -1828,6 +1841,7 @@ function createVastAdLayer(contentVideo, options) {
1828
1841
  }
1829
1842
  adContainerEl = void 0;
1830
1843
  currentAd = void 0;
1844
+ currentMediaFile = void 0;
1831
1845
  listeners.clear();
1832
1846
  },
1833
1847
  isAdPlaying: function isAdPlaying() {
@@ -2141,24 +2155,30 @@ function getBrowserID(clientInfo) {
2141
2155
  });
2142
2156
  })();
2143
2157
  }
2144
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2158
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
2159
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
2160
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
2161
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
2162
+ function buildHeaders(licenseKey) {
2163
+ var headers = {
2164
+ "Content-Type": "application/json"
2165
+ };
2166
+ if (licenseKey) {
2167
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2168
+ }
2169
+ return headers;
2170
+ }
2145
2171
  function sendTrackRequest(licenseKey, body) {
2146
2172
  return _async_to_generator(function() {
2147
- var headers, response;
2173
+ var response;
2148
2174
  return _ts_generator(this, function(_state) {
2149
2175
  switch(_state.label){
2150
2176
  case 0:
2151
- headers = {
2152
- "Content-Type": "application/json"
2153
- };
2154
- if (licenseKey) {
2155
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2156
- }
2157
2177
  return [
2158
2178
  4,
2159
2179
  fetch(TRACK_URL, {
2160
2180
  method: "POST",
2161
- headers: headers,
2181
+ headers: buildHeaders(licenseKey),
2162
2182
  body: JSON.stringify(body)
2163
2183
  })
2164
2184
  ];
@@ -2180,14 +2200,86 @@ function sendTrackRequest(licenseKey, body) {
2180
2200
  });
2181
2201
  })();
2182
2202
  }
2183
- function sendInitialTracking(licenseKey) {
2203
+ function postJson(url, licenseKey, body) {
2184
2204
  return _async_to_generator(function() {
2185
- var clientInfo, browserId, trackingData, headers, response, error;
2205
+ var response;
2206
+ return _ts_generator(this, function(_state) {
2207
+ switch(_state.label){
2208
+ case 0:
2209
+ return [
2210
+ 4,
2211
+ fetch(url, {
2212
+ method: "POST",
2213
+ headers: buildHeaders(licenseKey),
2214
+ body: JSON.stringify(body)
2215
+ })
2216
+ ];
2217
+ case 1:
2218
+ response = _state.sent();
2219
+ if (!response.ok) {
2220
+ throw new Error("HTTP error! status: ".concat(response.status));
2221
+ }
2222
+ return [
2223
+ 4,
2224
+ response.json()
2225
+ ];
2226
+ case 2:
2227
+ _state.sent();
2228
+ return [
2229
+ 2
2230
+ ];
2231
+ }
2232
+ });
2233
+ })();
2234
+ }
2235
+ function buildPlayerMetricEvent(_0) {
2236
+ return _async_to_generator(function(licenseKey) {
2237
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
2238
+ var _arguments = arguments;
2186
2239
  return _ts_generator(this, function(_state) {
2187
2240
  switch(_state.label){
2188
2241
  case 0:
2242
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2243
+ clientInfo = getClientInfo();
2244
+ return [
2245
+ 4,
2246
+ getBrowserID(clientInfo)
2247
+ ];
2248
+ case 1:
2249
+ browserId = _state.sent();
2250
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2251
+ return [
2252
+ 2,
2253
+ {
2254
+ player_id: browserId,
2255
+ browserId: browserId,
2256
+ device_type: clientInfo.deviceType,
2257
+ deviceType: clientInfo.deviceType,
2258
+ input_stream_type: context.inputStreamType,
2259
+ os: clientInfo.os,
2260
+ ad_loaded: flags.adLoaded,
2261
+ ad_detect: flags.adDetect,
2262
+ license_key: licenseKey,
2263
+ capture_at: captureAt,
2264
+ timestamp: captureAt
2265
+ }
2266
+ ];
2267
+ }
2268
+ });
2269
+ }).apply(this, arguments);
2270
+ }
2271
+ function sendInitialTracking(_0) {
2272
+ return _async_to_generator(function(licenseKey) {
2273
+ var context, clientInfo, browserId, trackingData, error;
2274
+ var _arguments = arguments;
2275
+ return _ts_generator(this, function(_state) {
2276
+ switch(_state.label){
2277
+ case 0:
2278
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2279
+ _state.label = 1;
2280
+ case 1:
2189
2281
  _state.trys.push([
2190
- 0,
2282
+ 1,
2191
2283
  4,
2192
2284
  ,
2193
2285
  5
@@ -2197,34 +2289,29 @@ function sendInitialTracking(licenseKey) {
2197
2289
  4,
2198
2290
  getBrowserID(clientInfo)
2199
2291
  ];
2200
- case 1:
2292
+ case 2:
2201
2293
  browserId = _state.sent();
2202
2294
  trackingData = _object_spread({
2203
2295
  browserId: browserId
2204
2296
  }, clientInfo);
2205
- headers = {
2206
- "Content-Type": "application/json"
2207
- };
2208
- if (licenseKey) {
2209
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2210
- }
2211
2297
  return [
2212
2298
  4,
2213
- fetch(TRACK_URL, {
2214
- method: "POST",
2215
- headers: headers,
2216
- body: JSON.stringify(trackingData)
2299
+ sendTrackRequest(licenseKey, {
2300
+ events: [
2301
+ {
2302
+ player_id: browserId,
2303
+ device_type: clientInfo.deviceType,
2304
+ input_stream_type: context.inputStreamType,
2305
+ os: clientInfo.os,
2306
+ ad_loaded: false,
2307
+ ad_detect: false,
2308
+ license_key: licenseKey,
2309
+ capture_at: /* @__PURE__ */ new Date().toISOString()
2310
+ }
2311
+ ],
2312
+ trackingData: trackingData
2217
2313
  })
2218
2314
  ];
2219
- case 2:
2220
- response = _state.sent();
2221
- if (!response.ok) {
2222
- throw new Error("HTTP error! status: ".concat(response.status));
2223
- }
2224
- return [
2225
- 4,
2226
- response.json()
2227
- ];
2228
2315
  case 3:
2229
2316
  _state.sent();
2230
2317
  return [
@@ -2244,36 +2331,30 @@ function sendInitialTracking(licenseKey) {
2244
2331
  ];
2245
2332
  }
2246
2333
  });
2247
- })();
2334
+ }).apply(this, arguments);
2248
2335
  }
2249
- function sendAdDetectTracking(licenseKey, adDetectInfo) {
2250
- return _async_to_generator(function() {
2251
- var clientInfo, browserId, trackingData, error;
2336
+ function sendAdDetectTracking(_0, _1) {
2337
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2338
+ var context, error;
2339
+ var _arguments = arguments;
2252
2340
  return _ts_generator(this, function(_state) {
2253
2341
  switch(_state.label){
2254
2342
  case 0:
2343
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2344
+ _state.label = 1;
2345
+ case 1:
2255
2346
  _state.trys.push([
2256
- 0,
2347
+ 1,
2257
2348
  3,
2258
2349
  ,
2259
2350
  4
2260
2351
  ]);
2261
- clientInfo = getClientInfo();
2262
- return [
2263
- 4,
2264
- getBrowserID(clientInfo)
2265
- ];
2266
- case 1:
2267
- browserId = _state.sent();
2268
- trackingData = _object_spread({
2269
- browserId: browserId
2270
- }, clientInfo);
2271
2352
  return [
2272
2353
  4,
2273
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2274
- licenseKey: licenseKey,
2275
- adDetectInfo: adDetectInfo
2276
- }))
2354
+ sendHeartbeat(licenseKey, context, {
2355
+ adDetect: true,
2356
+ captureAt: adDetectInfo.timestamp
2357
+ })
2277
2358
  ];
2278
2359
  case 2:
2279
2360
  _state.sent();
@@ -2294,36 +2375,30 @@ function sendAdDetectTracking(licenseKey, adDetectInfo) {
2294
2375
  ];
2295
2376
  }
2296
2377
  });
2297
- })();
2378
+ }).apply(this, arguments);
2298
2379
  }
2299
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2300
- return _async_to_generator(function() {
2301
- var clientInfo, browserId, trackingData, error;
2380
+ function sendAdLoadedTracking(_0, _1) {
2381
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2382
+ var context, error;
2383
+ var _arguments = arguments;
2302
2384
  return _ts_generator(this, function(_state) {
2303
2385
  switch(_state.label){
2304
2386
  case 0:
2387
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2388
+ _state.label = 1;
2389
+ case 1:
2305
2390
  _state.trys.push([
2306
- 0,
2391
+ 1,
2307
2392
  3,
2308
2393
  ,
2309
2394
  4
2310
2395
  ]);
2311
- clientInfo = getClientInfo();
2312
- return [
2313
- 4,
2314
- getBrowserID(clientInfo)
2315
- ];
2316
- case 1:
2317
- browserId = _state.sent();
2318
- trackingData = _object_spread({
2319
- browserId: browserId
2320
- }, clientInfo);
2321
2396
  return [
2322
2397
  4,
2323
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2324
- licenseKey: licenseKey,
2325
- adLoadedInfo: adLoadedInfo
2326
- }))
2398
+ sendHeartbeat(licenseKey, context, {
2399
+ adLoaded: true,
2400
+ captureAt: adLoadedInfo.timestamp
2401
+ })
2327
2402
  ];
2328
2403
  case 2:
2329
2404
  _state.sent();
@@ -2344,103 +2419,95 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2344
2419
  ];
2345
2420
  }
2346
2421
  });
2347
- })();
2422
+ }).apply(this, arguments);
2348
2423
  }
2349
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
2350
- return _async_to_generator(function() {
2351
- var clientInfo, browserId, trackingData, error;
2424
+ function sendAdImpressionTracking(_0, _1) {
2425
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2426
+ var context, metricEvent, error;
2427
+ var _arguments = arguments;
2352
2428
  return _ts_generator(this, function(_state) {
2353
2429
  switch(_state.label){
2354
2430
  case 0:
2431
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2432
+ _state.label = 1;
2433
+ case 1:
2355
2434
  _state.trys.push([
2356
- 0,
2357
- 3,
2435
+ 1,
2436
+ 4,
2358
2437
  ,
2359
- 4
2438
+ 5
2360
2439
  ]);
2361
- clientInfo = getClientInfo();
2362
2440
  return [
2363
2441
  4,
2364
- getBrowserID(clientInfo)
2442
+ buildPlayerMetricEvent(licenseKey, context, {
2443
+ captureAt: adImpressionInfo.timestamp
2444
+ })
2365
2445
  ];
2366
- case 1:
2367
- browserId = _state.sent();
2368
- trackingData = _object_spread({
2369
- browserId: browserId
2370
- }, clientInfo);
2446
+ case 2:
2447
+ metricEvent = _state.sent();
2371
2448
  return [
2372
2449
  4,
2373
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2374
- licenseKey: licenseKey,
2375
- adImpressionInfo: adImpressionInfo
2376
- }))
2450
+ Promise.all([
2451
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
2452
+ postJson(IMPRESSIONS_URL, licenseKey, {
2453
+ events: [
2454
+ {
2455
+ player_id: metricEvent.player_id,
2456
+ ad_played_count: 1,
2457
+ ad_url: adImpressionInfo.adUrl,
2458
+ license_key: licenseKey,
2459
+ capture_at: adImpressionInfo.timestamp
2460
+ }
2461
+ ]
2462
+ })
2463
+ ])
2377
2464
  ];
2378
- case 2:
2465
+ case 3:
2379
2466
  _state.sent();
2380
2467
  return [
2381
2468
  3,
2382
- 4
2469
+ 5
2383
2470
  ];
2384
- case 3:
2471
+ case 4:
2385
2472
  error = _state.sent();
2386
2473
  console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2387
2474
  return [
2388
2475
  3,
2389
- 4
2476
+ 5
2390
2477
  ];
2391
- case 4:
2478
+ case 5:
2392
2479
  return [
2393
2480
  2
2394
2481
  ];
2395
2482
  }
2396
2483
  });
2397
- })();
2484
+ }).apply(this, arguments);
2398
2485
  }
2399
- function sendHeartbeat(licenseKey) {
2400
- return _async_to_generator(function() {
2401
- var clientInfo, browserId, heartbeatData, headers, response, error;
2486
+ function sendHeartbeat(_0) {
2487
+ return _async_to_generator(function(licenseKey) {
2488
+ var context, flags, heartbeatData, error;
2489
+ var _arguments = arguments;
2402
2490
  return _ts_generator(this, function(_state) {
2403
2491
  switch(_state.label){
2404
2492
  case 0:
2493
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2494
+ _state.label = 1;
2495
+ case 1:
2405
2496
  _state.trys.push([
2406
- 0,
2497
+ 1,
2407
2498
  4,
2408
2499
  ,
2409
2500
  5
2410
2501
  ]);
2411
- clientInfo = getClientInfo();
2412
- return [
2413
- 4,
2414
- getBrowserID(clientInfo)
2415
- ];
2416
- case 1:
2417
- browserId = _state.sent();
2418
- heartbeatData = {
2419
- browserId: browserId,
2420
- timestamp: /* @__PURE__ */ new Date().toISOString()
2421
- };
2422
- headers = {
2423
- "Content-Type": "application/json"
2424
- };
2425
- if (licenseKey) {
2426
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2427
- }
2428
2502
  return [
2429
2503
  4,
2430
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
2431
- method: "POST",
2432
- headers: headers,
2433
- body: JSON.stringify(heartbeatData)
2434
- })
2504
+ buildPlayerMetricEvent(licenseKey, context, flags)
2435
2505
  ];
2436
2506
  case 2:
2437
- response = _state.sent();
2438
- if (!response.ok) {
2439
- throw new Error("HTTP error! status: ".concat(response.status));
2440
- }
2507
+ heartbeatData = _state.sent();
2441
2508
  return [
2442
2509
  4,
2443
- response.json()
2510
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
2444
2511
  ];
2445
2512
  case 3:
2446
2513
  _state.sent();
@@ -2461,7 +2528,7 @@ function sendHeartbeat(licenseKey) {
2461
2528
  ];
2462
2529
  }
2463
2530
  });
2464
- })();
2531
+ }).apply(this, arguments);
2465
2532
  }
2466
2533
  // src/utils/polyfills.ts
2467
2534
  function polyfillURLSearchParams() {
@@ -3476,17 +3543,67 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3476
3543
  return "vast";
3477
3544
  }
3478
3545
  },
3546
+ {
3547
+ key: "getInputStreamType",
3548
+ value: function getInputStreamType() {
3549
+ var src = this.config.src.toLowerCase();
3550
+ if (src.includes(".m3u8")) return "hls";
3551
+ if (src.includes(".mpd")) return "dash";
3552
+ if (src.includes(".mp4")) return "mp4";
3553
+ return this.isLiveStream ? "live" : "vod";
3554
+ }
3555
+ },
3556
+ {
3557
+ key: "getAnalyticsContext",
3558
+ value: function getAnalyticsContext() {
3559
+ return {
3560
+ inputStreamType: this.getInputStreamType()
3561
+ };
3562
+ }
3563
+ },
3564
+ {
3565
+ key: "getAdUrlFromBids",
3566
+ value: function getAdUrlFromBids(bids) {
3567
+ var _bids_;
3568
+ return bids === null || bids === void 0 ? void 0 : (_bids_ = bids[0]) === null || _bids_ === void 0 ? void 0 : _bids_.vastUrl;
3569
+ }
3570
+ },
3571
+ {
3572
+ key: "trackAdLoaded",
3573
+ value: function trackAdLoaded(bids) {
3574
+ if (!this.config.licenseKey) return;
3575
+ var adUrl = this.getAdUrlFromBids(bids);
3576
+ if (adUrl) {
3577
+ this.lastServedAdUrl = adUrl;
3578
+ }
3579
+ sendAdLoadedTracking(this.config.licenseKey, _object_spread_props(_object_spread({
3580
+ source: this.getAdSource()
3581
+ }, adUrl ? {
3582
+ vastUrl: adUrl
3583
+ } : {}), {
3584
+ timestamp: /* @__PURE__ */ new Date().toISOString()
3585
+ }), this.getAnalyticsContext());
3586
+ }
3587
+ },
3479
3588
  {
3480
3589
  key: "attachAdLayerEventListeners",
3481
3590
  value: function attachAdLayerEventListeners() {
3482
3591
  var _this = this;
3483
- this.adLayer.on("ad_impression", function() {
3592
+ this.adLayer.on("ad_impression", function(payload) {
3484
3593
  if (_this.config.licenseKey) {
3485
- sendAdImpressionTracking(_this.config.licenseKey, {
3594
+ var _ref;
3595
+ var adUrl = (_ref = payload === null || payload === void 0 ? void 0 : payload.adUrl) !== null && _ref !== void 0 ? _ref : _this.lastServedAdUrl;
3596
+ if (adUrl) {
3597
+ _this.lastServedAdUrl = adUrl;
3598
+ }
3599
+ sendAdImpressionTracking(_this.config.licenseKey, _object_spread_props(_object_spread({
3486
3600
  source: _this.getAdSource(),
3487
- adIndex: _this.currentAdIndex,
3601
+ adIndex: _this.currentAdIndex
3602
+ }, adUrl ? {
3603
+ adUrl: adUrl
3604
+ } : {}), {
3488
3605
  timestamp: /* @__PURE__ */ new Date().toISOString()
3489
- });
3606
+ }), _this.getAnalyticsContext());
3490
3607
  }
3491
3608
  });
3492
3609
  this.adLayer.on("ad_error", function(errorPayload) {
@@ -3580,6 +3697,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3580
3697
  _this.isInAdTransition = false;
3581
3698
  if (!_this.inAdBreak) return;
3582
3699
  _this.currentAdIndex++;
3700
+ _this.trackAdLoaded();
3583
3701
  _this.adLayer.playPreloaded(token).catch(function(err) {
3584
3702
  if (_this.config.debugAdTiming) console.warn("[StormcloudVideoPlayer] playPreloaded failed:", err);
3585
3703
  _this.handleAdFailure();
@@ -3609,6 +3727,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3609
3727
  var freshBids = (_this_pendingNextAdBids = _this.pendingNextAdBids) !== null && _this_pendingNextAdBids !== void 0 ? _this_pendingNextAdBids : bids;
3610
3728
  _this.pendingNextAdBids = null;
3611
3729
  _this.currentAdIndex++;
3730
+ _this.trackAdLoaded(freshBids);
3612
3731
  _this.adLayer.playAd(freshBids).catch(function(err) {
3613
3732
  if (_this.config.debugAdTiming) console.warn("[StormcloudVideoPlayer] playAd(pending) failed:", err);
3614
3733
  _this.handleAdFailure();
@@ -3988,7 +4107,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3988
4107
  }, ((_this_pendingAdBreak1 = this.pendingAdBreak) === null || _this_pendingAdBreak1 === void 0 ? void 0 : _this_pendingAdBreak1.detectedAtFragmentSn) != null && {
3989
4108
  detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn
3990
4109
  });
3991
- sendAdDetectTracking(this.config.licenseKey, adDetectInfo);
4110
+ sendAdDetectTracking(this.config.licenseKey, adDetectInfo, this.getAnalyticsContext());
3992
4111
  }
3993
4112
  var isManifestMarker = this.isManifestBasedMarker(marker);
3994
4113
  var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
@@ -4057,6 +4176,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4057
4176
  var bids = this.pendingNextAdBids;
4058
4177
  this.pendingNextAdBids = null;
4059
4178
  this.currentAdIndex++;
4179
+ this.trackAdLoaded(bids);
4060
4180
  this.adLayer.playAd(bids).catch(function() {
4061
4181
  return _this.handleAdFailure();
4062
4182
  });
@@ -4311,7 +4431,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4311
4431
  key: "initializeTracking",
4312
4432
  value: function initializeTracking() {
4313
4433
  var _this = this;
4314
- sendInitialTracking(this.config.licenseKey).then(function() {
4434
+ sendInitialTracking(this.config.licenseKey, this.getAnalyticsContext()).then(function() {
4315
4435
  _this.heartbeatInterval = window.setInterval(function() {
4316
4436
  _this.sendHeartbeatIfNeeded();
4317
4437
  }, 5e3);
@@ -4332,7 +4452,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4332
4452
  var now = Date.now();
4333
4453
  if (!this.lastHeartbeatTime || now - this.lastHeartbeatTime > 3e4) {
4334
4454
  this.lastHeartbeatTime = now;
4335
- sendHeartbeat(this.config.licenseKey).catch(function(error) {
4455
+ sendHeartbeat(this.config.licenseKey, this.getAnalyticsContext()).catch(function(error) {
4336
4456
  if (_this.config.debugAdTiming) {
4337
4457
  console.warn("[StormcloudVideoPlayer] Failed to send heartbeat:", error);
4338
4458
  }
@@ -4725,12 +4845,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4725
4845
  10
4726
4846
  ];
4727
4847
  _this.currentAdIndex++;
4728
- if (_this.config.licenseKey) {
4729
- sendAdLoadedTracking(_this.config.licenseKey, {
4730
- source: _this.getAdSource(),
4731
- timestamp: /* @__PURE__ */ new Date().toISOString()
4732
- });
4733
- }
4848
+ _this.trackAdLoaded(bids1);
4734
4849
  return [
4735
4850
  4,
4736
4851
  _this.adLayer.playAd(bids1)
@@ -4835,12 +4950,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4835
4950
  ];
4836
4951
  case 18:
4837
4952
  _this.currentAdIndex++;
4838
- if (_this.config.licenseKey) {
4839
- sendAdLoadedTracking(_this.config.licenseKey, {
4840
- source: _this.getAdSource(),
4841
- timestamp: /* @__PURE__ */ new Date().toISOString()
4842
- });
4843
- }
4953
+ _this.trackAdLoaded(bids2);
4844
4954
  return [
4845
4955
  4,
4846
4956
  _this.adLayer.playAd(bids2)
@@ -4999,12 +5109,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4999
5109
  6
5000
5110
  ];
5001
5111
  this.currentAdIndex++;
5002
- if (this.config.licenseKey) {
5003
- sendAdLoadedTracking(this.config.licenseKey, {
5004
- source: this.getAdSource(),
5005
- timestamp: /* @__PURE__ */ new Date().toISOString()
5006
- });
5007
- }
5112
+ this.trackAdLoaded();
5008
5113
  _state.label = 1;
5009
5114
  case 1:
5010
5115
  _state.trys.push([
@@ -5198,12 +5303,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5198
5303
  5
5199
5304
  ];
5200
5305
  case 3:
5201
- if (this.config.licenseKey) {
5202
- sendAdLoadedTracking(this.config.licenseKey, {
5203
- source: this.getAdSource(),
5204
- timestamp: /* @__PURE__ */ new Date().toISOString()
5205
- });
5206
- }
5306
+ this.trackAdLoaded(bids);
5207
5307
  return [
5208
5308
  4,
5209
5309
  this.adLayer.playAd(bids)
@@ -5349,6 +5449,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5349
5449
  ,
5350
5450
  7
5351
5451
  ]);
5452
+ this.trackAdLoaded(bids);
5352
5453
  return [
5353
5454
  4,
5354
5455
  this.adLayer.playAd(bids)