stormcloud-video-player 0.8.4 → 0.8.6

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.
@@ -198,6 +198,7 @@ __export(hlsAdPlayer_exports, {
198
198
  });
199
199
  module.exports = __toCommonJS(hlsAdPlayer_exports);
200
200
  var import_hls = __toESM(require("hls.js"), 1);
201
+ var MAX_VAST_WRAPPER_DEPTH = 5;
201
202
  function createHlsAdPlayer(contentVideo, options) {
202
203
  var adPlaying = false;
203
204
  var originalMutedState = false;
@@ -355,25 +356,91 @@ function createHlsAdPlayer(contentVideo, options) {
355
356
  var url = mediaFile.url.toLowerCase();
356
357
  return type.startsWith("video/") || url.endsWith(".mp4") || url.includes(".mp4?");
357
358
  }
359
+ function createEmptyTrackingUrls() {
360
+ return {
361
+ impression: [],
362
+ start: [],
363
+ firstQuartile: [],
364
+ midpoint: [],
365
+ thirdQuartile: [],
366
+ complete: [],
367
+ mute: [],
368
+ unmute: [],
369
+ pause: [],
370
+ resume: [],
371
+ fullscreen: [],
372
+ exitFullscreen: [],
373
+ skip: [],
374
+ error: []
375
+ };
376
+ }
377
+ function extractTrackingUrls(xmlDoc) {
378
+ var trackingUrls = createEmptyTrackingUrls();
379
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
380
+ var _el_textContent;
381
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
382
+ if (url) trackingUrls.impression.push(url);
383
+ });
384
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
385
+ var _el_textContent;
386
+ var event = el.getAttribute("event");
387
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
388
+ if (event && url) {
389
+ var eventKey = event;
390
+ if (trackingUrls[eventKey]) {
391
+ trackingUrls[eventKey].push(url);
392
+ }
393
+ }
394
+ });
395
+ xmlDoc.querySelectorAll("Error").forEach(function(el) {
396
+ var _el_textContent;
397
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
398
+ if (url) trackingUrls.error.push(url);
399
+ });
400
+ return trackingUrls;
401
+ }
402
+ function mergeTrackingUrls(target, source) {
403
+ Object.keys(target).forEach(function(key) {
404
+ if (source[key] && source[key].length > 0) {
405
+ target[key] = target[key].concat(source[key]);
406
+ }
407
+ });
408
+ return target;
409
+ }
358
410
  function parseVastXml(xmlString) {
359
411
  try {
360
- var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
412
+ var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
361
413
  var parser = new DOMParser();
362
414
  var xmlDoc = parser.parseFromString(xmlString, "text/xml");
363
415
  var parserError = xmlDoc.querySelector("parsererror");
364
416
  if (parserError) {
365
417
  console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
366
- return null;
418
+ return {
419
+ type: "empty"
420
+ };
367
421
  }
368
422
  var adElement = xmlDoc.querySelector("Ad");
369
423
  if (!adElement) {
370
424
  console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
371
- return null;
425
+ return {
426
+ type: "empty"
427
+ };
372
428
  }
373
429
  var adId = adElement.getAttribute("id") || "unknown";
374
430
  var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
431
+ var clickThrough = (_xmlDoc_querySelector1 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector1.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
432
+ var wrapperUri = (_xmlDoc_querySelector2 = xmlDoc.querySelector("VASTAdTagURI")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent1 = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent1 === void 0 ? void 0 : _xmlDoc_querySelector_textContent1.trim();
433
+ if (wrapperUri) {
434
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
435
+ return {
436
+ type: "wrapper",
437
+ vastAdTagUri: wrapperUri,
438
+ trackingUrls: extractTrackingUrls(xmlDoc),
439
+ clickThrough: clickThrough
440
+ };
441
+ }
375
442
  var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
376
- var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
443
+ var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
377
444
  var durationParts = durationText.split(":");
378
445
  var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
379
446
  var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
@@ -413,57 +480,31 @@ function createHlsAdPlayer(contentVideo, options) {
413
480
  } else {
414
481
  console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
415
482
  }
416
- return null;
417
- }
418
- var trackingUrls = {
419
- impression: [],
420
- start: [],
421
- firstQuartile: [],
422
- midpoint: [],
423
- thirdQuartile: [],
424
- complete: [],
425
- mute: [],
426
- unmute: [],
427
- pause: [],
428
- resume: [],
429
- fullscreen: [],
430
- exitFullscreen: [],
431
- skip: [],
432
- error: []
433
- };
434
- xmlDoc.querySelectorAll("Impression").forEach(function(el) {
435
- var _el_textContent;
436
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
437
- if (url) trackingUrls.impression.push(url);
438
- });
439
- xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
440
- var _el_textContent;
441
- var event = el.getAttribute("event");
442
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
443
- if (event && url) {
444
- var eventKey = event;
445
- if (trackingUrls[eventKey]) {
446
- trackingUrls[eventKey].push(url);
447
- }
448
- }
449
- });
450
- var clickThrough = (_xmlDoc_querySelector2 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
483
+ return {
484
+ type: "empty"
485
+ };
486
+ }
451
487
  return {
452
- id: adId,
453
- title: title,
454
- duration: duration,
455
- mediaFiles: mediaFiles,
456
- trackingUrls: trackingUrls,
457
- clickThrough: clickThrough
488
+ type: "inline",
489
+ ad: {
490
+ id: adId,
491
+ title: title,
492
+ duration: duration,
493
+ mediaFiles: mediaFiles,
494
+ trackingUrls: extractTrackingUrls(xmlDoc),
495
+ clickThrough: clickThrough
496
+ }
458
497
  };
459
498
  } catch (error) {
460
499
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
461
- return null;
500
+ return {
501
+ type: "empty"
502
+ };
462
503
  }
