stormcloud-video-player 0.3.14 → 0.3.17

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.
Files changed (36) hide show
  1. package/dist/stormcloud-vp.min.js +1 -10
  2. package/lib/index.cjs +8282 -6531
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.d.cts +2 -0
  5. package/lib/index.d.ts +2 -0
  6. package/lib/index.js +8112 -6495
  7. package/lib/index.js.map +1 -1
  8. package/lib/player/StormcloudVideoPlayer.cjs +5575 -3981
  9. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  10. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  11. package/lib/players/FilePlayer.cjs +556 -225
  12. package/lib/players/FilePlayer.cjs.map +1 -1
  13. package/lib/players/HlsPlayer.cjs +5845 -4163
  14. package/lib/players/HlsPlayer.cjs.map +1 -1
  15. package/lib/players/HlsPlayer.d.cts +1 -1
  16. package/lib/players/index.cjs +6142 -4371
  17. package/lib/players/index.cjs.map +1 -1
  18. package/lib/sdk/hlsAdPlayer.cjs +954 -699
  19. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  20. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  21. package/lib/sdk/ima.cjs +1034 -809
  22. package/lib/sdk/ima.cjs.map +1 -1
  23. package/lib/sdk/ima.d.cts +1 -1
  24. package/lib/{types-t9jEJXZy.d.cts → types-CryTJVCC.d.cts} +1 -0
  25. package/lib/ui/StormcloudVideoPlayer.cjs +6992 -5561
  26. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  27. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  28. package/lib/utils/browserCompat.cjs +241 -194
  29. package/lib/utils/browserCompat.cjs.map +1 -1
  30. package/lib/utils/polyfills.cjs +379 -214
  31. package/lib/utils/polyfills.cjs.map +1 -1
  32. package/lib/utils/tracking.cjs +559 -257
  33. package/lib/utils/tracking.cjs.map +1 -1
  34. package/lib/utils/tracking.d.cts +1 -1
  35. package/package.json +6 -1
  36. package/rollup.config.js +22 -0
@@ -1,741 +1,996 @@
1
1
  "use strict";
2
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
3
+ try {
4
+ var info = gen[key](arg);
5
+ var value = info.value;
6
+ } catch (error) {
7
+ reject(error);
8
+ return;
9
+ }
10
+ if (info.done) {
11
+ resolve(value);
12
+ } else {
13
+ Promise.resolve(value).then(_next, _throw);
14
+ }
15
+ }
16
+ function _async_to_generator(fn) {
17
+ return function() {
18
+ var self = this, args = arguments;
19
+ return new Promise(function(resolve, reject) {
20
+ var gen = fn.apply(self, args);
21
+ function _next(value) {
22
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
23
+ }
24
+ function _throw(err) {
25
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
26
+ }
27
+ _next(undefined);
28
+ });
29
+ };
30
+ }
31
+ function _type_of(obj) {
32
+ "@swc/helpers - typeof";
33
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
34
+ }
35
+ function _ts_generator(thisArg, body) {
36
+ var f, y, t, _ = {
37
+ label: 0,
38
+ sent: function() {
39
+ if (t[0] & 1) throw t[1];
40
+ return t[1];
41
+ },
42
+ trys: [],
43
+ ops: []
44
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
45
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
46
+ return this;
47
+ }), g;
48
+ function verb(n) {
49
+ return function(v) {
50
+ return step([
51
+ n,
52
+ v
53
+ ]);
54
+ };
55
+ }
56
+ function step(op) {
57
+ if (f) throw new TypeError("Generator is already executing.");
58
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
59
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
60
+ if (y = 0, t) op = [
61
+ op[0] & 2,
62
+ t.value
63
+ ];
64
+ switch(op[0]){
65
+ case 0:
66
+ case 1:
67
+ t = op;
68
+ break;
69
+ case 4:
70
+ _.label++;
71
+ return {
72
+ value: op[1],
73
+ done: false
74
+ };
75
+ case 5:
76
+ _.label++;
77
+ y = op[1];
78
+ op = [
79
+ 0
80
+ ];
81
+ continue;
82
+ case 7:
83
+ op = _.ops.pop();
84
+ _.trys.pop();
85
+ continue;
86
+ default:
87
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
88
+ _ = 0;
89
+ continue;
90
+ }
91
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
92
+ _.label = op[1];
93
+ break;
94
+ }
95
+ if (op[0] === 6 && _.label < t[1]) {
96
+ _.label = t[1];
97
+ t = op;
98
+ break;
99
+ }
100
+ if (t && _.label < t[2]) {
101
+ _.label = t[2];
102
+ _.ops.push(op);
103
+ break;
104
+ }
105
+ if (t[2]) _.ops.pop();
106
+ _.trys.pop();
107
+ continue;
108
+ }
109
+ op = body.call(thisArg, _);
110
+ } catch (e) {
111
+ op = [
112
+ 6,
113
+ e
114
+ ];
115
+ y = 0;
116
+ } finally{
117
+ f = t = 0;
118
+ }
119
+ if (op[0] & 5) throw op[1];
120
+ return {
121
+ value: op[0] ? op[1] : void 0,
122
+ done: true
123
+ };
124
+ }
125
+ }
2
126
  var __create = Object.create;
3
127
  var __defProp = Object.defineProperty;
4
128
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
129
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
130
  var __getProtoOf = Object.getPrototypeOf;
7
131
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
132
+ var __export = function(target, all) {
133
+ for(var name in all)__defProp(target, name, {
134
+ get: all[name],
135
+ enumerable: true
136
+ });
11
137
  };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
