unified-video-framework 1.4.217 → 1.4.219

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 (29) hide show
  1. package/CHANGELOG.md +0 -102
  2. package/package.json +1 -1
  3. package/packages/core/dist/interfaces.d.ts +2 -34
  4. package/packages/core/dist/interfaces.d.ts.map +1 -1
  5. package/packages/core/src/interfaces.ts +3 -51
  6. package/packages/web/dist/ads/GoogleAdsManager.d.ts +39 -0
  7. package/packages/web/dist/ads/GoogleAdsManager.d.ts.map +1 -0
  8. package/packages/web/dist/ads/GoogleAdsManager.js +180 -0
  9. package/packages/web/dist/ads/GoogleAdsManager.js.map +1 -0
  10. package/packages/web/dist/index.d.ts +0 -1
  11. package/packages/web/dist/index.d.ts.map +1 -1
  12. package/packages/web/dist/index.js +0 -1
  13. package/packages/web/dist/index.js.map +1 -1
  14. package/packages/web/dist/react/WebPlayerView.d.ts +103 -0
  15. package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
  16. package/packages/web/dist/react/WebPlayerView.js +207 -2
  17. package/packages/web/dist/react/WebPlayerView.js.map +1 -1
  18. package/packages/web/dist/react/examples/google-ads-example.d.ts +4 -0
  19. package/packages/web/dist/react/examples/google-ads-example.d.ts.map +1 -0
  20. package/packages/web/dist/react/examples/google-ads-example.js +84 -0
  21. package/packages/web/dist/react/examples/google-ads-example.js.map +1 -0
  22. package/packages/web/src/ads/GoogleAdsManager.ts +358 -0
  23. package/packages/web/src/index.ts +0 -3
  24. package/packages/web/src/react/WebPlayerView.tsx +386 -3
  25. package/packages/web/src/react/examples/google-ads-example.tsx +196 -0
  26. package/packages/web/src/ads/AdsManager.ts +0 -691
  27. package/packages/web/src/ads/README.md +0 -403
  28. package/packages/web/src/ads/index.ts +0 -17
  29. package/packages/web/src/ads/types.ts +0 -442
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-ads-example.js","sourceRoot":"","sources":["../../../src/react/examples/google-ads-example.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Google IMA Ads Manager
3
+ * Supports ALL Google ad types:
4
+ * - Pre-roll (before video)
5
+ * - Mid-roll (during video)
6
+ * - Post-roll (after video)
7
+ * - Overlay ads (non-linear)
8
+ * - Companion ads (sidebar/banner)
9
+ * - Bumper ads (short 6s ads)
10
+ * - Skippable & non-skippable ads
11
+ */
12
+
13
+ export interface GoogleAdsConfig {
14
+ // Ad tag URL (VAST/VMAP)
15
+ adTagUrl: string;
16
+
17
+ // Optional: Specific ad break times (for mid-rolls)
18
+ // If not provided, uses VMAP schedule from ad server
19
+ midrollTimes?: number[]; // e.g., [30, 60, 120] = ads at 30s, 60s, 120s
20
+
21
+ // Companion ad containers
22
+ companionAdSlots?: Array<{
23
+ containerId: string; // HTML element ID
24
+ width: number;
25
+ height: number;
26
+ }>;
27
+
28
+ // Callbacks
29
+ onAdStart?: () => void;
30
+ onAdEnd?: () => void;
31
+ onAdError?: (error: any) => void;
32
+ onAllAdsComplete?: () => void;
33
+ }
34
+
35
+ export class GoogleAdsManager {
36
+ private video: HTMLVideoElement;
37
+ private adContainer: HTMLElement;
38
+ private config: GoogleAdsConfig;
39
+ private adsManager: any = null;
40
+ private adsLoader: any = null;
41
+ private adDisplayContainer: any = null;
42
+ private isAdPlaying = false;
43
+
44
+ constructor(video: HTMLVideoElement, adContainer: HTMLElement, config: GoogleAdsConfig) {
45
+ this.video = video;
46
+ this.adContainer = adContainer;
47
+ this.config = config;
48
+ }
49
+
50
+ /**
51
+ * Initialize ads system
52
+ */
53
+ async initialize(): Promise<void> {
54
+ try {
55
+ await this.loadIMASDK();
56
+ this.setupAdsLoader();
57
+ } catch (error) {
58
+ console.error('Failed to initialize Google Ads:', error);
59
+ this.config.onAdError?.(error);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Load Google IMA SDK
65
+ */
66
+ private loadIMASDK(): Promise<void> {
67
+ return new Promise((resolve, reject) => {
68
+ if ((window as any).google?.ima) {
69
+ resolve();
70
+ return;
71
+ }
72
+
73
+ const script = document.createElement('script');
74
+ script.src = 'https://imasdk.googleapis.com/js/sdkloader/ima3.js';
75
+ script.async = true;
76
+ script.onload = () => resolve();
77
+ script.onerror = () => reject(new Error('Failed to load Google IMA SDK'));
78
+ document.head.appendChild(script);
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Setup ads loader
84
+ */
85
+ private setupAdsLoader(): void {
86
+ const google = (window as any).google;
87
+
88
+ // Create ad display container
89
+ this.adDisplayContainer = new google.ima.AdDisplayContainer(
90
+ this.adContainer,
91
+ this.video
92
+ );
93
+
94
+ // Create ads loader
95
+ this.adsLoader = new google.ima.AdsLoader(this.adDisplayContainer);
96
+
97
+ // Register for ads loaded event
98
+ this.adsLoader.addEventListener(
99
+ google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
100
+ (event: any) => this.onAdsManagerLoaded(event),
101
+ false
102
+ );
103
+
104
+ // Register for error event
105
+ this.adsLoader.addEventListener(
106
+ google.ima.AdErrorEvent.Type.AD_ERROR,
107
+ (event: any) => this.onAdError(event),
108
+ false
109
+ );
110
+
111
+ // Signal when video content completes (for post-rolls)
112
+ this.video.addEventListener('ended', () => {
113
+ if (!this.isAdPlaying) {
114
+ this.adsLoader?.contentComplete();
115
+ }
116
+ });
117
+ }
118
+
119
+ /**
120
+ * Request ads
121
+ */
122
+ requestAds(): void {
123
+ const google = (window as any).google;
124
+
125
+ try {
126
+ const adsRequest = new google.ima.AdsRequest();
127
+ adsRequest.adTagUrl = this.config.adTagUrl;
128
+
129
+ // Set video dimensions
130
+ adsRequest.linearAdSlotWidth = this.video.clientWidth;
131
+ adsRequest.linearAdSlotHeight = this.video.clientHeight;
132
+ adsRequest.nonLinearAdSlotWidth = this.video.clientWidth;
133
+ adsRequest.nonLinearAdSlotHeight = Math.floor(this.video.clientHeight / 3);
134
+
135
+ // Set companion ad slots if provided
136
+ if (this.config.companionAdSlots && this.config.companionAdSlots.length > 0) {
137
+ const companionAdSlots = this.config.companionAdSlots.map(slot => {
138
+ return new google.ima.CompanionAdSelectionSettings();
139
+ });
140
+ adsRequest.setAdWillAutoPlay(true);
141
+ adsRequest.setAdWillPlayMuted(false);
142
+ }
143
+
144
+ // Request ads
145
+ this.adsLoader.requestAds(adsRequest);
146
+ } catch (error) {
147
+ console.error('Error requesting ads:', error);
148
+ this.config.onAdError?.(error);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Initialize ad display container (must be called on user gesture)
154
+ */
155
+ initAdDisplayContainer(): void {
156
+ try {
157
+ this.adDisplayContainer?.initialize();
158
+ } catch (error) {
159
+ console.warn('Ad display container already initialized');
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Handle ads manager loaded
165
+ */
166
+ private onAdsManagerLoaded(event: any): void {
167
+ const google = (window as any).google;
168
+
169
+ // Setup ads rendering settings
170
+ const adsRenderingSettings = new google.ima.AdsRenderingSettings();
171
+ adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;
172
+ adsRenderingSettings.enablePreloading = true;
173
+
174
+ // Get the ads manager
175
+ this.adsManager = event.getAdsManager(this.video, adsRenderingSettings);
176
+
177
+ // Setup ads manager event listeners
178
+ this.setupAdsManagerListeners();
179
+
180
+ try {
181
+ // Initialize ads manager
182
+ this.adsManager.init(
183
+ this.video.clientWidth,
184
+ this.video.clientHeight,
185
+ google.ima.ViewMode.NORMAL
186
+ );
187
+
188
+ // Start ads
189
+ this.adsManager.start();
190
+ } catch (error) {
191
+ console.error('Error starting ads:', error);
192
+ this.video.play().catch(() => {});
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Setup ads manager event listeners
198
+ */
199
+ private setupAdsManagerListeners(): void {
200
+ const google = (window as any).google;
201
+
202
+ // Content pause - ad is about to play
203
+ this.adsManager.addEventListener(
204
+ google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
205
+ () => {
206
+ console.log('Ad: Content paused');
207
+ this.isAdPlaying = true;
208
+ this.video.pause();
209
+ this.config.onAdStart?.();
210
+ }
211
+ );
212
+
213
+ // Content resume - ad finished
214
+ this.adsManager.addEventListener(
215
+ google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
216
+ () => {
217
+ console.log('Ad: Content resume');
218
+ this.isAdPlaying = false;
219
+ this.config.onAdEnd?.();
220
+ this.video.play().catch(() => {});
221
+ }
222
+ );
223
+
224
+ // Ad started
225
+ this.adsManager.addEventListener(
226
+ google.ima.AdEvent.Type.STARTED,
227
+ (event: any) => {
228
+ const ad = event.getAd();
229
+ console.log('Ad started:', {
230
+ type: ad.isLinear() ? 'Linear (video)' : 'Non-linear (overlay)',
231
+ duration: ad.getDuration(),
232
+ skippable: ad.getSkipTimeOffset() !== -1,
233
+ title: ad.getTitle(),
234
+ });
235
+ }
236
+ );
237
+
238
+ // Ad completed
239
+ this.adsManager.addEventListener(
240
+ google.ima.AdEvent.Type.COMPLETE,
241
+ () => {
242
+ console.log('Ad completed');
243
+ }
244
+ );
245
+
246
+ // All ads completed
247
+ this.adsManager.addEventListener(
248
+ google.ima.AdEvent.Type.ALL_ADS_COMPLETED,
249
+ () => {
250
+ console.log('All ads completed');
251
+ this.config.onAllAdsComplete?.();
252
+ }
253
+ );
254
+
255
+ // Ad error
256
+ this.adsManager.addEventListener(
257
+ google.ima.AdErrorEvent.Type.AD_ERROR,
258
+ (event: any) => this.onAdError(event)
259
+ );
260
+
261
+ // Ad skipped
262
+ this.adsManager.addEventListener(
263
+ google.ima.AdEvent.Type.SKIPPED,
264
+ () => {
265
+ console.log('Ad skipped by user');
266
+ }
267
+ );
268
+ }
269
+
270
+ /**
271
+ * Handle ad error
272
+ */
273
+ private onAdError(event: any): void {
274
+ const error = event.getError?.();
275
+ console.error('Ad error:', error?.getMessage?.() || error);
276
+
277
+ this.config.onAdError?.(error);
278
+
279
+ // Destroy ads manager on error
280
+ if (this.adsManager) {
281
+ this.adsManager.destroy();
282
+ }
283
+
284
+ // Resume content playback
285
+ this.isAdPlaying = false;
286
+ this.video.play().catch(() => {});
287
+ }
288
+
289
+ /**
290
+ * Pause ad
291
+ */
292
+ pause(): void {
293
+ if (this.adsManager && this.isAdPlaying) {
294
+ this.adsManager.pause();
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Resume ad
300
+ */
301
+ resume(): void {
302
+ if (this.adsManager && this.isAdPlaying) {
303
+ this.adsManager.resume();
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Skip ad (if skippable)
309
+ */
310
+ skip(): void {
311
+ if (this.adsManager) {
312
+ this.adsManager.skip();
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Resize ads
318
+ */
319
+ resize(width: number, height: number): void {
320
+ const google = (window as any).google;
321
+ if (this.adsManager) {
322
+ this.adsManager.resize(width, height, google.ima.ViewMode.NORMAL);
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Set volume
328
+ */
329
+ setVolume(volume: number): void {
330
+ if (this.adsManager) {
331
+ this.adsManager.setVolume(volume);
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Check if ad is currently playing
337
+ */
338
+ isPlayingAd(): boolean {
339
+ return this.isAdPlaying;
340
+ }
341
+
342
+ /**
343
+ * Cleanup
344
+ */
345
+ destroy(): void {
346
+ if (this.adsManager) {
347
+ this.adsManager.destroy();
348
+ this.adsManager = null;
349
+ }
350
+
351
+ if (this.adsLoader) {
352
+ this.adsLoader.destroy();
353
+ this.adsLoader = null;
354
+ }
355
+
356
+ this.isAdPlaying = false;
357
+ }
358
+ }
@@ -14,8 +14,5 @@ export { SecureVideoPlayer } from './SecureVideoPlayer';
14
14
  // Export EPG (Electronic Program Guide) components
15
15
  export * from './react/EPG';
16
16
 
17
- // Export Ads module (Google Ads Integration)
18
- export * from './ads/index';
19
-
20
17
  // Version
21
18
  export const VERSION = '1.0.0';