463
504
  }
464
- function fetchAndParseVastAd(vastTagUrl) {
505
+ function fetchVastXml(vastTagUrl) {
465
506
  return _async_to_generator(function() {
466
- var response, vastXml;
507
+ var response;
467
508
  return _ts_generator(this, function(_state) {
468
509
  switch(_state.label){
469
510
  case 0:
@@ -484,20 +525,58 @@ function createHlsAdPlayer(contentVideo, options) {
484
525
  throw new Error("Failed to fetch VAST: ".concat(response.statusText));
485
526
  }
486
527
  return [
487
- 4,
528
+ 2,
488
529
  response.text()
489
530
  ];
490
- case 2:
531
+ }
532
+ });
533
+ })();
534
+ }
535
+ function fetchAndParseVastAd(_0) {
536
+ return _async_to_generator(function(vastTagUrl) {
537
+ var depth, accumulatedTracking, vastXml, parsed;
538
+ var _arguments = arguments;
539
+ return _ts_generator(this, function(_state) {
540
+ switch(_state.label){
541
+ case 0:
542
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
543
+ return [
544
+ 4,
545
+ fetchVastXml(vastTagUrl)
546
+ ];
547
+ case 1:
491
548
  vastXml = _state.sent();
492
549
  console.log("[HlsAdPlayer] VAST XML received");
493
550
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
551
+ parsed = parseVastXml(vastXml);
552
+ if (parsed.type === "empty") {
553
+ return [
554
+ 2,
555
+ null
556
+ ];
557
+ }
558
+ if (parsed.type === "wrapper") {
559
+ if (depth >= MAX_VAST_WRAPPER_DEPTH) {
560
+ console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
561
+ return [
562
+ 2,
563
+ null
564
+ ];
565
+ }
566
+ mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
567
+ return [
568
+ 2,
569
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
570
+ ];
571
+ }
572
+ mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
494
573
  return [
495
574
  2,
496
- parseVastXml(vastXml)
575
+ parsed.ad
497
576
  ];
498
577
  }
499
578
  });
500
- })();
579
+ }).apply(this, arguments);
501
580
  }
502
581
  function createAdVideoElement() {
503
582
  var video = document.createElement("video");