138
+ var __copyProps = function(to, from, except, desc) {
139
+ if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
140
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
141
+ try {
142
+ var _loop = function() {
143
+ var key = _step.value;
144
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
145
+ get: function() {
146
+ return from[key];
147
+ },
148
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
149
+ });
150
+ };
151
+ for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
152
+ } catch (err) {
153
+ _didIteratorError = true;
154
+ _iteratorError = err;
155
+ } finally{
156
+ try {
157
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
158
+ _iterator.return();
159
+ }
160
+ } finally{
161
+ if (_didIteratorError) {
162
+ throw _iteratorError;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ return to;
168
+ };
169
+ var __toESM = function(mod, isNodeMode, target) {
170
+ return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
171
+ // file that has been converted to a CommonJS file using a Babel-
172
+ // compatible transform (i.e. "__esModule" has not been set), then set
173
+ // "default" to the CommonJS "module.exports" for node compatibility.
174
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
175
+ value: mod,
176
+ enumerable: true
177
+ }) : target, mod);
178
+ };
179
+ var __toCommonJS = function(mod) {
180
+ return __copyProps(__defProp({}, "__esModule", {
181
+ value: true
182
+ }), mod);
19
183
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
184
  // src/sdk/hlsAdPlayer.ts
31
185
  var hlsAdPlayer_exports = {};
32
186
  __export(hlsAdPlayer_exports, {
33
- createHlsAdPlayer: () => createHlsAdPlayer
187
+ createHlsAdPlayer: function() {
188
+ return createHlsAdPlayer;
189
+ }
34
190
  });
35
191
  module.exports = __toCommonJS(hlsAdPlayer_exports);
36
192
  var import_hls = __toESM(require("hls.js"), 1);
37
193
  function createHlsAdPlayer(contentVideo, options) {
38
- let adPlaying = false;
39
- let originalMutedState = false;
40
- let originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
41
- const listeners = /* @__PURE__ */ new Map();
42
- const licenseKey = options == null ? void 0 : options.licenseKey;
43
- const mainHlsInstance = options == null ? void 0 : options.mainHlsInstance;
44
- let adVideoElement;
45
- let adHls;
46
- let adContainerEl;
47
- let currentAd;
48
- let sessionId;
49
- const preloadedAds = /* @__PURE__ */ new Map();
50
- const preloadingAds = /* @__PURE__ */ new Map();
51
- let destroyed = false;
52
- let pendingTimeouts = [];
53
- let trackingFired = {
54
- impression: false,
55
- start: false,
56
- firstQuartile: false,
57
- midpoint: false,
58
- thirdQuartile: false,
59
- complete: false
60
- };
61
- function emit(event, payload) {
62
- const set = listeners.get(event);
63
- if (!set) return;
64
- for (const fn of Array.from(set)) {
65
- try {
66
- fn(payload);
67
- } catch (error) {
68
- console.warn(
69
- `[HlsAdPlayer] Error in event listener for ${event}:`,
70
- error
71
- );
72
- }
194
+ var adPlaying = false;
195
+ var originalMutedState = false;
196
+ var originalVolume = Math.max(0, Math.min(1, contentVideo.volume || 1));
197
+ var listeners = /* @__PURE__ */ new Map();
198
+ var licenseKey = options === null || options === void 0 ? void 0 : options.licenseKey;
199
+ var mainHlsInstance = options === null || options === void 0 ? void 0 : options.mainHlsInstance;
200
+ var adVideoElement;
201
+ var adHls;
202
+ var adContainerEl;
203
+ var currentAd;
204
+ var sessionId;
205
+ var preloadedAds = /* @__PURE__ */ new Map();
206
+ var preloadingAds = /* @__PURE__ */ new Map();
207
+ var destroyed = false;
208
+ var pendingTimeouts = [];
209
+ var trackingFired = {
210
+ impression: false,
211
+ start: false,
212
+ firstQuartile: false,
213
+ midpoint: false,
214
+ thirdQuartile: false,
215
+ complete: false
216
+ };
217
+ function emit(event, payload) {
218
+ var set = listeners.get(event);
219
+ if (!set) return;
220
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
221
+ try {
222
+ for(var _iterator = Array.from(set)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
223
+ var fn = _step.value;
224
+ try {
225
+ fn(payload);
226
+ } catch (error) {
227
+ console.warn("[HlsAdPlayer] Error in event listener for ".concat(event, ":"), error);
228
+ }
229
+ }
230
+ } catch (err) {
231
+ _didIteratorError = true;
232
+ _iteratorError = err;
233
+ } finally{
234
+ try {
235
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
236
+ _iterator.return();
237
+ }
238
+ } finally{
239
+ if (_didIteratorError) {
240
+ throw _iteratorError;
241
+ }
242
+ }
243
+ }
244
+ }
245
+ function generateSessionId() {
246
+ return "session-".concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9));
247
+ }
248
+ function fireTrackingPixels(urls) {
249
+ if (!urls || urls.length === 0) return;
250
+ urls.forEach(function(url) {
251
+ try {
252
+ var trackingUrl = url;
253
+ if (sessionId) {
254
+ trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "session_id=").concat(sessionId);
255
+ }
256
+ if (licenseKey) {
257
+ trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "license_key=").concat(licenseKey);
258
+ }
259
+ var img = new Image(1, 1);
260
+ img.src = trackingUrl;
261
+ console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingUrl));
262
+ } catch (error) {
263
+ console.warn("[HlsAdPlayer] Error firing tracking pixel:", error);
264
+ }
265
+ });
73
266
  }
