stormcloud-video-player 0.4.0 → 0.5.0
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.
- package/README.md +245 -156
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +9759 -5311
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +193 -17
- package/lib/index.d.ts +193 -17
- package/lib/index.js +9761 -5329
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +7090 -1508
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +95 -9
- package/lib/players/HlsPlayer.cjs +7107 -1525
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +7098 -1516
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +302 -266
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +2 -2
- package/lib/sdk/ima.cjs +1375 -0
- package/lib/sdk/ima.cjs.map +1 -0
- package/lib/sdk/ima.d.cts +12 -0
- package/lib/sdk/prebid.cjs +564 -0
- package/lib/sdk/prebid.cjs.map +1 -0
- package/lib/sdk/prebid.d.cts +5 -0
- package/lib/sdk/prebidController.cjs +1560 -0
- package/lib/sdk/prebidController.cjs.map +1 -0
- package/lib/sdk/prebidController.d.cts +11 -0
- package/lib/sdk/vastParser.cjs +393 -0
- package/lib/sdk/vastParser.cjs.map +1 -0
- package/lib/sdk/vastParser.d.cts +45 -0
- package/lib/{types-Ca4ZDaWw.d.cts → types-g2d4Akez.d.cts} +72 -3
- package/lib/ui/StormcloudVideoPlayer.cjs +7130 -1530
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/browserCompat.cjs +222 -20
- package/lib/utils/browserCompat.cjs.map +1 -1
- package/lib/utils/browserCompat.d.cts +9 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +2 -1
- package/lib/sdk/adstormPlayer.cjs +0 -908
- package/lib/sdk/adstormPlayer.cjs.map +0 -1
- package/lib/sdk/adstormPlayer.d.cts +0 -9
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -189,42 +189,196 @@ __export(hlsAdPlayer_exports, {
|
|
|
189
189
|
}
|
|
190
190
|
});
|
|
191
191
|
module.exports = __toCommonJS(hlsAdPlayer_exports);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
".
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
".
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
".
|
|
201
|
-
".mp4",
|
|
202
|
-
".webm"
|
|
203
|
-
];
|
|
204
|
-
function getFileExtension(url) {
|
|
192
|
+
// src/sdk/vastParser.ts
|
|
193
|
+
function isHlsType(type) {
|
|
194
|
+
return type === "application/x-mpegURL" || type.includes("m3u8");
|
|
195
|
+
}
|
|
196
|
+
function isMp4Type(type) {
|
|
197
|
+
return type === "video/mp4" || type.includes("mp4");
|
|
198
|
+
}
|
|
199
|
+
function parseVastXml(xmlString) {
|
|
200
|
+
var filter = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "all", logPrefix = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "[VastParser]";
|
|
205
201
|
try {
|
|
206
|
-
var
|
|
207
|
-
var
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
202
|
+
var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
|
|
203
|
+
var parser = new DOMParser();
|
|
204
|
+
var xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
205
|
+
var parserError = xmlDoc.querySelector("parsererror");
|
|
206
|
+
if (parserError) {
|
|
207
|
+
console.error("".concat(logPrefix, " XML parsing error (malformed VAST XML):"), parserError.textContent);
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
var adElement = xmlDoc.querySelector("Ad");
|
|
211
|
+
if (!adElement) {
|
|
212
|
+
console.warn("".concat(logPrefix, " No Ad element found in VAST XML"));
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
var adId = adElement.getAttribute("id") || "unknown";
|
|
216
|
+
var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
|
|
217
|
+
var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
|
|
218
|
+
var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
|
|
219
|
+
var durationParts = durationText.split(":");
|
|
220
|
+
var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + Math.round(parseFloat(durationParts[2] || "0"));
|
|
221
|
+
var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
222
|
+
var mediaFiles = [];
|
|
223
|
+
console.log("".concat(logPrefix, " Found ").concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
|
|
224
|
+
mediaFileElements.forEach(function(mf, index) {
|
|
225
|
+
var _mf_textContent;
|
|
226
|
+
var type = mf.getAttribute("type") || "";
|
|
227
|
+
var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
|
|
228
|
+
var width = mf.getAttribute("width") || "";
|
|
229
|
+
var height = mf.getAttribute("height") || "";
|
|
230
|
+
console.log("".concat(logPrefix, " MediaFile ").concat(index, ': type="').concat(type, '", url="').concat(url.substring(0, 80), '...", width="').concat(width, '", height="').concat(height, '"'));
|
|
231
|
+
if (!url) {
|
|
232
|
+
console.warn("".concat(logPrefix, " MediaFile ").concat(index, " has empty URL"));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
var isHls = isHlsType(type);
|
|
236
|
+
var isMp4 = isMp4Type(type);
|
|
237
|
+
var accepted = false;
|
|
238
|
+
if (filter === "hls-only") {
|
|
239
|
+
accepted = isHls;
|
|
240
|
+
} else if (filter === "mp4-first") {
|
|
241
|
+
accepted = isMp4 || isHls;
|
|
242
|
+
} else {
|
|
243
|
+
accepted = true;
|
|
244
|
+
}
|
|
245
|
+
if (!accepted) {
|
|
246
|
+
console.log("".concat(logPrefix, " MediaFile ").concat(index, ' ignored (type="').concat(type, '" not accepted by filter "').concat(filter, '")'));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
var bitrateAttr = mf.getAttribute("bitrate");
|
|
250
|
+
var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
251
|
+
mediaFiles.push({
|
|
252
|
+
url: url,
|
|
253
|
+
type: type,
|
|
254
|
+
width: parseInt(width || "1920", 10),
|
|
255
|
+
height: parseInt(height || "1080", 10),
|
|
256
|
+
bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
|
|
257
|
+
});
|
|
258
|
+
console.log("".concat(logPrefix, ' Added MediaFile: type="').concat(type, '" url="').concat(url.substring(0, 80), '..."'));
|
|
259
|
+
});
|
|
260
|
+
if (filter === "mp4-first" && mediaFiles.length > 1) {
|
|
261
|
+
mediaFiles.sort(function(a, b) {
|
|
262
|
+
var aIsMp4 = isMp4Type(a.type) ? 0 : 1;
|
|
263
|
+
var bIsMp4 = isMp4Type(b.type) ? 0 : 1;
|
|
264
|
+
return aIsMp4 - bIsMp4;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (mediaFiles.length === 0) {
|
|
268
|
+
if (isNoAdAvailable) {
|
|
269
|
+
console.warn("".concat(logPrefix, " No ads available (VAST response indicates no ads)"));
|
|
270
|
+
} else {
|
|
271
|
+
console.warn("".concat(logPrefix, " No compatible media files found in VAST XML"));
|
|
272
|
+
}
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
var trackingUrls = {
|
|
276
|
+
impression: [],
|
|
277
|
+
start: [],
|
|
278
|
+
firstQuartile: [],
|
|
279
|
+
midpoint: [],
|
|
280
|
+
thirdQuartile: [],
|
|
281
|
+
complete: [],
|
|
282
|
+
mute: [],
|
|
283
|
+
unmute: [],
|
|
284
|
+
pause: [],
|
|
285
|
+
resume: [],
|
|
286
|
+
fullscreen: [],
|
|
287
|
+
exitFullscreen: [],
|
|
288
|
+
skip: [],
|
|
289
|
+
error: []
|
|
290
|
+
};
|
|
291
|
+
xmlDoc.querySelectorAll("Impression").forEach(function(el) {
|
|
292
|
+
var _el_textContent;
|
|
293
|
+
var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
294
|
+
if (url) trackingUrls.impression.push(url);
|
|
295
|
+
});
|
|
296
|
+
xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
|
|
297
|
+
var _el_textContent;
|
|
298
|
+
var event = el.getAttribute("event");
|
|
299
|
+
var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
300
|
+
if (event && url) {
|
|
301
|
+
var eventKey = event;
|
|
302
|
+
if (trackingUrls[eventKey]) {
|
|
303
|
+
trackingUrls[eventKey].push(url);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
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();
|
|
308
|
+
return {
|
|
309
|
+
id: adId,
|
|
310
|
+
title: title,
|
|
311
|
+
duration: duration,
|
|
312
|
+
mediaFiles: mediaFiles,
|
|
313
|
+
trackingUrls: trackingUrls,
|
|
314
|
+
clickThrough: clickThrough
|
|
315
|
+
};
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error("".concat(logPrefix, " Error parsing VAST XML:"), error);
|
|
318
|
+
return null;
|
|
215
319
|
}
|
|
216
320
|
}
|
|
217
|
-
function
|
|
218
|
-
var
|
|
219
|
-
return
|
|
321
|
+
function fetchAndParseVastAd(vastTagUrl) {
|
|
322
|
+
var filter = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "all", logPrefix = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "[VastParser]";
|
|
323
|
+
return _async_to_generator(function() {
|
|
324
|
+
var response, vastXml;
|
|
325
|
+
return _ts_generator(this, function(_state) {
|
|
326
|
+
switch(_state.label){
|
|
327
|
+
case 0:
|
|
328
|
+
return [
|
|
329
|
+
4,
|
|
330
|
+
fetch(vastTagUrl, {
|
|
331
|
+
mode: "cors",
|
|
332
|
+
credentials: "include",
|
|
333
|
+
headers: {
|
|
334
|
+
Accept: "application/xml, text/xml, */*"
|
|
335
|
+
},
|
|
336
|
+
referrerPolicy: "no-referrer-when-downgrade"
|
|
337
|
+
})
|
|
338
|
+
];
|
|
339
|
+
case 1:
|
|
340
|
+
response = _state.sent();
|
|
341
|
+
if (!response.ok) {
|
|
342
|
+
throw new Error("Failed to fetch VAST: ".concat(response.statusText));
|
|
343
|
+
}
|
|
344
|
+
return [
|
|
345
|
+
4,
|
|
346
|
+
response.text()
|
|
347
|
+
];
|
|
348
|
+
case 2:
|
|
349
|
+
vastXml = _state.sent();
|
|
350
|
+
console.log("".concat(logPrefix, " VAST XML received"));
|
|
351
|
+
console.log("".concat(logPrefix, " VAST XML content (first 2000 chars):"), vastXml.substring(0, 2e3));
|
|
352
|
+
return [
|
|
353
|
+
2,
|
|
354
|
+
parseVastXml(vastXml, filter, logPrefix)
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
})();
|
|
220
359
|
}
|
|
221
|
-
function
|
|
222
|
-
var
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
360
|
+
function fireTrackingPixels(urls, sessionId, licenseKey) {
|
|
361
|
+
var logPrefix = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "[VastParser]";
|
|
362
|
+
if (!urls || urls.length === 0) return;
|
|
363
|
+
urls.forEach(function(url) {
|
|
364
|
+
try {
|
|
365
|
+
var trackingUrl = url;
|
|
366
|
+
if (sessionId) {
|
|
367
|
+
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "session_id=").concat(sessionId);
|
|
368
|
+
}
|
|
369
|
+
if (licenseKey) {
|
|
370
|
+
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "license_key=").concat(licenseKey);
|
|
371
|
+
}
|
|
372
|
+
var img = new Image(1, 1);
|
|
373
|
+
img.src = trackingUrl;
|
|
374
|
+
console.log("".concat(logPrefix, " Fired tracking pixel: ").concat(trackingUrl));
|
|
375
|
+
} catch (error) {
|
|
376
|
+
console.warn("".concat(logPrefix, " Error firing tracking pixel:"), error);
|
|
377
|
+
}
|
|
378
|
+
});
|
|
227
379
|
}
|
|
380
|
+
// src/sdk/hlsAdPlayer.ts
|
|
381
|
+
var import_hls = __toESM(require("hls.js"), 1);
|
|
228
382
|
function createHlsAdPlayer(contentVideo, options) {
|
|
229
383
|
var adPlaying = false;
|
|
230
384
|
var originalMutedState = false;
|
|
@@ -237,6 +391,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
237
391
|
var adContainerEl;
|
|
238
392
|
var currentAd;
|
|
239
393
|
var sessionId;
|
|
394
|
+
var preloadedAds = /* @__PURE__ */ new Map();
|
|
395
|
+
var preloadingAds = /* @__PURE__ */ new Map();
|
|
240
396
|
var destroyed = false;
|
|
241
397
|
var pendingTimeouts = [];
|
|
242
398
|
var trackingFired = {
|
|
@@ -278,46 +434,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
278
434
|
function generateSessionId() {
|
|
279
435
|
return "session-".concat(Date.now(), "-").concat(Math.random().toString(36).substr(2, 9));
|
|
280
436
|
}
|
|
281
|
-
function
|
|
282
|
-
|
|
283
|
-
var metadata = {
|
|
284
|
-
video: {
|
|
285
|
-
codec: "h264",
|
|
286
|
-
width: contentVideo.videoWidth || 1280,
|
|
287
|
-
height: contentVideo.videoHeight || 720,
|
|
288
|
-
fps: 29.97,
|
|
289
|
-
bitrate: 5e3,
|
|
290
|
-
profile: "high",
|
|
291
|
-
pix_fmt: "yuv420p",
|
|
292
|
-
has_b_frames: 0
|
|
293
|
-
},
|
|
294
|
-
audio: {
|
|
295
|
-
codec: "aac",
|
|
296
|
-
sample_rate: 48e3,
|
|
297
|
-
bitrate: 128
|
|
298
|
-
}
|
|
299
|
-
};
|
|
300
|
-
var metadataStr = encodeURIComponent(JSON.stringify(metadata));
|
|
301
|
-
return "".concat(baseUrl, "?duration=").concat(Math.ceil(durationSeconds), "&metadata=").concat(metadataStr);
|
|
302
|
-
}
|
|
303
|
-
function fireTrackingPixels(urls) {
|
|
304
|
-
if (!urls || urls.length === 0) return;
|
|
305
|
-
urls.forEach(function(url) {
|
|
306
|
-
try {
|
|
307
|
-
var trackingUrl = url;
|
|
308
|
-
if (sessionId) {
|
|
309
|
-
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "session_id=").concat(sessionId);
|
|
310
|
-
}
|
|
311
|
-
if (licenseKey) {
|
|
312
|
-
trackingUrl = "".concat(trackingUrl).concat(trackingUrl.includes("?") ? "&" : "?", "license_key=").concat(licenseKey);
|
|
313
|
-
}
|
|
314
|
-
var img = new Image(1, 1);
|
|
315
|
-
img.src = trackingUrl;
|
|
316
|
-
console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingUrl));
|
|
317
|
-
} catch (error) {
|
|
318
|
-
console.warn("[HlsAdPlayer] Error firing tracking pixel:", error);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
437
|
+
function fireTrackingPixels2(urls) {
|
|
438
|
+
fireTrackingPixels(urls, sessionId, licenseKey, "[HlsAdPlayer]");
|
|
321
439
|
}
|
|
322
440
|
function getMainStreamQuality() {
|
|
323
441
|
if (!mainHlsInstance || !mainHlsInstance.levels) {
|
|
@@ -392,148 +510,13 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
392
510
|
});
|
|
393
511
|
return bestMatch.file;
|
|
394
512
|
}
|
|
395
|
-
function
|
|
396
|
-
try {
|
|
397
|
-
var _xmlDoc_querySelector, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector2;
|
|
398
|
-
var parser = new DOMParser();
|
|
399
|
-
var xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
400
|
-
var parserError = xmlDoc.querySelector("parsererror");
|
|
401
|
-
if (parserError) {
|
|
402
|
-
console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
var adElement = xmlDoc.querySelector("Ad");
|
|
406
|
-
if (!adElement) {
|
|
407
|
-
console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
var adId = adElement.getAttribute("id") || "unknown";
|
|
411
|
-
var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
|
|
412
|
-
var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
|
|
413
|
-
var durationText = ((_xmlDoc_querySelector1 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : _xmlDoc_querySelector1.textContent) || "00:00:30";
|
|
414
|
-
var durationParts = durationText.split(":");
|
|
415
|
-
var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
416
|
-
var mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
417
|
-
var mediaFiles = [];
|
|
418
|
-
console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
|
|
419
|
-
mediaFileElements.forEach(function(mf, index) {
|
|
420
|
-
var _mf_textContent;
|
|
421
|
-
var type = mf.getAttribute("type") || "";
|
|
422
|
-
var url = ((_mf_textContent = mf.textContent) === null || _mf_textContent === void 0 ? void 0 : _mf_textContent.trim()) || "";
|
|
423
|
-
var width = mf.getAttribute("width") || "";
|
|
424
|
-
var height = mf.getAttribute("height") || "";
|
|
425
|
-
console.log("[HlsAdPlayer] MediaFile ".concat(index, ': type="').concat(type, '", url="').concat(url, '", width="').concat(width, '", height="').concat(height, '"'));
|
|
426
|
-
var originalUrl = url;
|
|
427
|
-
url = replaceFlvExtension(url);
|
|
428
|
-
if (url !== originalUrl) {
|
|
429
|
-
console.log("[HlsAdPlayer] Converted FLV to MP4: ".concat(originalUrl, " -> ").concat(url));
|
|
430
|
-
}
|
|
431
|
-
if (isUnsupportedForHls(url)) {
|
|
432
|
-
var ext = getFileExtension(url);
|
|
433
|
-
console.log("[HlsAdPlayer] MediaFile ".concat(index, " ignored: unsupported format (extension: ").concat(ext, ", declared type: ").concat(type, ")"));
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
437
|
-
if (!url) {
|
|
438
|
-
console.warn("[HlsAdPlayer] MediaFile ".concat(index, " has HLS type but empty URL"));
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
var bitrateAttr = mf.getAttribute("bitrate");
|
|
442
|
-
var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
443
|
-
mediaFiles.push({
|
|
444
|
-
url: url,
|
|
445
|
-
type: type,
|
|
446
|
-
width: parseInt(width || "1920", 10),
|
|
447
|
-
height: parseInt(height || "1080", 10),
|
|
448
|
-
bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
|
|
449
|
-
});
|
|
450
|
-
console.log("[HlsAdPlayer] Added HLS MediaFile: ".concat(url));
|
|
451
|
-
} else {
|
|
452
|
-
console.log("[HlsAdPlayer] MediaFile ".concat(index, ' ignored (type="').concat(type, '" is not HLS)'));
|
|
453
|
-
}
|
|
454
|
-
});
|
|
455
|
-
if (mediaFiles.length === 0) {
|
|
456
|
-
if (isNoAdAvailable) {
|
|
457
|
-
console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
|
|
458
|
-
} else {
|
|
459
|
-
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
460
|
-
}
|
|
461
|
-
return null;
|
|
462
|
-
}
|
|
463
|
-
var trackingUrls = {
|
|
464
|
-
impression: [],
|
|
465
|
-
start: [],
|
|
466
|
-
firstQuartile: [],
|
|
467
|
-
midpoint: [],
|
|
468
|
-
thirdQuartile: [],
|
|
469
|
-
complete: [],
|
|
470
|
-
mute: [],
|
|
471
|
-
unmute: [],
|
|
472
|
-
pause: [],
|
|
473
|
-
resume: [],
|
|
474
|
-
fullscreen: [],
|
|
475
|
-
exitFullscreen: [],
|
|
476
|
-
skip: [],
|
|
477
|
-
error: []
|
|
478
|
-
};
|
|
479
|
-
xmlDoc.querySelectorAll("Impression").forEach(function(el) {
|
|
480
|
-
var _el_textContent;
|
|
481
|
-
var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
482
|
-
if (url) trackingUrls.impression.push(url);
|
|
483
|
-
});
|
|
484
|
-
xmlDoc.querySelectorAll("Tracking").forEach(function(el) {
|
|
485
|
-
var _el_textContent;
|
|
486
|
-
var event = el.getAttribute("event");
|
|
487
|
-
var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
|
|
488
|
-
if (event && url) {
|
|
489
|
-
var eventKey = event;
|
|
490
|
-
if (trackingUrls[eventKey]) {
|
|
491
|
-
trackingUrls[eventKey].push(url);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
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();
|
|
496
|
-
return {
|
|
497
|
-
id: adId,
|
|
498
|
-
title: title,
|
|
499
|
-
duration: duration,
|
|
500
|
-
mediaFiles: mediaFiles,
|
|
501
|
-
trackingUrls: trackingUrls,
|
|
502
|
-
clickThrough: clickThrough
|
|
503
|
-
};
|
|
504
|
-
} catch (error) {
|
|
505
|
-
console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
function fetchAndParseVastAd(url) {
|
|
513
|
+
function fetchAndParseVastAdLocal(vastTagUrl) {
|
|
510
514
|
return _async_to_generator(function() {
|
|
511
|
-
var response, vastXml;
|
|
512
515
|
return _ts_generator(this, function(_state) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
fetch(url)
|
|
518
|
-
];
|
|
519
|
-
case 1:
|
|
520
|
-
response = _state.sent();
|
|
521
|
-
if (!response.ok) {
|
|
522
|
-
throw new Error("Failed to fetch VAST: ".concat(response.statusText));
|
|
523
|
-
}
|
|
524
|
-
return [
|
|
525
|
-
4,
|
|
526
|
-
response.text()
|
|
527
|
-
];
|
|
528
|
-
case 2:
|
|
529
|
-
vastXml = _state.sent();
|
|
530
|
-
console.log("[HlsAdPlayer] VAST XML received");
|
|
531
|
-
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
532
|
-
return [
|
|
533
|
-
2,
|
|
534
|
-
parseVastXml(vastXml)
|
|
535
|
-
];
|
|
536
|
-
}
|
|
516
|
+
return [
|
|
517
|
+
2,
|
|
518
|
+
fetchAndParseVastAd(vastTagUrl, "hls-only", "[HlsAdPlayer]")
|
|
519
|
+
];
|
|
537
520
|
});
|
|
538
521
|
})();
|
|
539
522
|
}
|
|
@@ -559,53 +542,53 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
559
542
|
var progress = adVideoElement.currentTime / currentAd.duration;
|
|
560
543
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
561
544
|
trackingFired.firstQuartile = true;
|
|
562
|
-
|
|
545
|
+
fireTrackingPixels2(currentAd.trackingUrls.firstQuartile);
|
|
563
546
|
}
|
|
564
547
|
if (progress >= 0.5 && !trackingFired.midpoint) {
|
|
565
548
|
trackingFired.midpoint = true;
|
|
566
|
-
|
|
549
|
+
fireTrackingPixels2(currentAd.trackingUrls.midpoint);
|
|
567
550
|
}
|
|
568
551
|
if (progress >= 0.75 && !trackingFired.thirdQuartile) {
|
|
569
552
|
trackingFired.thirdQuartile = true;
|
|
570
|
-
|
|
553
|
+
fireTrackingPixels2(currentAd.trackingUrls.thirdQuartile);
|
|
571
554
|
}
|
|
572
555
|
});
|
|
573
556
|
adVideoElement.addEventListener("playing", function() {
|
|
574
557
|
if (!currentAd || trackingFired.start) return;
|
|
575
558
|
trackingFired.start = true;
|
|
576
|
-
|
|
559
|
+
fireTrackingPixels2(currentAd.trackingUrls.start);
|
|
577
560
|
console.log("[HlsAdPlayer] Ad started playing");
|
|
578
561
|
});
|
|
579
562
|
adVideoElement.addEventListener("ended", function() {
|
|
580
563
|
if (!currentAd || trackingFired.complete) return;
|
|
581
564
|
trackingFired.complete = true;
|
|
582
|
-
|
|
565
|
+
fireTrackingPixels2(currentAd.trackingUrls.complete);
|
|
583
566
|
console.log("[HlsAdPlayer] Ad completed");
|
|
584
567
|
handleAdComplete();
|
|
585
568
|
});
|
|
586
569
|
adVideoElement.addEventListener("error", function(e) {
|
|
587
570
|
console.error("[HlsAdPlayer] Ad video error:", e);
|
|
588
571
|
if (currentAd) {
|
|
589
|
-
|
|
572
|
+
fireTrackingPixels2(currentAd.trackingUrls.error);
|
|
590
573
|
}
|
|
591
574
|
handleAdError();
|
|
592
575
|
});
|
|
593
576
|
adVideoElement.addEventListener("volumechange", function() {
|
|
594
577
|
if (!currentAd) return;
|
|
595
578
|
if (adVideoElement.muted) {
|
|
596
|
-
|
|
579
|
+
fireTrackingPixels2(currentAd.trackingUrls.mute);
|
|
597
580
|
} else {
|
|
598
|
-
|
|
581
|
+
fireTrackingPixels2(currentAd.trackingUrls.unmute);
|
|
599
582
|
}
|
|
600
583
|
});
|
|
601
584
|
adVideoElement.addEventListener("pause", function() {
|
|
602
585
|
if (currentAd && !adVideoElement.ended) {
|
|
603
|
-
|
|
586
|
+
fireTrackingPixels2(currentAd.trackingUrls.pause);
|
|
604
587
|
}
|
|
605
588
|
});
|
|
606
589
|
adVideoElement.addEventListener("play", function() {
|
|
607
590
|
if (currentAd && adVideoElement.currentTime > 0) {
|
|
608
|
-
|
|
591
|
+
fireTrackingPixels2(currentAd.trackingUrls.resume);
|
|
609
592
|
}
|
|
610
593
|
});
|
|
611
594
|
}
|
|
@@ -620,44 +603,32 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
620
603
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
621
604
|
adPlaying = false;
|
|
622
605
|
setAdPlayingFlag(false);
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
if (
|
|
631
|
-
console.log("[HlsAdPlayer]
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
var idx = pendingTimeouts.indexOf(timeoutId);
|
|
638
|
-
if (idx !== -1) {
|
|
639
|
-
pendingTimeouts.splice(idx, 1);
|
|
606
|
+
contentVideo.muted = true;
|
|
607
|
+
contentVideo.volume = 0;
|
|
608
|
+
if (adContainerEl) {
|
|
609
|
+
adContainerEl.style.display = "none";
|
|
610
|
+
adContainerEl.style.pointerEvents = "none";
|
|
611
|
+
}
|
|
612
|
+
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
613
|
+
if (contentVideo.paused) {
|
|
614
|
+
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
|
|
615
|
+
contentVideo.play().catch(function() {});
|
|
616
|
+
} else {
|
|
617
|
+
console.log("[HlsAdPlayer] Content video already playing in live mode");
|
|
640
618
|
}
|
|
641
|
-
}
|
|
642
|
-
|
|
619
|
+
}
|
|
620
|
+
emit("content_resume");
|
|
643
621
|
}
|
|
644
622
|
function handleAdError() {
|
|
645
623
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
646
624
|
adPlaying = false;
|
|
647
625
|
setAdPlayingFlag(false);
|
|
648
|
-
|
|
649
|
-
contentVideo.
|
|
650
|
-
contentVideo.volume = originalMutedState ? 0 : originalVolume;
|
|
651
|
-
console.log("[HlsAdPlayer] Restored mute state: ".concat(previousMutedState, " -> ").concat(originalMutedState));
|
|
626
|
+
contentVideo.muted = true;
|
|
627
|
+
contentVideo.volume = 0;
|
|
652
628
|
if (adContainerEl) {
|
|
653
629
|
adContainerEl.style.display = "none";
|
|
654
630
|
adContainerEl.style.pointerEvents = "none";
|
|
655
631
|
}
|
|
656
|
-
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
657
|
-
if (contentVideo.paused) {
|
|
658
|
-
contentVideo.play().catch(function() {});
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
632
|
emit("ad_error");
|
|
662
633
|
}
|
|
663
634
|
return {
|
|
@@ -681,13 +652,19 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
681
652
|
adContainerEl = container;
|
|
682
653
|
}
|
|
683
654
|
},
|
|
684
|
-
requestAds: function requestAds(
|
|
655
|
+
requestAds: function requestAds(vastTagUrl) {
|
|
685
656
|
return _async_to_generator(function() {
|
|
686
|
-
var
|
|
657
|
+
var ad, error;
|
|
687
658
|
return _ts_generator(this, function(_state) {
|
|
688
659
|
switch(_state.label){
|
|
689
660
|
case 0:
|
|
690
|
-
|
|
661
|
+
if (destroyed) {
|
|
662
|
+
return [
|
|
663
|
+
2,
|
|
664
|
+
Promise.reject(new Error("Controller has been destroyed"))
|
|
665
|
+
];
|
|
666
|
+
}
|
|
667
|
+
console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
|
|
691
668
|
if (adPlaying) {
|
|
692
669
|
console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
|
|
693
670
|
return [
|
|
@@ -699,40 +676,48 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
699
676
|
case 1:
|
|
700
677
|
_state.trys.push([
|
|
701
678
|
1,
|
|
702
|
-
|
|
679
|
+
5,
|
|
703
680
|
,
|
|
704
|
-
|
|
681
|
+
6
|
|
705
682
|
]);
|
|
706
683
|
sessionId = generateSessionId();
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
684
|
+
if (!preloadedAds.has(vastTagUrl)) return [
|
|
685
|
+
3,
|
|
686
|
+
2
|
|
687
|
+
];
|
|
688
|
+
ad = preloadedAds.get(vastTagUrl);
|
|
689
|
+
preloadedAds.delete(vastTagUrl);
|
|
690
|
+
console.log("[HlsAdPlayer] Using preloaded VAST response:", vastTagUrl);
|
|
713
691
|
return [
|
|
714
|
-
|
|
715
|
-
|
|
692
|
+
3,
|
|
693
|
+
4
|
|
716
694
|
];
|
|
717
695
|
case 2:
|
|
696
|
+
return [
|
|
697
|
+
4,
|
|
698
|
+
fetchAndParseVastAdLocal(vastTagUrl)
|
|
699
|
+
];
|
|
700
|
+
case 3:
|
|
718
701
|
ad = _state.sent();
|
|
702
|
+
_state.label = 4;
|
|
703
|
+
case 4:
|
|
719
704
|
if (!ad) {
|
|
720
705
|
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
721
706
|
emit("ad_error");
|
|
722
707
|
return [
|
|
723
708
|
2,
|
|
724
|
-
Promise.
|
|
709
|
+
Promise.reject(new Error("No ads available from VAST response"))
|
|
725
710
|
];
|
|
726
711
|
}
|
|
727
712
|
currentAd = ad;
|
|
728
713
|
console.log("[HlsAdPlayer] Ad parsed: ".concat(ad.title, ", duration: ").concat(ad.duration, "s"));
|
|
729
|
-
|
|
714
|
+
fireTrackingPixels2(ad.trackingUrls.impression);
|
|
730
715
|
trackingFired.impression = true;
|
|
731
716
|
return [
|
|
732
717
|
2,
|
|
733
718
|
Promise.resolve()
|
|
734
719
|
];
|
|
735
|
-
case
|
|
720
|
+
case 5:
|
|
736
721
|
error = _state.sent();
|
|
737
722
|
console.error("[HlsAdPlayer] Error requesting ads:", error);
|
|
738
723
|
emit("ad_error");
|
|
@@ -740,7 +725,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
740
725
|
2,
|
|
741
726
|
Promise.reject(error)
|
|
742
727
|
];
|
|
743
|
-
case
|
|
728
|
+
case 6:
|
|
744
729
|
return [
|
|
745
730
|
2
|
|
746
731
|
];
|
|
@@ -752,6 +737,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
752
737
|
return _async_to_generator(function() {
|
|
753
738
|
var contentVolume, adVolume, mediaFile;
|
|
754
739
|
return _ts_generator(this, function(_state) {
|
|
740
|
+
if (destroyed) {
|
|
741
|
+
return [
|
|
742
|
+
2,
|
|
743
|
+
Promise.reject(new Error("Controller has been destroyed"))
|
|
744
|
+
];
|
|
745
|
+
}
|
|
755
746
|
if (!currentAd) {
|
|
756
747
|
console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
|
|
757
748
|
return [
|
|
@@ -853,16 +844,53 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
853
844
|
});
|
|
854
845
|
})();
|
|
855
846
|
},
|
|
847
|
+
pause: function pause() {
|
|
848
|
+
if (!adPlaying || !adVideoElement) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
if (adVideoElement && !adVideoElement.paused) {
|
|
853
|
+
adVideoElement.pause();
|
|
854
|
+
}
|
|
855
|
+
} catch (error) {
|
|
856
|
+
console.warn("[HlsAdPlayer] Error pausing ad:", error);
|
|
857
|
+
}
|
|
858
|
+
},
|
|
859
|
+
resume: function resume() {
|
|
860
|
+
if (!adPlaying || !adVideoElement) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
try {
|
|
864
|
+
if (adVideoElement && adVideoElement.paused) {
|
|
865
|
+
adVideoElement.play().catch(function() {});
|
|
866
|
+
}
|
|
867
|
+
} catch (error) {
|
|
868
|
+
console.warn("[HlsAdPlayer] Error resuming ad:", error);
|
|
869
|
+
}
|
|
870
|
+
},
|
|
856
871
|
stop: function stop() {
|
|
857
872
|
return _async_to_generator(function() {
|
|
873
|
+
var previousMutedState;
|
|
858
874
|
return _ts_generator(this, function(_state) {
|
|
859
875
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
860
876
|
adPlaying = false;
|
|
861
877
|
setAdPlayingFlag(false);
|
|
878
|
+
previousMutedState = contentVideo.muted;
|
|
879
|
+
contentVideo.muted = originalMutedState;
|
|
880
|
+
contentVideo.volume = originalMutedState ? 0 : originalVolume;
|
|
881
|
+
console.log("[HlsAdPlayer] Restored mute state on stop: ".concat(previousMutedState, " -> ").concat(originalMutedState));
|
|
862
882
|
if (adContainerEl) {
|
|
863
883
|
adContainerEl.style.display = "none";
|
|
864
884
|
adContainerEl.style.pointerEvents = "none";
|
|
865
885
|
}
|
|
886
|
+
contentVideo.style.visibility = "visible";
|
|
887
|
+
contentVideo.style.opacity = "1";
|
|
888
|
+
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
889
|
+
if (contentVideo.paused) {
|
|
890
|
+
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback on stop");
|
|
891
|
+
contentVideo.play().catch(function() {});
|
|
892
|
+
}
|
|
893
|
+
}
|
|
866
894
|
if (adHls) {
|
|
867
895
|
adHls.destroy();
|
|
868
896
|
adHls = void 0;
|
|
@@ -922,6 +950,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
922
950
|
adContainerEl = void 0;
|
|
923
951
|
currentAd = void 0;
|
|
924
952
|
listeners.clear();
|
|
953
|
+
preloadedAds.clear();
|
|
954
|
+
preloadingAds.clear();
|
|
925
955
|
},
|
|
926
956
|
isAdPlaying: function isAdPlaying() {
|
|
927
957
|
return adPlaying;
|
|
@@ -969,6 +999,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
969
999
|
return 1;
|
|
970
1000
|
},
|
|
971
1001
|
showPlaceholder: function showPlaceholder() {
|
|
1002
|
+
contentVideo.style.opacity = "0";
|
|
1003
|
+
contentVideo.style.visibility = "hidden";
|
|
972
1004
|
if (!adContainerEl) {
|
|
973
1005
|
var _contentVideo_parentElement;
|
|
974
1006
|
var container = document.createElement("div");
|
|
@@ -996,6 +1028,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
996
1028
|
adContainerEl.style.display = "none";
|
|
997
1029
|
adContainerEl.style.pointerEvents = "none";
|
|
998
1030
|
}
|
|
1031
|
+
if (!adPlaying) {
|
|
1032
|
+
contentVideo.style.visibility = "visible";
|
|
1033
|
+
contentVideo.style.opacity = "1";
|
|
1034
|
+
}
|
|
999
1035
|
}
|
|
1000
1036
|
};
|
|
1001
1037
|
}
|