stormcloud-video-player 0.3.13 → 0.3.14
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/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +57 -46
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +57 -46
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +57 -46
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +2 -0
- package/lib/players/HlsPlayer.cjs +57 -46
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +57 -46
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +26 -5
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +57 -46
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/lib/players/index.cjs
CHANGED
|
@@ -964,6 +964,8 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
964
964
|
let sessionId;
|
|
965
965
|
const preloadedAds = /* @__PURE__ */ new Map();
|
|
966
966
|
const preloadingAds = /* @__PURE__ */ new Map();
|
|
967
|
+
let destroyed = false;
|
|
968
|
+
let pendingTimeouts = [];
|
|
967
969
|
let trackingFired = {
|
|
968
970
|
impression: false,
|
|
969
971
|
start: false,
|
|
@@ -1292,13 +1294,27 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1292
1294
|
adPlaying = false;
|
|
1293
1295
|
setAdPlayingFlag(false);
|
|
1294
1296
|
emit("content_resume");
|
|
1295
|
-
setTimeout(() => {
|
|
1296
|
-
if (
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1297
|
+
const timeoutId = window.setTimeout(() => {
|
|
1298
|
+
if (destroyed) {
|
|
1299
|
+
console.log("[HlsAdPlayer] Player destroyed, skipping post-completion check");
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
const stillInPod = contentVideo.dataset.stormcloudAdPlaying === "true";
|
|
1303
|
+
if (stillInPod) {
|
|
1304
|
+
console.log(
|
|
1305
|
+
"[HlsAdPlayer] Still in ad pod - keeping ad container visible (black screen)"
|
|
1306
|
+
);
|
|
1307
|
+
if (adContainerEl) {
|
|
1308
|
+
adContainerEl.style.display = "flex";
|
|
1309
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
const idx = pendingTimeouts.indexOf(timeoutId);
|
|
1313
|
+
if (idx !== -1) {
|
|
1314
|
+
pendingTimeouts.splice(idx, 1);
|
|
1300
1315
|
}
|
|
1301
1316
|
}, 50);
|
|
1317
|
+
pendingTimeouts.push(timeoutId);
|
|
1302
1318
|
}
|
|
1303
1319
|
function handleAdError() {
|
|
1304
1320
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
@@ -1528,6 +1544,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1528
1544
|
},
|
|
1529
1545
|
destroy() {
|
|
1530
1546
|
console.log("[HlsAdPlayer] Destroying");
|
|
1547
|
+
destroyed = true;
|
|
1548
|
+
for (const timeoutId of pendingTimeouts) {
|
|
1549
|
+
clearTimeout(timeoutId);
|
|
1550
|
+
}
|
|
1551
|
+
pendingTimeouts = [];
|
|
1531
1552
|
adPlaying = false;
|
|
1532
1553
|
setAdPlayingFlag(false);
|
|
1533
1554
|
contentVideo.muted = originalMutedState;
|
|
@@ -2440,10 +2461,11 @@ var StormcloudVideoPlayer = class {
|
|
|
2440
2461
|
this.handleAdPodComplete();
|
|
2441
2462
|
}
|
|
2442
2463
|
});
|
|
2443
|
-
this.
|
|
2464
|
+
this.timeUpdateHandler = () => {
|
|
2444
2465
|
this.onTimeUpdate(this.video.currentTime);
|
|
2445
|
-
}
|
|
2446
|
-
this.video.addEventListener("
|
|
2466
|
+
};
|
|
2467
|
+
this.video.addEventListener("timeupdate", this.timeUpdateHandler);
|
|
2468
|
+
this.emptiedHandler = () => {
|
|
2447
2469
|
if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
|
|
2448
2470
|
if (this.config.debugAdTiming) {
|
|
2449
2471
|
console.log(
|
|
@@ -2460,7 +2482,8 @@ var StormcloudVideoPlayer = class {
|
|
|
2460
2482
|
});
|
|
2461
2483
|
}
|
|
2462
2484
|
}
|
|
2463
|
-
}
|
|
2485
|
+
};
|
|
2486
|
+
this.video.addEventListener("emptied", this.emptiedHandler);
|
|
2464
2487
|
}
|
|
2465
2488
|
shouldUseNativeHls() {
|
|
2466
2489
|
const streamType = this.getStreamType();
|
|
@@ -3152,7 +3175,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3152
3175
|
continue;
|
|
3153
3176
|
}
|
|
3154
3177
|
if (this.config.debugAdTiming) {
|
|
3155
|
-
console.log(`[CONTINUOUS-FETCH] \u{1F4E1} Attempting to fetch ad
|
|
3178
|
+
console.log(`[CONTINUOUS-FETCH] \u{1F4E1} Attempting to fetch ad (${this.successfulAdRequests.length + this.adRequestQueue.length + 1} total)...`);
|
|
3156
3179
|
}
|
|
3157
3180
|
try {
|
|
3158
3181
|
const response = await fetch(newAdUrl, { mode: "cors" });
|
|
@@ -3168,8 +3191,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3168
3191
|
console.log("[CONTINUOUS-FETCH] \u26A0\uFE0F VAST response has no media files, skipping");
|
|
3169
3192
|
}
|
|
3170
3193
|
this.failedVastUrls.add(newAdUrl);
|
|
3171
|
-
|
|
3172
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
3194
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
3173
3195
|
continue;
|
|
3174
3196
|
}
|
|
3175
3197
|
if (this.config.debugAdTiming) {
|
|
@@ -3177,19 +3199,17 @@ var StormcloudVideoPlayer = class {
|
|
|
3177
3199
|
}
|
|
3178
3200
|
this.adRequestQueue.push(newAdUrl);
|
|
3179
3201
|
this.totalAdsInBreak++;
|
|
3180
|
-
|
|
3181
|
-
await new Promise((resolve) => setTimeout(resolve, successDelay));
|
|
3202
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3182
3203
|
} catch (error) {
|
|
3183
3204
|
if (this.config.debugAdTiming) {
|
|
3184
3205
|
console.log("[CONTINUOUS-FETCH] \u274C Ad fetch failed:", error.message);
|
|
3185
3206
|
}
|
|
3186
3207
|
this.failedVastUrls.add(newAdUrl);
|
|
3187
|
-
|
|
3188
|
-
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
3208
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
3189
3209
|
}
|
|
3190
3210
|
}
|
|
3191
3211
|
if (this.config.debugAdTiming) {
|
|
3192
|
-
console.log(
|
|
3212
|
+
console.log("[CONTINUOUS-FETCH] \u{1F6D1} Continuous fetch loop ended");
|
|
3193
3213
|
}
|
|
3194
3214
|
}
|
|
3195
3215
|
stopContinuousFetching() {
|
|
@@ -3227,27 +3247,20 @@ var StormcloudVideoPlayer = class {
|
|
|
3227
3247
|
return;
|
|
3228
3248
|
}
|
|
3229
3249
|
}
|
|
3230
|
-
const
|
|
3231
|
-
|
|
3232
|
-
const retryDelayMs = hasPlayedAtLeastOneAd ? 500 : 1e3;
|
|
3233
|
-
const minRemainingForRetry = 1e3;
|
|
3234
|
-
if (this.continuousFetchingActive && retryCount < maxRetries && remaining > minRemainingForRetry) {
|
|
3250
|
+
const maxRetries = 5;
|
|
3251
|
+
if (this.continuousFetchingActive && retryCount < maxRetries && remaining > 2e3) {
|
|
3235
3252
|
if (this.config.debugAdTiming) {
|
|
3236
|
-
console.log(`[CONTINUOUS-FETCH] \u23F3 Queue empty but fetching active, waiting
|
|
3253
|
+
console.log(`[CONTINUOUS-FETCH] \u23F3 Queue empty but fetching active, waiting... (retry ${retryCount + 1}/${maxRetries})`);
|
|
3237
3254
|
}
|
|
3238
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
3255
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
3239
3256
|
await this.tryNextAvailableAd(retryCount + 1);
|
|
3240
3257
|
return;
|
|
3241
3258
|
}
|
|
3242
|
-
|
|
3243
|
-
if (!this.isShowingPlaceholder && remaining >= minTimeForPlaceholder && this.continuousFetchingActive) {
|
|
3244
|
-
if (this.config.debugAdTiming) {
|
|
3245
|
-
console.log(`[CONTINUOUS-FETCH] \u2B1B Last resort: showing placeholder (${remaining}ms remaining)`);
|
|
3246
|
-
}
|
|
3259
|
+
if (!this.isShowingPlaceholder && remaining > 1e3) {
|
|
3247
3260
|
this.showPlaceholderAndWaitForAds();
|
|
3248
3261
|
} else {
|
|
3249
3262
|
if (this.config.debugAdTiming) {
|
|
3250
|
-
console.log(
|
|
3263
|
+
console.log("[CONTINUOUS-FETCH] \u23F9\uFE0F No more ads available, ending ad break");
|
|
3251
3264
|
}
|
|
3252
3265
|
this.handleAdPodComplete();
|
|
3253
3266
|
}
|
|
@@ -3255,36 +3268,26 @@ var StormcloudVideoPlayer = class {
|
|
|
3255
3268
|
async showPlaceholderAndWaitForAds() {
|
|
3256
3269
|
const remaining = this.getRemainingAdMs();
|
|
3257
3270
|
const waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);
|
|
3258
|
-
if (waitTime <
|
|
3259
|
-
if (this.config.debugAdTiming) {
|
|
3260
|
-
console.log(`[CONTINUOUS-FETCH] \u23F9\uFE0F Insufficient time for placeholder (${waitTime}ms), ending ad break`);
|
|
3261
|
-
}
|
|
3271
|
+
if (waitTime < 1e3) {
|
|
3262
3272
|
this.handleAdPodComplete();
|
|
3263
3273
|
return;
|
|
3264
3274
|
}
|
|
3265
3275
|
if (this.config.debugAdTiming) {
|
|
3266
|
-
console.log(`[CONTINUOUS-FETCH] \u2B1B Showing black placeholder for
|
|
3276
|
+
console.log(`[CONTINUOUS-FETCH] \u2B1B Showing black placeholder for ${waitTime}ms while waiting for ads`);
|
|
3267
3277
|
}
|
|
3268
3278
|
this.isShowingPlaceholder = true;
|
|
3269
3279
|
this.placeholderStartTimeMs = Date.now();
|
|
3270
3280
|
this.ima.showPlaceholder();
|
|
3271
|
-
const checkInterval =
|
|
3281
|
+
const checkInterval = 500;
|
|
3272
3282
|
const maxChecks = Math.floor(waitTime / checkInterval);
|
|
3273
3283
|
for (let i = 0; i < maxChecks; i++) {
|
|
3274
3284
|
await new Promise((resolve) => setTimeout(resolve, checkInterval));
|
|
3275
3285
|
if (!this.inAdBreak) {
|
|
3276
|
-
if (this.config.debugAdTiming) {
|
|
3277
|
-
console.log("[CONTINUOUS-FETCH] \u2139\uFE0F Ad break ended during placeholder wait");
|
|
3278
|
-
}
|
|
3279
|
-
this.isShowingPlaceholder = false;
|
|
3280
|
-
this.placeholderStartTimeMs = null;
|
|
3281
|
-
this.ima.hidePlaceholder();
|
|
3282
3286
|
return;
|
|
3283
3287
|
}
|
|
3284
3288
|
if (this.adRequestQueue.length > 0) {
|
|
3285
|
-
const elapsedInPlaceholder = Date.now() - (this.placeholderStartTimeMs || Date.now());
|
|
3286
3289
|
if (this.config.debugAdTiming) {
|
|
3287
|
-
console.log(
|
|
3290
|
+
console.log("[CONTINUOUS-FETCH] \u2705 New ad became available during placeholder");
|
|
3288
3291
|
}
|
|
3289
3292
|
this.isShowingPlaceholder = false;
|
|
3290
3293
|
this.placeholderStartTimeMs = null;
|
|
@@ -3303,9 +3306,8 @@ var StormcloudVideoPlayer = class {
|
|
|
3303
3306
|
return;
|
|
3304
3307
|
}
|
|
3305
3308
|
}
|
|
3306
|
-
const totalPlaceholderTime = Date.now() - (this.placeholderStartTimeMs || Date.now());
|
|
3307
3309
|
if (this.config.debugAdTiming) {
|
|
3308
|
-
console.log(
|
|
3310
|
+
console.log("[CONTINUOUS-FETCH] \u23F0 Placeholder timeout reached, no ads fetched");
|
|
3309
3311
|
}
|
|
3310
3312
|
this.isShowingPlaceholder = false;
|
|
3311
3313
|
this.placeholderStartTimeMs = null;
|
|
@@ -4117,6 +4119,15 @@ var StormcloudVideoPlayer = class {
|
|
|
4117
4119
|
this.clearAdStartTimer();
|
|
4118
4120
|
this.clearAdStopTimer();
|
|
4119
4121
|
this.clearAdFailsafeTimer();
|
|
4122
|
+
this.clearAdRequestWatchdog();
|
|
4123
|
+
if (this.timeUpdateHandler) {
|
|
4124
|
+
this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
|
|
4125
|
+
delete this.timeUpdateHandler;
|
|
4126
|
+
}
|
|
4127
|
+
if (this.emptiedHandler) {
|
|
4128
|
+
this.video.removeEventListener("emptied", this.emptiedHandler);
|
|
4129
|
+
delete this.emptiedHandler;
|
|
4130
|
+
}
|
|
4120
4131
|
if (this.heartbeatInterval) {
|
|
4121
4132
|
clearInterval(this.heartbeatInterval);
|
|
4122
4133
|
this.heartbeatInterval = void 0;
|