74
- }
75
- function generateSessionId() {
76
- return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
77
- }
78
- function fireTrackingPixels(urls) {
79
- if (!urls || urls.length === 0) return;
80
- urls.forEach((url) => {
81
- try {
82
- let trackingUrl = url;
83
- if (sessionId) {
84
- trackingUrl = `${trackingUrl}${trackingUrl.includes("?") ? "&" : "?"}session_id=${sessionId}`;
267
+ function getMainStreamQuality() {
268
+ if (!mainHlsInstance || !mainHlsInstance.levels) {
269
+ return null;
85
270
  }
86
- if (licenseKey) {
87
- trackingUrl = `${trackingUrl}${trackingUrl.includes("?") ? "&" : "?"}license_key=${licenseKey}`;
271
+ var currentLevel = mainHlsInstance.currentLevel;
272
+ if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
273
+ var autoLevel = mainHlsInstance.loadLevel;
274
+ if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
275
+ var level2 = mainHlsInstance.levels[autoLevel];
276
+ return {
277
+ width: level2.width || 1920,
278
+ height: level2.height || 1080,
279
+ bitrate: level2.bitrate || 5e6
280
+ };
281
+ }
282
+ return null;
88
283
  }
89
- const img = new Image(1, 1);
90
- img.src = trackingUrl;
91
- console.log(`[HlsAdPlayer] Fired tracking pixel: ${trackingUrl}`);
92
- } catch (error) {
93
- console.warn(`[HlsAdPlayer] Error firing tracking pixel:`, error);
94
- }
95
- });
96
- }
97
- function getMainStreamQuality() {
98
- if (!mainHlsInstance || !mainHlsInstance.levels) {
99
- return null;
100
- }
101
- const currentLevel = mainHlsInstance.currentLevel;
102
- if (currentLevel === -1 || !mainHlsInstance.levels[currentLevel]) {
103
- const autoLevel = mainHlsInstance.loadLevel;
104
- if (autoLevel !== -1 && mainHlsInstance.levels[autoLevel]) {
105
- const level2 = mainHlsInstance.levels[autoLevel];
284
+ var level = mainHlsInstance.levels[currentLevel];
106
285
  return {
107
- width: level2.width || 1920,
108
- height: level2.height || 1080,
109
- bitrate: level2.bitrate || 5e6
286
+ width: level.width || 1920,
287
+ height: level.height || 1080,
288
+ bitrate: level.bitrate || 5e6
110
289
  };
111
- }
112
- return null;
113
- }
114
- const level = mainHlsInstance.levels[currentLevel];
115
- return {
116
- width: level.width || 1920,
117
- height: level.height || 1080,
118
- bitrate: level.bitrate || 5e6
119
- };
120
- }
121
- function selectBestMediaFile(mediaFiles) {
122
- if (mediaFiles.length === 0) {
123
- throw new Error("No media files available");
124
- }
125
- const firstFile = mediaFiles[0];
126
- if (!firstFile) {
127
- throw new Error("No media files available");
128
- }
129
- if (mediaFiles.length === 1) {
130
- return firstFile;
131
- }
132
- const mainQuality = getMainStreamQuality();
133
- if (!mainQuality) {
134
- console.log(
135
- "[HlsAdPlayer] No main stream quality info, using first media file"
136
- );
137
- return firstFile;
138
- }
139
- console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
140
- const scoredFiles = mediaFiles.map((file) => {
141
- const widthDiff = Math.abs(file.width - mainQuality.width);
142
- const heightDiff = Math.abs(file.height - mainQuality.height);
143
- const resolutionDiff = widthDiff + heightDiff;
144
- const fileBitrate = (file.bitrate || 5e3) * 1e3;
145
- const bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
146
- const score = resolutionDiff * 2 + bitrateDiff / 1e3;
147
- return { file, score, resolutionDiff, bitrateDiff };
148
- });
149
- scoredFiles.sort((a, b) => a.score - b.score);
150
- const bestMatch = scoredFiles[0];
151
- if (!bestMatch) {
152
- console.log("[HlsAdPlayer] No best match found, using first media file");
153
- return firstFile;
154
290
  }
155
- console.log("[HlsAdPlayer] Selected media file:", {
156
- url: bestMatch.file.url,
157
- resolution: `${bestMatch.file.width}x${bestMatch.file.height}`,
158
- bitrate: bestMatch.file.bitrate,
159
- score: bestMatch.score,
160
- resolutionDiff: bestMatch.resolutionDiff,
161
- bitrateDiff: bestMatch.bitrateDiff
162
- });
163
- return bestMatch.file;
164
- }
165
- function parseVastXml(xmlString) {
166
- var _a, _b, _c, _d;
167
- try {
168
- const parser = new DOMParser();
169
- const xmlDoc = parser.parseFromString(xmlString, "text/xml");
170
- const parserError = xmlDoc.querySelector("parsererror");
171
- if (parserError) {
172
- console.error(
173
- "[HlsAdPlayer] XML parsing error (malformed VAST XML):",
174
- parserError.textContent
175
- );
176
- return null;
177
- }
178
- const adElement = xmlDoc.querySelector("Ad");
179
- if (!adElement) {
180
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
181
- return null;
182
- }
183
- const adId = adElement.getAttribute("id") || "unknown";
184
- const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
185
- const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
186
- const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
187
- const durationParts = durationText.split(":");
188
- const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
189
- const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
190
- const mediaFiles = [];
191
- console.log(
192
- `[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`
193
- );
194
- mediaFileElements.forEach((mf, index) => {
195
- var _a2;
196
- const type = mf.getAttribute("type") || "";
197
- const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
198
- const width = mf.getAttribute("width") || "";
199
- const height = mf.getAttribute("height") || "";
200
- console.log(
201
- `[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`
202
- );
203
- if (type === "application/x-mpegURL" || type.includes("m3u8")) {
204
- if (!url) {
205
- console.warn(
206
- `[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`
207
- );
208
- return;
209
- }
210
- const bitrateAttr = mf.getAttribute("bitrate");
211
- const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
212
- mediaFiles.push({
213
- url,
214
- type,
215
- width: parseInt(width || "1920", 10),
216
- height: parseInt(height || "1080", 10),
217
- bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
218
- });
219
- console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
220
- } else {
221
- console.log(
222
- `[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`
223
- );
291
+ function selectBestMediaFile(mediaFiles) {
292
+ if (mediaFiles.length === 0) {
293
+ throw new Error("No media files available");
224
294
  }
225
- });
226
- if (mediaFiles.length === 0) {
227
- if (isNoAdAvailable) {
228
- console.warn(
229
- "[HlsAdPlayer] No ads available (VAST response indicates no ads)"
230
- );
231
- } else {
232
- console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
295
+ var firstFile = mediaFiles[0];
296
+ if (!firstFile) {
297
+ throw new Error("No media files available");
233
298
  }
234
- return null;
235
- }
236
- const trackingUrls = {
237
- impression: [],
238
- start: [],
239
- firstQuartile: [],
240
- midpoint: [],
241
- thirdQuartile: [],
242
- complete: [],
243
- mute: [],
244
- unmute: [],
245
- pause: [],
246
- resume: [],
247
- fullscreen: [],
248
- exitFullscreen: [],
249
- skip: [],
250
- error: []
251
- };
252
- xmlDoc.querySelectorAll("Impression").forEach((el) => {
253
- var _a2;
254
- const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
255
- if (url) trackingUrls.impression.push(url);
256
- });
257
- xmlDoc.querySelectorAll("Tracking").forEach((el) => {
258
- var _a2;
259
- const event = el.getAttribute("event");
260
- const url = (_a2 = el.textContent) == null ? void 0 : _a2.trim();
261
- if (event && url) {
262
- const eventKey = event;
263
- if (trackingUrls[eventKey]) {
264
- trackingUrls[eventKey].push(url);
265
- }
299
+ if (mediaFiles.length === 1) {
300
+ return firstFile;
266
301
  }
267
- });
268
- const clickThrough = (_d = (_c = xmlDoc.querySelector("ClickThrough")) == null ? void 0 : _c.textContent) == null ? void 0 : _d.trim();
269
- return {
270
- id: adId,
271
- title,
272
- duration,
273
- mediaFiles,
274
- trackingUrls,
275
- clickThrough
276
- };
277
- } catch (error) {
278
- console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
279
- return null;
302
+ var mainQuality = getMainStreamQuality();
303
+ if (!mainQuality) {
304
+ console.log("[HlsAdPlayer] No main stream quality info, using first media file");
305
+ return firstFile;
306
+ }
307
+ console.log("[HlsAdPlayer] Main stream quality:", mainQuality);
308
+ var scoredFiles = mediaFiles.map(function(file) {
309
+ var widthDiff = Math.abs(file.width - mainQuality.width);
310
+ var heightDiff = Math.abs(file.height - mainQuality.height);
311
+ var resolutionDiff = widthDiff + heightDiff;
312
+ var fileBitrate = (file.bitrate || 5e3) * 1e3;
313
+ var bitrateDiff = Math.abs(fileBitrate - mainQuality.bitrate);
314
+ var score = resolutionDiff * 2 + bitrateDiff / 1e3;
315
+ return {
316
+ file: file,
317
+ score: score,
318
+ resolutionDiff: resolutionDiff,
319
+ bitrateDiff: bitrateDiff
320
+ };
321
+ });
322
+ scoredFiles.sort(function(a, b) {
323
+ return a.score - b.score;
324
+ });
325
+ var bestMatch = scoredFiles[0];
326
+ if (!bestMatch) {
327
+ console.log("[HlsAdPlayer] No best match found, using first media file");
328
+ return firstFile;
329
+ }
330
+ console.log("[HlsAdPlayer] Selected media file:", {
331
+ url: bestMatch.file.url,
332
+ resolution: "".concat(bestMatch.file.width, "x").concat(bestMatch.file.height),
333
+ bitrate: bestMatch.file.bitrate,
334
+ score: bestMatch.score,
335
+ resolutionDiff: bestMatch.resolutionDiff,
336
+ bitrateDiff: bestMatch.bitrateDiff
337
+ });
338
+ return bestMatch.file;
280
339
  }
281
- }
282
- async function fetchAndParseVastAd(vastTagUrl) {
283
- const response = await fetch(vastTagUrl);
284
- if (!response.ok) {
285
- throw new Error(`Failed to fetch VAST: ${response.statusText}`);
340
+ function parseVastXml(xmlString) {
341
+ try {
342
+ var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
343
+ var parser = new DOMParser();
344
+ var xmlDoc = parser.parseFromString(xmlString, "text/xml");
345
+ var parserError = xmlDoc.querySelector("parsererror");
346
+ if (parserError) {
347
+ console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
348
+ return null;
349
+ }
350
+ var adElement = xmlDoc.querySelector("Ad");
351
+ if (!adElement) {
352
+ console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
353
+ return null;
354
+ }
355
+ var adId = adElement.getAttribute("id") || "unknown";
356
+ var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
357
+ var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
358
+ var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
359
+ var durationParts = durationText.split(":");
360
+ var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
361
+ var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
362
+ var mediaFiles = [];
363
+ console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
364
+ mediaFileElements.forEach(function(mf, index) {
365
+ var _mf_textContent;
366
+ var type = mf.getAttribute("type") || "";
367
+ var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
368
+ var width = mf.getAttribute("width") || "";
369
+ var height = mf.getAttribute("height") || "";
370
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
371
+ if (type === "application/x-mpegURL" || type.includes("m3u8")) {
372
+ if (!url) {
373
+ console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
374
+ return;
375
+ }
376
+ var bitrateAttr = mf.getAttribute("bitrate");
377
+ var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
378
+ mediaFiles.push({
379
+ url: url,
380
+ type: type,
381
+ width: parseInt(width || "1920", 10),
382
+ height: parseInt(height || "1080", 10),
383
+ bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
384
+ });
385
+ console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
386
+ } else {
387
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
388
+ }
389
+ });
390
+ if (mediaFiles.length === 0) {
391
+ if (isNoAdAvailable) {
392
+ console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
393
+ } else {
394
+ console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
395
+ }
396
+ return null;
397
+ }
398
+ var trackingUrls = {
399
+ impression: [],
400
+ start: [],
401
+ firstQuartile: [],
402
+ midpoint: [],
403
+ thirdQuartile: [],
404
+ complete: [],
405
+ mute: [],
406
+ unmute: [],
407
+ pause: [],
408
+ resume: [],
409
+ fullscreen: [],
410
+ exitFullscreen: [],
411
+ skip: [],
412
+ error: []
413
+ };
414
+ xmlDoc.querySelectorAll("Impression").forEach(function(el) {
415
+ var _el_textContent;
416
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
417
+ if (url) trackingUrls.impression.push(url);
418
+ });
419
+ xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
420
+ var _el_textContent;
421
+ var event = el.getAttribute("event");
422
+ var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
423
+ if (event && url) {
424
+ var eventKey = event;
425
+ if (trackingUrls[eventKey]) {
426
+ trackingUrls[eventKey].push(url);
427
+ }
428
+ }
429
+ });
430
+ 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();
431
+ return {
432
+ id: adId,
433
+ title: title,
434
+ duration: duration,
435
+ mediaFiles: mediaFiles,
436
+ trackingUrls: trackingUrls,
437
+ clickThrough: clickThrough
438
+ };
439
+ } catch (error) {
440
+ console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
441
+ return null;
442
+ }
286
443
  }
287
- const vastXml = await response.text();
288
- console.log("[HlsAdPlayer] VAST XML received");
289
- console.log(
290
- "[HlsAdPlayer] VAST XML content (first 2000 chars):",
291
- vastXml.substring(0, 2e3)
292
- );
293
- return parseVastXml(vastXml);
294
- }
295
- function createAdVideoElement() {
296
- const video = document.createElement("video");
297
- video.style.position = "absolute";
298
- video.style.left = "0";
299
- video.style.top = "0";
300
- video.style.width = "100%";
301
- video.style.height = "100%";
302
- video.style.objectFit = "contain";
303
- video.style.backgroundColor = "#000";
304
- video.playsInline = true;
305
- video.muted = false;
306
- video.volume = 1;
307
- console.log(
308
- `[HlsAdPlayer] Created ad video element with volume ${video.volume}`
309
- );
310
- return video;
311
- }
312
- function setupAdEventListeners() {
313
- if (!adVideoElement || !currentAd) return;
314
- adVideoElement.addEventListener("timeupdate", () => {
315
- if (!currentAd || !adVideoElement) return;
316
- const progress = adVideoElement.currentTime / currentAd.duration;
317
- if (progress >= 0.25 && !trackingFired.firstQuartile) {
318
- trackingFired.firstQuartile = true;
319
- fireTrackingPixels(currentAd.trackingUrls.firstQuartile);
320
- }
321
- if (progress >= 0.5 && !trackingFired.midpoint) {
322
- trackingFired.midpoint = true;
323
- fireTrackingPixels(currentAd.trackingUrls.midpoint);
324
- }
325
- if (progress >= 0.75 && !trackingFired.thirdQuartile) {
326
- trackingFired.thirdQuartile = true;
327
- fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);
328
- }
329
- });
330
- adVideoElement.addEventListener("playing", () => {
331
- if (!currentAd || trackingFired.start) return;
332
- trackingFired.start = true;
333
- fireTrackingPixels(currentAd.trackingUrls.start);
334
- console.log("[HlsAdPlayer] Ad started playing");
335
- });
336
- adVideoElement.addEventListener("ended", () => {
337
- if (!currentAd || trackingFired.complete) return;
338
- trackingFired.complete = true;
339
- fireTrackingPixels(currentAd.trackingUrls.complete);
340
- console.log("[HlsAdPlayer] Ad completed");
341
- handleAdComplete();
342
- });
343
- adVideoElement.addEventListener("error", (e) => {
344
- console.error("[HlsAdPlayer] Ad video error:", e);
345
- if (currentAd) {
346
- fireTrackingPixels(currentAd.trackingUrls.error);
347
- }
348
- handleAdError();
349
- });
350
- adVideoElement.addEventListener("volumechange", () => {
351
- if (!currentAd) return;
352
- if (adVideoElement.muted) {
353
- fireTrackingPixels(currentAd.trackingUrls.mute);
354
- } else {
355
- fireTrackingPixels(currentAd.trackingUrls.unmute);
356
- }
357
- });
358
- adVideoElement.addEventListener("pause", () => {
359
- if (currentAd && !adVideoElement.ended) {
360
- fireTrackingPixels(currentAd.trackingUrls.pause);
361
- }
362
- });
363
- adVideoElement.addEventListener("play", () => {
364
- if (currentAd && adVideoElement.currentTime > 0) {
365
- fireTrackingPixels(currentAd.trackingUrls.resume);
366
- }
367
- });
368
- }
369
- function setAdPlayingFlag(isPlaying) {
370
- if (isPlaying) {
371
- contentVideo.dataset.stormcloudAdPlaying = "true";
372
- } else {
373
- delete contentVideo.dataset.stormcloudAdPlaying;
444
+ function fetchAndParseVastAd(vastTagUrl) {
445
+ return _async_to_generator(function() {
446
+ var response, vastXml;
447
+ return _ts_generator(this, function(_state) {
448
+ switch(_state.label){
449
+ case 0:
450
+ return [
451
+ 4,
452
+ fetch(vastTagUrl)
453
+ ];
454
+ case 1:
455
+ response = _state.sent();
456
+ if (!response.ok) {
457
+ throw new Error("Failed to fetch VAST: ".concat(response.statusText));
458
+ }
459
+ return [
460
+ 4,
461
+ response.text()
462
+ ];
463
+ case 2:
464
+ vastXml = _state.sent();
465
+ console.log("[HlsAdPlayer] VAST XML received");
466
+ console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
467
+ return [
468
+ 2,
469
+ parseVastXml(vastXml)
470
+ ];
471
+ }
472
+ });
473
+ })();
374
474
  }
375
- }
376
- function handleAdComplete() {
377
- console.log("[HlsAdPlayer] Handling ad completion");
378
- adPlaying = false;
379
- setAdPlayingFlag(false);
380
- emit("content_resume");
381
- const timeoutId = window.setTimeout(() => {
382
- if (destroyed) {
383
- console.log("[HlsAdPlayer] Player destroyed, skipping post-completion check");
384
- return;
385
- }
386
- const stillInPod = contentVideo.dataset.stormcloudAdPlaying === "true";
387
- if (stillInPod) {
388
- console.log(
389
- "[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)"
390
- );
391
- if (adContainerEl) {
392
- adContainerEl.style.display = "flex";
393
- adContainerEl.style.pointerEvents = "auto";
394
- }
395
- }
396
- const idx = pendingTimeouts.indexOf(timeoutId);
397
- if (idx !== -1) {
398
- pendingTimeouts.splice(idx, 1);
399
- }
400
- }, 50);
401
- pendingTimeouts.push(timeoutId);
402
- }
403
- function handleAdError() {
404
- console.log("[HlsAdPlayer] Handling ad error");
405
- adPlaying = false;
406
- setAdPlayingFlag(false);
407
- const previousMutedState = contentVideo.muted;
408
- contentVideo.muted = originalMutedState;
409
- contentVideo.volume = originalMutedState ? 0 : originalVolume;
410
- console.log(
411
- `[HlsAdPlayer] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
412
- );
413
- if (adContainerEl) {
414
- adContainerEl.style.display = "none";
415
- adContainerEl.style.pointerEvents = "none";
475
+ function createAdVideoElement() {
476
+ var video = document.createElement("video");
477
+ video.style.position = "absolute";
478
+ video.style.left = "0";
479
+ video.style.top = "0";
480
+ video.style.width = "100%";
481
+ video.style.height = "100%";
482
+ video.style.objectFit = "contain";
483
+ video.style.backgroundColor = "#000";
484
+ video.playsInline = true;
485
+ video.muted = false;
486
+ video.volume = 1;
487
+ console.log("[HlsAdPlayer] Created ad video element with volume ".concat(video.volume));
488
+ return video;
416
489
  }
417
- if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
418
- if (contentVideo.paused) {
419
- contentVideo.play().catch(() => {
490
+ function setupAdEventListeners() {
491
+ if (!adVideoElement || !currentAd) return;
492
+ adVideoElement.addEventListener("timeupdate", function() {
493
+ if (!currentAd || !adVideoElement) return;
494
+ var progress = adVideoElement.currentTime / currentAd.duration;
495
+ if (progress >= 0.25 && !trackingFired.firstQuartile) {
496
+ trackingFired.firstQuartile = true;
497
+ fireTrackingPixels(currentAd.trackingUrls.firstQuartile);
498
+ }
499
+ if (progress >= 0.5 && !trackingFired.midpoint) {
500
+ trackingFired.midpoint = true;
501
+ fireTrackingPixels(currentAd.trackingUrls.midpoint);
502
+ }
503
+ if (progress >= 0.75 && !trackingFired.thirdQuartile) {
504
+ trackingFired.thirdQuartile = true;
505
+ fireTrackingPixels(currentAd.trackingUrls.thirdQuartile);
506
+ }
507
+ });
508
+ adVideoElement.addEventListener("playing", function() {
509
+ if (!currentAd || trackingFired.start) return;
510
+ trackingFired.start = true;
511
+ fireTrackingPixels(currentAd.trackingUrls.start);
512
+ console.log("[HlsAdPlayer] Ad started playing");
513
+ });
514
+ adVideoElement.addEventListener("ended", function() {
515
+ if (!currentAd || trackingFired.complete) return;
516
+ trackingFired.complete = true;
517
+ fireTrackingPixels(currentAd.trackingUrls.complete);
518
+ console.log("[HlsAdPlayer] Ad completed");
519
+ handleAdComplete();
520
+ });
521
+ adVideoElement.addEventListener("error", function(e) {
522
+ console.error("[HlsAdPlayer] Ad video error:", e);
523
+ if (currentAd) {
524
+ fireTrackingPixels(currentAd.trackingUrls.error);
525
+ }
526
+ handleAdError();
527
+ });
528
+ adVideoElement.addEventListener("volumechange", function() {
529
+ if (!currentAd) return;
530
+ if (adVideoElement.muted) {
531
+ fireTrackingPixels(currentAd.trackingUrls.mute);
532
+ } else {
533
+ fireTrackingPixels(currentAd.trackingUrls.unmute);
534
+ }
535
+ });
536
+ adVideoElement.addEventListener("pause", function() {
537
+ if (currentAd && !adVideoElement.ended) {
538
+ fireTrackingPixels(currentAd.trackingUrls.pause);
539
+ }
540
+ });
541
+ adVideoElement.addEventListener("play", function() {
542
+ if (currentAd && adVideoElement.currentTime > 0) {
543
+ fireTrackingPixels(currentAd.trackingUrls.resume);
544
+ }
420
545
  });
421
- }
422
546
  }
423
- emit("ad_error");
424
- }
425
- return {
426
- initialize() {
427
- var _a;
428
- console.log("[HlsAdPlayer] Initializing");
429
- if (!adContainerEl) {
430
- const container = document.createElement("div");
431
- container.style.position = "absolute";
432
- container.style.left = "0";
433
- container.style.top = "0";
434
- container.style.right = "0";
435
- container.style.bottom = "0";
436
- container.style.display = "none";
437
- container.style.alignItems = "center";
438
- container.style.justifyContent = "center";
439
- container.style.pointerEvents = "none";
440
- container.style.zIndex = "10";
441
- container.style.backgroundColor = "#000";
442
- (_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
443
- adContainerEl = container;
444
- }
445
- },
446
- async requestAds(vastTagUrl) {
447
- console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
448
- if (adPlaying) {
449
- console.warn(
450
- "[HlsAdPlayer] Cannot request new ads while an ad is playing"
451
- );
452
- return Promise.reject(new Error("Ad already playing"));
453
- }
454
- try {
455
- sessionId = generateSessionId();
456
- let ad;
457
- if (preloadedAds.has(vastTagUrl)) {
458
- ad = preloadedAds.get(vastTagUrl);
459
- preloadedAds.delete(vastTagUrl);
460
- console.log(
461
- "[HlsAdPlayer] Using preloaded VAST response:",
462
- vastTagUrl
463
- );
464
- } else {
465
- ad = await fetchAndParseVastAd(vastTagUrl);
466
- }
467
- if (!ad) {
468
- console.warn("[HlsAdPlayer] No ads available from VAST response");
469
- emit("ad_error");
470
- return Promise.resolve();
471
- }
472
- currentAd = ad;
473
- console.log(
474
- `[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`
475
- );
476
- fireTrackingPixels(ad.trackingUrls.impression);
477
- trackingFired.impression = true;
478
- return Promise.resolve();
479
- } catch (error) {
480
- console.error("[HlsAdPlayer] Error requesting ads:", error);
481
- emit("ad_error");
482
- return Promise.reject(error);
483
- }
484
- },
485
- async preloadAds(vastTagUrl) {
486
- if (!vastTagUrl || vastTagUrl.trim() === "") {
487
- return Promise.resolve();
488
- }
489
- if (preloadedAds.has(vastTagUrl)) {
490
- return Promise.resolve();
491
- }
492
- const inflight = preloadingAds.get(vastTagUrl);
493
- if (inflight) {
494
- return inflight;
495
- }
496
- const preloadPromise = fetchAndParseVastAd(vastTagUrl).then((ad) => {
497
- if (ad) {
498
- preloadedAds.set(vastTagUrl, ad);
499
- console.log(
500
- "[HlsAdPlayer] Cached VAST response for preloading:",
501
- vastTagUrl
502
- );
503
- }
504
- }).catch((error) => {
505
- console.warn("[HlsAdPlayer] Failed to preload VAST response:", error);
506
- preloadedAds.delete(vastTagUrl);
507
- }).finally(() => {
508
- preloadingAds.delete(vastTagUrl);
509
- });
510
- preloadingAds.set(vastTagUrl, preloadPromise);
511
- return preloadPromise;
512
- },
513
- hasPreloadedAd(vastTagUrl) {
514
- return preloadedAds.has(vastTagUrl);
515
- },
516
- async play() {
517
- if (!currentAd) {
518
- console.warn(
519
- "[HlsAdPlayer] Cannot play: No ad loaded (no ads available)"
520
- );
521
- return Promise.reject(new Error("No ad loaded"));
522
- }
523
- console.log("[HlsAdPlayer] Starting ad playback");
524
- try {
525
- if (!adVideoElement) {
526
- adVideoElement = createAdVideoElement();
527
- adContainerEl == null ? void 0 : adContainerEl.appendChild(adVideoElement);
528
- setupAdEventListeners();
529
- }
530
- trackingFired = {
531
- impression: trackingFired.impression,
532
- start: false,
533
- firstQuartile: false,
534
- midpoint: false,
535
- thirdQuartile: false,
536
- complete: false
537
- };
538
- const contentVolume = contentVideo.volume;
539
- originalVolume = Math.max(
540
- 0,
541
- Math.min(1, contentVolume || originalVolume)
542
- );
543
- if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
544
- contentVideo.pause();
545
- console.log("[HlsAdPlayer] Content paused (VOD mode)");
547
+ function setAdPlayingFlag(isPlaying) {
548
+ if (isPlaying) {
549
+ contentVideo.dataset.stormcloudAdPlaying = "true";
546
550
  } else {
547
- console.log("[HlsAdPlayer] Content continues (Live mode)");
548
- }
549
- console.log("[HlsAdPlayer] FORCE MUTING main video");
550
- contentVideo.muted = true;
551
- contentVideo.volume = 0;
552
- adPlaying = true;
553
- setAdPlayingFlag(true);
554
- if (adVideoElement) {
555
- const adVolume = originalMutedState ? 0 : originalVolume;
556
- adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
557
- adVideoElement.muted = false;
558
- console.log(
559
- `[HlsAdPlayer] Set ad video volume to ${adVideoElement.volume}, muted: ${adVideoElement.muted}, originalMutedState: ${originalMutedState}, contentVolume: ${contentVolume}`
560
- );
551
+ delete contentVideo.dataset.stormcloudAdPlaying;
561
552
  }
553
+ }
554
+ function handleAdComplete() {
555
+ console.log("[HlsAdPlayer] Handling ad completion");
556
+ adPlaying = false;
557
+ setAdPlayingFlag(false);
558
+ emit("content_resume");
559
+ var timeoutId = window.setTimeout(function() {
560
+ if (destroyed) {
561
+ console.log("[HlsAdPlayer] Player destroyed, skipping post-completion check");
562
+ return;
563
+ }
564
+ var stillInPod = contentVideo.dataset.stormcloudAdPlaying === "true";
565
+ if (stillInPod) {
566
+ console.log("[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)");
567
+ if (adContainerEl) {
568
+ adContainerEl.style.display = "flex";
569
+ adContainerEl.style.pointerEvents = "auto";
570
+ }
571
+ }
572
+ var idx = pendingTimeouts.indexOf(timeoutId);
573
+ if (idx !== -1) {
574
+ pendingTimeouts.splice(idx, 1);
575
+ }
576
+ }, 50);
577
+ pendingTimeouts.push(timeoutId);
578
+ }
579
+ function handleAdError() {
580
+ console.log("[HlsAdPlayer] Handling ad error");
581
+ adPlaying = false;
582
+ setAdPlayingFlag(false);
583
+ var previousMutedState = contentVideo.muted;
584
+ contentVideo.muted = originalMutedState;
585
+ contentVideo.volume = originalMutedState ? 0 : originalVolume;
586
+ console.log("[HlsAdPlayer] Restored mute state: ".concat(previousMutedState, " -> ").concat(originalMutedState));
562
587
  if (adContainerEl) {
563
- adContainerEl.style.display = "flex";
564
- adContainerEl.style.pointerEvents = "auto";
588
+ adContainerEl.style.display = "none";
589
+ adContainerEl.style.pointerEvents = "none";
565
590
  }
566
- emit("content_pause");
567
- const mediaFile = selectBestMediaFile(currentAd.mediaFiles);
568
- if (!mediaFile) {
569
- throw new Error("No media file available for ad");
570
- }
571
- console.log(`[HlsAdPlayer] Loading ad from: ${mediaFile.url}`);
572
- if (import_hls.default.isSupported()) {
573
- if (adHls) {
574
- adHls.destroy();
575
- }
576
- adHls = new import_hls.default({
577
- enableWorker: true,
578
- lowLatencyMode: false
579
- });
580
- adHls.loadSource(mediaFile.url);
581
- adHls.attachMedia(adVideoElement);
582
- adHls.on(import_hls.default.Events.MANIFEST_PARSED, () => {
583
- console.log("[HlsAdPlayer] HLS manifest parsed, starting playback");
584
- adVideoElement.play().catch((error) => {
585
- console.error("[HlsAdPlayer] Error starting ad playback:", error);
586
- handleAdError();
587
- });
588
- });
589
- adHls.on(import_hls.default.Events.ERROR, (event, data) => {
590
- console.error("[HlsAdPlayer] HLS error:", data);
591
- if (data.fatal) {
592
- handleAdError();
593
- }
594
- });
595
- } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
596
- adVideoElement.src = mediaFile.url;
597
- adVideoElement.play().catch((error) => {
598
- console.error("[HlsAdPlayer] Error starting ad playback:", error);
599
- handleAdError();
600
- });
601
- } else {
602
- throw new Error("HLS not supported");
591
+ if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
592
+ if (contentVideo.paused) {
593
+ contentVideo.play().catch(function() {});
594
+ }
603
595
  }
604
- return Promise.resolve();
605
- } catch (error) {
606
- console.error("[HlsAdPlayer] Error playing ad:", error);
607
- handleAdError();
608
- return Promise.reject(error);
609
- }
610
- },
611
- async stop() {
612
- console.log("[HlsAdPlayer] Stopping ad");
613
- adPlaying = false;
614
- setAdPlayingFlag(false);
615
- if (adContainerEl) {
616
- adContainerEl.style.display = "none";
617
- adContainerEl.style.pointerEvents = "none";
618
- }
619
- if (adHls) {
620
- adHls.destroy();
621
- adHls = void 0;
622
- }
623
- if (adVideoElement) {
624
- adVideoElement.pause();
625
- adVideoElement.src = "";
626
- }
627
- currentAd = void 0;
628
- },
629
- destroy() {
630
- console.log("[HlsAdPlayer] Destroying");
631
- destroyed = true;
632
- for (const timeoutId of pendingTimeouts) {
633
- clearTimeout(timeoutId);
634
- }
635
- pendingTimeouts = [];
636
- adPlaying = false;
637
- setAdPlayingFlag(false);
638
- contentVideo.muted = originalMutedState;
639
- contentVideo.volume = originalMutedState ? 0 : originalVolume;
640
- if (adHls) {
641
- adHls.destroy();
642
- adHls = void 0;
643
- }
644
- if (adVideoElement) {
645
- adVideoElement.pause();
646
- adVideoElement.src = "";
647
- adVideoElement.remove();
648
- adVideoElement = void 0;
649
- }
650
- if (adContainerEl == null ? void 0 : adContainerEl.parentElement) {
651
- adContainerEl.parentElement.removeChild(adContainerEl);
652
- }
653
- adContainerEl = void 0;
654
- currentAd = void 0;
655
- listeners.clear();
656
- preloadedAds.clear();
657
- preloadingAds.clear();
658
- },
659
- isAdPlaying() {
660
- return adPlaying;
661
- },
662
- resize(width, height) {
663
- console.log(`[HlsAdPlayer] Resizing to ${width}x${height}`);
664
- if (adContainerEl) {
665
- adContainerEl.style.width = `${width}px`;
666
- adContainerEl.style.height = `${height}px`;
667
- }
668
- if (adVideoElement) {
669
- adVideoElement.style.width = `${width}px`;
670
- adVideoElement.style.height = `${height}px`;
671
- }
672
- },
673
- on(event, listener) {
674
- if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
675
- listeners.get(event).add(listener);
676
- },
677
- off(event, listener) {
678
- var _a;
679
- (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
680
- },
681
- updateOriginalMutedState(muted, volume) {
682
- const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
683
- console.log(
684
- `[HlsAdPlayer] updateOriginalMutedState called: { muted: ${originalMutedState} -> ${muted}, volume: ${originalVolume} -> ${nextVolume} }`
685
- );
686
- originalMutedState = muted;
687
- originalVolume = nextVolume;
688
- },
689
- getOriginalMutedState() {
690
- return originalMutedState;
691
- },
692
- getOriginalVolume() {
693
- return originalVolume;
694
- },
695
- setAdVolume(volume) {
696
- if (adVideoElement && adPlaying) {
697
- adVideoElement.volume = Math.max(0, Math.min(1, volume));
698
- }
699
- },
700
- getAdVolume() {
701
- if (adVideoElement && adPlaying) {
702
- return adVideoElement.volume;
703
- }
704
- return 1;
705
- },
706
- showPlaceholder() {
707
- var _a;
708
- if (!adContainerEl) {
709
- const container = document.createElement("div");
710
- container.style.position = "absolute";
711
- container.style.left = "0";
712
- container.style.top = "0";
713
- container.style.right = "0";
714
- container.style.bottom = "0";
715
- container.style.display = "none";
716
- container.style.alignItems = "center";
717
- container.style.justifyContent = "center";
718
- container.style.pointerEvents = "none";
719
- container.style.zIndex = "10";
720
- container.style.backgroundColor = "#000";
721
- (_a = contentVideo.parentElement) == null ? void 0 : _a.appendChild(container);
722
- adContainerEl = container;
723
- }
724
- if (adContainerEl) {
725
- adContainerEl.style.display = "flex";
726
- adContainerEl.style.pointerEvents = "auto";
727
- }
728
- },
729
- hidePlaceholder() {
730
- if (adContainerEl) {
731
- adContainerEl.style.display = "none";
732
- adContainerEl.style.pointerEvents = "none";
733
- }
596
+ emit("ad_error");
734
597
  }
735
- };
598
+ return {
599
+ initialize: function initialize() {
600
+ console.log("[HlsAdPlayer] Initializing");
601
+ if (!adContainerEl) {
602
+ var _contentVideo_parentElement;
603
+ var container = document.createElement("div");
604
+ container.style.position = "absolute";
605
+ container.style.left = "0";
606
+ container.style.top = "0";
607
+ container.style.right = "0";
608
+ container.style.bottom = "0";
609
+ container.style.display = "none";
610
+ container.style.alignItems = "center";
611
+ container.style.justifyContent = "center";
612
+ container.style.pointerEvents = "none";
613
+ container.style.zIndex = "10";
614
+ container.style.backgroundColor = "#000";
615
+ (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
616
+ adContainerEl = container;
617
+ }
618
+ },
619
+ requestAds: function requestAds(vastTagUrl) {
620
+ return _async_to_generator(function() {
621
+ var ad, error;
622
+ return _ts_generator(this, function(_state) {
623
+ switch(_state.label){
624
+ case 0:
625
+ console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
626
+ if (adPlaying) {
627
+ console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
628
+ return [
629
+ 2,
630
+ Promise.reject(new Error("Ad already playing"))
631
+ ];
632
+ }
633
+ _state.label = 1;
634
+ case 1:
635
+ _state.trys.push([
636
+ 1,
637
+ 5,
638
+ ,
639
+ 6
640
+ ]);
641
+ sessionId = generateSessionId();
642
+ if (!preloadedAds.has(vastTagUrl)) return [
643
+ 3,
644
+ 2
645
+ ];
646
+ ad = preloadedAds.get(vastTagUrl);
647
+ preloadedAds.delete(vastTagUrl);
648
+ console.log("[HlsAdPlayer] Using preloaded VAST response:", vastTagUrl);
649
+ return [
650
+ 3,
651
+ 4
652
+ ];
653
+ case 2:
654
+ return [
655
+ 4,
656
+ fetchAndParseVastAd(vastTagUrl)
657
+ ];
658
+ case 3:
659
+ ad = _state.sent();
660
+ _state.label = 4;
661
+ case 4:
662
+ if (!ad) {
663
+ console.warn("[HlsAdPlayer] No ads available from VAST response");
664
+ emit("ad_error");
665
+ return [
666
+ 2,
667
+ Promise.resolve()
668
+ ];
669
+ }
670
+ currentAd = ad;
671
+ console.log("[HlsAdPlayer] Ad parsed: ".concat(ad.title, ", duration: ").concat(ad.duration, "s"));
672
+ fireTrackingPixels(ad.trackingUrls.impression);
673
+ trackingFired.impression = true;
674
+ return [
675
+ 2,
676
+ Promise.resolve()
677
+ ];
678
+ case 5:
679
+ error = _state.sent();
680
+ console.error("[HlsAdPlayer] Error requesting ads:", error);
681
+ emit("ad_error");
682
+ return [
683
+ 2,
684
+ Promise.reject(error)
685
+ ];
686
+ case 6:
687
+ return [
688
+ 2
689
+ ];
690
+ }
691
+ });
692
+ })();
693
+ },
694
+ preloadAds: function preloadAds(vastTagUrl) {
695
+ return _async_to_generator(function() {
696
+ var inflight, preloadPromise;
697
+ return _ts_generator(this, function(_state) {
698
+ if (!vastTagUrl || vastTagUrl.trim() === "") {
699
+ return [
700
+ 2,
701
+ Promise.resolve()
702
+ ];
703
+ }
704
+ if (preloadedAds.has(vastTagUrl)) {
705
+ return [
706
+ 2,
707
+ Promise.resolve()
708
+ ];
709
+ }
710
+ inflight = preloadingAds.get(vastTagUrl);
711
+ if (inflight) {
712
+ return [
713
+ 2,
714
+ inflight
715
+ ];
716
+ }
717
+ preloadPromise = fetchAndParseVastAd(vastTagUrl).then(function(ad) {
718
+ if (ad) {
719
+ preloadedAds.set(vastTagUrl, ad);
720
+ console.log("[HlsAdPlayer] Cached VAST response for preloading:", vastTagUrl);
721
+ }
722
+ }).catch(function(error) {
723
+ console.warn("[HlsAdPlayer] Failed to preload VAST response:", error);
724
+ preloadedAds.delete(vastTagUrl);
725
+ }).finally(function() {
726
+ preloadingAds.delete(vastTagUrl);
727
+ });
728
+ preloadingAds.set(vastTagUrl, preloadPromise);
729
+ return [
730
+ 2,
731
+ preloadPromise
732
+ ];
733
+ });
734
+ })();
735
+ },
736
+ hasPreloadedAd: function hasPreloadedAd(vastTagUrl) {
737
+ return preloadedAds.has(vastTagUrl);
738
+ },
739
+ play: function play() {
740
+ return _async_to_generator(function() {
741
+ var contentVolume, adVolume, mediaFile;
742
+ return _ts_generator(this, function(_state) {
743
+ if (!currentAd) {
744
+ console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
745
+ return [
746
+ 2,
747
+ Promise.reject(new Error("No ad loaded"))
748
+ ];
749
+ }
750
+ console.log("[HlsAdPlayer] Starting ad playback");
751
+ try {
752
+ if (!adVideoElement) {
753
+ adVideoElement = createAdVideoElement();
754
+ adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.appendChild(adVideoElement);
755
+ setupAdEventListeners();
756
+ }
757
+ trackingFired = {
758
+ impression: trackingFired.impression,
759
+ start: false,
760
+ firstQuartile: false,
761
+ midpoint: false,
762
+ thirdQuartile: false,
763
+ complete: false
764
+ };
765
+ contentVolume = contentVideo.volume;
766
+ originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
767
+ if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
768
+ contentVideo.pause();
769
+ console.log("[HlsAdPlayer] Content paused (VOD mode)");
770
+ } else {
771
+ console.log("[HlsAdPlayer] Content continues (Live mode)");
772
+ }
773
+ console.log("[HlsAdPlayer] FORCE MUTING main video");
774
+ contentVideo.muted = true;
775
+ contentVideo.volume = 0;
776
+ adPlaying = true;
777
+ setAdPlayingFlag(true);
778
+ if (adVideoElement) {
779
+ adVolume = originalMutedState ? 0 : originalVolume;
780
+ adVideoElement.volume = Math.max(0, Math.min(1, adVolume));
781
+ adVideoElement.muted = false;
782
+ console.log("[HlsAdPlayer] Set ad video volume to ".concat(adVideoElement.volume, ", muted: ").concat(adVideoElement.muted, ", originalMutedState: ").concat(originalMutedState, ", contentVolume: ").concat(contentVolume));
783
+ }
784
+ if (adContainerEl) {
785
+ adContainerEl.style.display = "flex";
786
+ adContainerEl.style.pointerEvents = "auto";
787
+ }
788
+ emit("content_pause");
789
+ mediaFile = selectBestMediaFile(currentAd.mediaFiles);
790
+ if (!mediaFile) {
791
+ throw new Error("No media file available for ad");
792
+ }
793
+ console.log("[HlsAdPlayer] Loading ad from: ".concat(mediaFile.url));
794
+ if (import_hls.default.isSupported()) {
795
+ if (adHls) {
796
+ adHls.destroy();
797
+ }
798
+ adHls = new import_hls.default({
799
+ enableWorker: true,
800
+ lowLatencyMode: false
801
+ });
802
+ adHls.loadSource(mediaFile.url);
803
+ adHls.attachMedia(adVideoElement);
804
+ adHls.on(import_hls.default.Events.MANIFEST_PARSED, function() {
805
+ console.log("[HlsAdPlayer] HLS manifest parsed, starting playback");
806
+ adVideoElement.play().catch(function(error) {
807
+ console.error("[HlsAdPlayer] Error starting ad playback:", error);
808
+ handleAdError();
809
+ });
810
+ });
811
+ adHls.on(import_hls.default.Events.ERROR, function(event, data) {
812
+ console.error("[HlsAdPlayer] HLS error:", data);
813
+ if (data.fatal) {
814
+ handleAdError();
815
+ }
816
+ });
817
+ } else if (adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
818
+ adVideoElement.src = mediaFile.url;
819
+ adVideoElement.play().catch(function(error) {
820
+ console.error("[HlsAdPlayer] Error starting ad playback:", error);
821
+ handleAdError();
822
+ });
823
+ } else {
824
+ throw new Error("HLS not supported");
825
+ }
826
+ return [
827
+ 2,
828
+ Promise.resolve()
829
+ ];
830
+ } catch (error) {
831
+ console.error("[HlsAdPlayer] Error playing ad:", error);
832
+ handleAdError();
833
+ return [
834
+ 2,
835
+ Promise.reject(error)
836
+ ];
837
+ }
838
+ return [
839
+ 2
840
+ ];
841
+ });
842
+ })();
843
+ },
844
+ stop: function stop() {
845
+ return _async_to_generator(function() {
846
+ return _ts_generator(this, function(_state) {
847
+ console.log("[HlsAdPlayer] Stopping ad");
848
+ adPlaying = false;
849
+ setAdPlayingFlag(false);
850
+ if (adContainerEl) {
851
+ adContainerEl.style.display = "none";
852
+ adContainerEl.style.pointerEvents = "none";
853
+ }
854
+ if (adHls) {
855
+ adHls.destroy();
856
+ adHls = void 0;
857
+ }
858
+ if (adVideoElement) {
859
+ adVideoElement.pause();
860
+ adVideoElement.src = "";
861
+ }
862
+ currentAd = void 0;
863
+ return [
864
+ 2
865
+ ];
866
+ });
867
+ })();
868
+ },
869
+ destroy: function destroy() {
870
+ console.log("[HlsAdPlayer] Destroying");
871
+ destroyed = true;
872
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
873
+ try {
874
+ for(var _iterator = pendingTimeouts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
875
+ var timeoutId = _step.value;
876
+ clearTimeout(timeoutId);
877
+ }
878
+ } catch (err) {
879
+ _didIteratorError = true;
880
+ _iteratorError = err;
881
+ } finally{
882
+ try {
883
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
884
+ _iterator.return();
885
+ }
886
+ } finally{
887
+ if (_didIteratorError) {
888
+ throw _iteratorError;
889
+ }
890
+ }
891
+ }
892
+ pendingTimeouts = [];
893
+ adPlaying = false;
894
+ setAdPlayingFlag(false);
895
+ contentVideo.muted = originalMutedState;
896
+ contentVideo.volume = originalMutedState ? 0 : originalVolume;
897
+ if (adHls) {
898
+ adHls.destroy();
899
+ adHls = void 0;
900
+ }
901
+ if (adVideoElement) {
902
+ adVideoElement.pause();
903
+ adVideoElement.src = "";
904
+ adVideoElement.remove();
905
+ adVideoElement = void 0;
906
+ }
907
+ if (adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.parentElement) {
908
+ adContainerEl.parentElement.removeChild(adContainerEl);
909
+ }
910
+ adContainerEl = void 0;
911
+ currentAd = void 0;
912
+ listeners.clear();
913
+ preloadedAds.clear();
914
+ preloadingAds.clear();
915
+ },
916
+ isAdPlaying: function isAdPlaying() {
917
+ return adPlaying;
918
+ },
919
+ resize: function resize(width, height) {
920
+ console.log("[HlsAdPlayer] Resizing to ".concat(width, "x").concat(height));
921
+ if (adContainerEl) {
922
+ adContainerEl.style.width = "".concat(width, "px");
923
+ adContainerEl.style.height = "".concat(height, "px");
924
+ }
925
+ if (adVideoElement) {
926
+ adVideoElement.style.width = "".concat(width, "px");
927
+ adVideoElement.style.height = "".concat(height, "px");
928
+ }
929
+ },
930
+ on: function on(event, listener) {
931
+ if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
932
+ listeners.get(event).add(listener);
933
+ },
934
+ off: function off(event, listener) {
935
+ var _listeners_get;
936
+ (_listeners_get = listeners.get(event)) === null || _listeners_get === void 0 ? void 0 : _listeners_get.delete(listener);
937
+ },
938
+ updateOriginalMutedState: function updateOriginalMutedState(muted, volume) {
939
+ var nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
940
+ console.log("[HlsAdPlayer] updateOriginalMutedState called: { muted: ".concat(originalMutedState, " -> ").concat(muted, ", volume: ").concat(originalVolume, " -> ").concat(nextVolume, " }"));
941
+ originalMutedState = muted;
942
+ originalVolume = nextVolume;
943
+ },
944
+ getOriginalMutedState: function getOriginalMutedState() {
945
+ return originalMutedState;
946
+ },
947
+ getOriginalVolume: function getOriginalVolume() {
948
+ return originalVolume;
949
+ },
950
+ setAdVolume: function setAdVolume(volume) {
951
+ if (adVideoElement && adPlaying) {
952
+ adVideoElement.volume = Math.max(0, Math.min(1, volume));
953
+ }
954
+ },
955
+ getAdVolume: function getAdVolume() {
956
+ if (adVideoElement && adPlaying) {
957
+ return adVideoElement.volume;
958
+ }
959
+ return 1;
960
+ },
961
+ showPlaceholder: function showPlaceholder() {
962
+ if (!adContainerEl) {
963
+ var _contentVideo_parentElement;
964
+ var container = document.createElement("div");
965
+ container.style.position = "absolute";
966
+ container.style.left = "0";
967
+ container.style.top = "0";
968
+ container.style.right = "0";
969
+ container.style.bottom = "0";
970
+ container.style.display = "none";
971
+ container.style.alignItems = "center";
972
+ container.style.justifyContent = "center";
973
+ container.style.pointerEvents = "none";
974
+ container.style.zIndex = "10";
975
+ container.style.backgroundColor = "#000";
976
+ (_contentVideo_parentElement = contentVideo.parentElement) === null || _contentVideo_parentElement === void 0 ? void 0 : _contentVideo_parentElement.appendChild(container);
977
+ adContainerEl = container;
978
+ }
979
+ if (adContainerEl) {
980
+ adContainerEl.style.display = "flex";
981
+ adContainerEl.style.pointerEvents = "auto";
982
+ }
983
+ },
984
+ hidePlaceholder: function hidePlaceholder() {
985
+ if (adContainerEl) {
986
+ adContainerEl.style.display = "none";
987
+ adContainerEl.style.pointerEvents = "none";
988
+ }
989
+ }
990
+ };
736
991
  }
737
992
  // Annotate the CommonJS export names for ESM import in node:
738
993
  0 && (module.exports = {
739
- createHlsAdPlayer
994
+ createHlsAdPlayer: createHlsAdPlayer
740
995
  });
741
996
  //# sourceMappingURL=hlsAdPlayer.cjs.map