stormcloud-video-player 0.8.43 → 0.8.44

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.
@@ -1,4 +1,4 @@
1
- import { A as AdController } from '../types-cTqIKw_D.cjs';
1
+ import { A as AdController } from '../types-iDjS8f_7.cjs';
2
2
  import Hls from 'hls.js';
3
3
 
4
4
  declare function createHlsAdPlayer(contentVideo: HTMLVideoElement, options?: {
@@ -0,0 +1,133 @@
1
+ interface AdBreak {
2
+ id?: string;
3
+ startTimeMs: number;
4
+ durationMs?: number;
5
+ vastTagUrl?: string;
6
+ }
7
+ interface StormcloudVideoPlayerConfig {
8
+ videoElement: HTMLVideoElement;
9
+ src: string;
10
+ autoplay?: boolean;
11
+ muted?: boolean;
12
+ allowNativeHls?: boolean;
13
+ lowLatencyMode?: boolean;
14
+ isLiveStream?: boolean;
15
+ pauseContentDuringAds?: boolean;
16
+ driftToleranceMs?: number;
17
+ immediateManifestAds?: boolean;
18
+ debugAdTiming?: boolean;
19
+ adFailsafeTimeoutMs?: number;
20
+ adBreakCheckIntervalMs?: number;
21
+ maxAdBreakExtensionMs?: number;
22
+ minRemainingMsToStartAd?: number;
23
+ showCustomControls?: boolean;
24
+ hideLoadingIndicator?: boolean;
25
+ onVolumeToggle?: () => void;
26
+ onFullscreenToggle?: () => void;
27
+ onControlClick?: () => void;
28
+ licenseKey?: string;
29
+ vastTagUrl?: string;
30
+ isVmap?: boolean;
31
+ vmapUrl?: string;
32
+ vastMode?: 'adstorm' | 'default';
33
+ minSegmentsBeforePlay?: number;
34
+ ctvAdRequest?: boolean;
35
+ adTest?: boolean;
36
+ podMaxAds?: number;
37
+ podMaxDurationMs?: number;
38
+ podExactDuration?: boolean;
39
+ }
40
+ interface Scte35Marker {
41
+ type: "start" | "end" | "progress";
42
+ ptsSeconds?: number;
43
+ durationSeconds?: number;
44
+ raw?: unknown;
45
+ }
46
+ interface Id3TagInfo {
47
+ key: string;
48
+ value: string | Uint8Array;
49
+ ptsSeconds?: number;
50
+ }
51
+ interface AdController {
52
+ initialize: () => void;
53
+ requestAds: (vastTagUrl: string) => Promise<void>;
54
+ play: () => Promise<void>;
55
+ pause: () => void;
56
+ resume: () => void;
57
+ stop: () => Promise<void>;
58
+ destroy: () => void;
59
+ isAdPlaying: () => boolean;
60
+ resize: (width: number, height: number) => void;
61
+ on: (event: string, listener: (payload?: any) => void) => void;
62
+ off: (event: string, listener: (payload?: any) => void) => void;
63
+ updateOriginalMutedState: (muted: boolean, volume?: number) => void;
64
+ getOriginalMutedState: () => boolean;
65
+ getOriginalVolume: () => number;
66
+ setAdVolume: (volume: number) => void;
67
+ getAdVolume: () => number;
68
+ showPlaceholder: () => void;
69
+ hidePlaceholder: () => void;
70
+ getLoadedAdDuration?: () => number | undefined;
71
+ getLoadedAdId?: () => string | undefined;
72
+ getPodAdCount?: () => number;
73
+ getPodTotalDurationMs?: () => number;
74
+ }
75
+ interface ClientInfo {
76
+ brand: string;
77
+ os: string;
78
+ model: string;
79
+ deviceType: "tv" | "mobile" | "tablet" | "desktop";
80
+ isSmartTV: boolean;
81
+ isAndroid: boolean;
82
+ isWebView: boolean;
83
+ isWebApp: boolean;
84
+ domain: string;
85
+ origin: string;
86
+ path: string;
87
+ userAgent: string;
88
+ vendor: string;
89
+ platform: string;
90
+ screen: {
91
+ width?: number;
92
+ height?: number;
93
+ availWidth?: number;
94
+ availHeight?: number;
95
+ orientation?: string;
96
+ pixelDepth?: number;
97
+ };
98
+ hardwareConcurrency: number;
99
+ deviceMemory: number | null;
100
+ maxTouchPoints: number;
101
+ language: string;
102
+ languages: string;
103
+ cookieEnabled: boolean;
104
+ doNotTrack: string;
105
+ referrer: string;
106
+ visibilityState: string;
107
+ }
108
+ interface PlayerAnalyticsContext {
109
+ inputStreamType?: string;
110
+ debugAdTiming?: boolean;
111
+ }
112
+ interface AdDetectInfo {
113
+ source: "scte35";
114
+ durationSeconds?: number;
115
+ ptsSeconds?: number;
116
+ detectedAtFragmentSn?: number;
117
+ timestamp: string;
118
+ }
119
+ interface AdLoadedInfo {
120
+ source: "vast" | "hls";
121
+ vastUrl?: string;
122
+ durationSeconds?: number;
123
+ timestamp: string;
124
+ }
125
+ interface AdImpressionInfo {
126
+ source: "vast" | "hls";
127
+ adIndex: number;
128
+ adUrl?: string;
129
+ durationSeconds?: number;
130
+ timestamp: string;
131
+ }
132
+
133
+ export type { AdController as A, ClientInfo as C, Id3TagInfo as I, PlayerAnalyticsContext as P, StormcloudVideoPlayerConfig as S, Scte35Marker as a, AdBreak as b, AdDetectInfo as c, AdImpressionInfo as d, AdLoadedInfo as e };
@@ -8083,6 +8083,34 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8083
8083
  return 0;
8084
8084
  }
8085
8085
  },
8086
+ {
8087
+ key: "describeVideoState",
8088
+ value: function describeVideoState() {
8089
+ var _networkStates_v_networkState, _readyStates_v_readyState;
8090
+ var v = this.host.video;
8091
+ var networkStates = [
8092
+ "EMPTY",
8093
+ "IDLE",
8094
+ "LOADING",
8095
+ "NO_SOURCE"
8096
+ ];
8097
+ var readyStates = [
8098
+ "HAVE_NOTHING",
8099
+ "HAVE_METADATA",
8100
+ "HAVE_CURRENT_DATA",
8101
+ "HAVE_FUTURE_DATA",
8102
+ "HAVE_ENOUGH_DATA"
8103
+ ];
8104
+ var net = (_networkStates_v_networkState = networkStates[v.networkState]) !== null && _networkStates_v_networkState !== void 0 ? _networkStates_v_networkState : String(v.networkState);
8105
+ var ready = (_readyStates_v_readyState = readyStates[v.readyState]) !== null && _readyStates_v_readyState !== void 0 ? _readyStates_v_readyState : String(v.readyState);
8106
+ var err = v.error ? "code=".concat(v.error.code).concat(v.error.message ? " (".concat(v.error.message, ")") : "") : "none";
8107
+ var ranges = [];
8108
+ for(var i = 0; i < v.buffered.length; i++){
8109
+ ranges.push("[".concat(v.buffered.start(i).toFixed(2), "–").concat(v.buffered.end(i).toFixed(2), "]"));
8110
+ }
8111
+ return "t=".concat(v.currentTime.toFixed(2), "s paused=").concat(v.paused, " ended=").concat(v.ended, " seeking=").concat(v.seeking, " readyState=").concat(ready, " networkState=").concat(net, " error=").concat(err, " buffered=").concat(ranges.length ? ranges.join(",") : "none");
8112
+ }
8113
+ },
8086
8114
  {
8087
8115
  key: "monitorLiveResumeStall",
8088
8116
  value: function monitorLiveResumeStall(resumeBaseline) {
@@ -8096,18 +8124,93 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8096
8124
  var baseline = resumeBaseline;
8097
8125
  var recoveries = 0;
8098
8126
  var lastRecoveryAt = 0;
8127
+ var video = this.host.video;
8128
+ var listenersAttached = false;
8129
+ var onMediaEvent;
8130
+ var diagEvents = [
8131
+ "loadstart",
8132
+ "loadedmetadata",
8133
+ "loadeddata",
8134
+ "canplay",
8135
+ "canplaythrough",
8136
+ "play",
8137
+ "playing",
8138
+ "pause",
8139
+ "waiting",
8140
+ "stalled",
8141
+ "suspend",
8142
+ "seeking",
8143
+ "seeked",
8144
+ "emptied",
8145
+ "error",
8146
+ "ended"
8147
+ ];
8148
+ if (this.debug) {
8149
+ onMediaEvent = function onMediaEvent(e) {
8150
+ var dt = ((Date.now() - startTime) / 1e3).toFixed(1);
8151
+ console.log("[ResumeDiag] +".concat(dt, "s event=").concat(e.type, " — ").concat(_this.describeVideoState()));
8152
+ };
8153
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8154
+ try {
8155
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8156
+ var name = _step.value;
8157
+ video.addEventListener(name, onMediaEvent);
8158
+ }
8159
+ } catch (err) {
8160
+ _didIteratorError = true;
8161
+ _iteratorError = err;
8162
+ } finally{
8163
+ try {
8164
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8165
+ _iterator.return();
8166
+ }
8167
+ } finally{
8168
+ if (_didIteratorError) {
8169
+ throw _iteratorError;
8170
+ }
8171
+ }
8172
+ }
8173
+ listenersAttached = true;
8174
+ console.log("[ResumeDiag] +0.0s monitor start — ".concat(this.describeVideoState()));
8175
+ }
8176
+ var cleanup = function cleanup() {
8177
+ if (listenersAttached && onMediaEvent) {
8178
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
8179
+ try {
8180
+ for(var _iterator = diagEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
8181
+ var name = _step.value;
8182
+ video.removeEventListener(name, onMediaEvent);
8183
+ }
8184
+ } catch (err) {
8185
+ _didIteratorError = true;
8186
+ _iteratorError = err;
8187
+ } finally{
8188
+ try {
8189
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
8190
+ _iterator.return();
8191
+ }
8192
+ } finally{
8193
+ if (_didIteratorError) {
8194
+ throw _iteratorError;
8195
+ }
8196
+ }
8197
+ }
8198
+ listenersAttached = false;
8199
+ }
8200
+ };
8099
8201
  var poll = function poll1() {
8100
8202
  if (_this.inAdBreak) {
8203
+ cleanup();
8101
8204
  return;
8102
8205
  }
8103
- var video = _this.host.video;
8104
8206
  var currentTime = video.currentTime;
8105
8207
  var advanced = currentTime > baseline + 0.5;
8106
8208
  var playing = !video.paused && video.readyState >= 3;
8107
8209
  if (advanced && playing) {
8108
8210
  if (_this.debug) {
8109
- console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break");
8211
+ console.log("[StormcloudVideoPlayer] Live stream resumed successfully after ad break".concat(_this.describeVideoState()));
8110
8212
  }
8213
+ cleanup();
8111
8214
  return;
8112
8215
  }
8113
8216
  if (video.paused) {
@@ -8119,8 +8222,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8119
8222
  var wedged = bufferedAhead < 0.5 && !advanced;
8120
8223
  if (elapsed >= maxMonitorMs) {
8121
8224
  if (_this.debug && !advanced) {
8122
- console.warn("[StormcloudVideoPlayer] Live stream failed to resume after ".concat((maxMonitorMs / 1e3).toFixed(0), "s (t=").concat(currentTime.toFixed(2), "s, buffered=").concat(bufferedAhead.toFixed(2), "s)"));
8225
+ console.warn("[StormcloudVideoPlayer] Live stream failed to resume after ".concat((maxMonitorMs / 1e3).toFixed(0), "s ").concat(_this.describeVideoState()));
8123
8226
  }
8227
+ cleanup();
8124
8228
  return;
8125
8229
  }
8126
8230
  var canRecover = wedged && elapsed >= graceMs && Date.now() - lastRecoveryAt >= recoveryCooldownMs && recoveries < maxRecoveries;
@@ -8132,7 +8236,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8132
8236
  var liveSyncPos = _this.host.getLiveSyncPosition();
8133
8237
  var reloadPos = liveSyncPos != null && liveSyncPos > currentTime ? liveSyncPos : currentTime;
8134
8238
  if (_this.debug) {
8135
- console.warn("[StormcloudVideoPlayer] Content wedged after ad break (t=".concat(currentTime.toFixed(2), "s, buffered=").concat(bufferedAhead.toFixed(2), "s) — restarting HLS load at ").concat(reloadPos.toFixed(2), "s (recovery ").concat(recoveries, "/").concat(maxRecoveries, ")"));
8239
+ console.warn("[StormcloudVideoPlayer] Content wedged after ad break — restarting HLS load at ".concat(reloadPos.toFixed(2), "s (recovery ").concat(recoveries, "/").concat(maxRecoveries, ")").concat(_this.describeVideoState()));
8136
8240
  }
8137
8241
  if (liveSyncPos != null && liveSyncPos > currentTime) {
8138
8242
  video.currentTime = liveSyncPos;
@@ -8140,7 +8244,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
8140
8244
  _this.host.restartHlsLoad(reloadPos);
8141
8245
  } else {
8142
8246
  if (_this.debug) {
8143
- console.warn("[StormcloudVideoPlayer] Content still wedged after ad break (t=".concat(currentTime.toFixed(2), "s, buffered=").concat(bufferedAhead.toFixed(2), "s) — hard-reloading live stream (recovery ").concat(recoveries, "/").concat(maxRecoveries, ")"));
8247
+ console.warn("[StormcloudVideoPlayer] Content still wedged after ad break — hard-reloading live stream (recovery ".concat(recoveries, "/").concat(maxRecoveries, ")").concat(_this.describeVideoState()));
8144
8248
  }
8145
8249
  _this.host.reloadLiveStream();
8146
8250
  }