unified-video-framework 1.4.215 → 1.4.216
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/CHANGELOG.md +94 -0
- package/package.json +1 -1
- package/packages/core/dist/interfaces.d.ts +34 -2
- package/packages/core/dist/interfaces.d.ts.map +1 -1
- package/packages/core/src/interfaces.ts +51 -3
- package/packages/web/dist/ads/AdsManager.d.ts +65 -0
- package/packages/web/dist/ads/AdsManager.d.ts.map +1 -0
- package/packages/web/dist/ads/AdsManager.js +495 -0
- package/packages/web/dist/ads/AdsManager.js.map +1 -0
- package/packages/web/dist/ads/index.d.ts +4 -0
- package/packages/web/dist/ads/index.d.ts.map +1 -0
- package/packages/web/dist/ads/index.js +3 -0
- package/packages/web/dist/ads/index.js.map +1 -0
- package/packages/web/dist/ads/types.d.ts +339 -0
- package/packages/web/dist/ads/types.d.ts.map +1 -0
- package/packages/web/dist/ads/types.js +55 -0
- package/packages/web/dist/ads/types.js.map +1 -0
- package/packages/web/dist/index.d.ts +1 -0
- package/packages/web/dist/index.d.ts.map +1 -1
- package/packages/web/dist/index.js +1 -0
- package/packages/web/dist/index.js.map +1 -1
- package/packages/web/src/ads/AdsManager.ts +691 -0
- package/packages/web/src/ads/README.md +403 -0
- package/packages/web/src/ads/index.ts +17 -0
- package/packages/web/src/ads/types.ts +442 -0
- package/packages/web/src/index.ts +3 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# Google Ads Integration for Unified Video Framework
|
|
2
|
+
|
|
3
|
+
Comprehensive ads support with Google IMA SDK integration and custom ad formats.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### Google Standard Ads
|
|
8
|
+
- ✅ Skippable In-Stream (TrueView)
|
|
9
|
+
- ✅ Non-Skippable In-Stream
|
|
10
|
+
- ✅ Bumper Ads (6-second)
|
|
11
|
+
- ✅ Responsive Display Ads
|
|
12
|
+
- ✅ Masthead Ads
|
|
13
|
+
|
|
14
|
+
### Custom Ad Formats
|
|
15
|
+
- ✅ Pause Overlay Ads (YouTube-style split-screen)
|
|
16
|
+
- ✅ Overlay Banner Ads
|
|
17
|
+
- ✅ Interactive Ads (hotspots, CTA buttons)
|
|
18
|
+
|
|
19
|
+
### Ad Placements
|
|
20
|
+
- ✅ Preroll (before content)
|
|
21
|
+
- ✅ Midroll (during content at specified times)
|
|
22
|
+
- ✅ Postroll (after content)
|
|
23
|
+
- ✅ Pause Ads (when user pauses)
|
|
24
|
+
- ✅ Overlay Ads (non-intrusive banners)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
The ads module is included in the `@unified-video-framework/web` package.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install unified-video-framework
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Basic Setup with Google IMA
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { AdsManager } from 'unified-video-framework/web';
|
|
40
|
+
|
|
41
|
+
// Create ad container in your HTML
|
|
42
|
+
<div id="player-container">
|
|
43
|
+
<div id="ad-container"></div>
|
|
44
|
+
<video id="main-video" controls></video>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
// Initialize ads
|
|
48
|
+
const adsManager = new AdsManager({
|
|
49
|
+
adsEnabled: true,
|
|
50
|
+
adContainer: '#ad-container',
|
|
51
|
+
videoElement: '#main-video',
|
|
52
|
+
preroll: true,
|
|
53
|
+
postroll: true,
|
|
54
|
+
debug: true,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Listen to ad events
|
|
58
|
+
adsManager.on('adStarted', (event) => {
|
|
59
|
+
console.log('Ad started:', event.ad.metadata.title);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
adsManager.on('adCompleted', (event) => {
|
|
63
|
+
console.log('Ad completed:', event.ad.metadata.title);
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### With Backend API Integration
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const adsManager = new AdsManager({
|
|
71
|
+
adsEnabled: true,
|
|
72
|
+
adContainer: '#ad-container',
|
|
73
|
+
videoElement: '#main-video',
|
|
74
|
+
|
|
75
|
+
// Backend API for ad configuration
|
|
76
|
+
apiEndpoint: 'https://your-backend.com/api/ads',
|
|
77
|
+
|
|
78
|
+
// Ad breaks
|
|
79
|
+
preroll: true,
|
|
80
|
+
midroll: {
|
|
81
|
+
enabled: true,
|
|
82
|
+
interval: 300, // Every 5 minutes
|
|
83
|
+
},
|
|
84
|
+
postroll: true,
|
|
85
|
+
|
|
86
|
+
// Privacy
|
|
87
|
+
gdprConsent: true,
|
|
88
|
+
coppa: false,
|
|
89
|
+
|
|
90
|
+
// Callbacks
|
|
91
|
+
onAdStarted: (ad) => {
|
|
92
|
+
console.log('Ad started:', ad.metadata.title);
|
|
93
|
+
},
|
|
94
|
+
onAdError: (error) => {
|
|
95
|
+
console.error('Ad error:', error.message);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Using VAST/VMAP URLs
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
const adsManager = new AdsManager({
|
|
104
|
+
adsEnabled: true,
|
|
105
|
+
adContainer: '#ad-container',
|
|
106
|
+
videoElement: '#main-video',
|
|
107
|
+
|
|
108
|
+
// Direct VAST URL for preroll
|
|
109
|
+
preroll: {
|
|
110
|
+
id: 'preroll-1',
|
|
111
|
+
type: 'preroll',
|
|
112
|
+
position: 'start',
|
|
113
|
+
ads: [{
|
|
114
|
+
id: 'ad-1',
|
|
115
|
+
type: 'SKIPPABLE_IN_STREAM',
|
|
116
|
+
vastUrl: 'https://pubads.g.doubleclick.net/gampad/ads?...',
|
|
117
|
+
metadata: {
|
|
118
|
+
id: 'ad-1',
|
|
119
|
+
title: 'Advertisement',
|
|
120
|
+
duration: 30,
|
|
121
|
+
skippable: true,
|
|
122
|
+
skipOffset: 5,
|
|
123
|
+
},
|
|
124
|
+
}],
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Custom Pause Ads
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const adsManager = new AdsManager({
|
|
133
|
+
adsEnabled: true,
|
|
134
|
+
adContainer: '#ad-container',
|
|
135
|
+
videoElement: '#main-video',
|
|
136
|
+
|
|
137
|
+
// Pause overlay ads (YouTube-style)
|
|
138
|
+
pauseAds: {
|
|
139
|
+
type: 'PAUSE_OVERLAY',
|
|
140
|
+
layout: {
|
|
141
|
+
type: 'split_screen',
|
|
142
|
+
contentSide: 'left',
|
|
143
|
+
adSide: 'right',
|
|
144
|
+
splitRatio: '60:40',
|
|
145
|
+
},
|
|
146
|
+
closeButton: {
|
|
147
|
+
enabled: true,
|
|
148
|
+
position: 'top-right',
|
|
149
|
+
style: '×',
|
|
150
|
+
delay: 0,
|
|
151
|
+
},
|
|
152
|
+
resumeButton: {
|
|
153
|
+
enabled: true,
|
|
154
|
+
text: 'Resume Video',
|
|
155
|
+
position: 'center',
|
|
156
|
+
},
|
|
157
|
+
triggers: {
|
|
158
|
+
minPauseDuration: 3, // Show after 3 seconds of pause
|
|
159
|
+
maxDisplayTime: 30, // Hide after 30 seconds
|
|
160
|
+
frequency: 'once_per_session',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Overlay Ads
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const adsManager = new AdsManager({
|
|
170
|
+
adsEnabled: true,
|
|
171
|
+
adContainer: '#ad-container',
|
|
172
|
+
videoElement: '#main-video',
|
|
173
|
+
|
|
174
|
+
overlayAds: {
|
|
175
|
+
type: 'OVERLAY_AD',
|
|
176
|
+
positions: ['bottom', 'top-right'],
|
|
177
|
+
sizes: ['20%', '25%', '30%'],
|
|
178
|
+
closeButton: {
|
|
179
|
+
enabled: true,
|
|
180
|
+
position: 'top-right',
|
|
181
|
+
style: '×',
|
|
182
|
+
delay: 5,
|
|
183
|
+
},
|
|
184
|
+
animation: {
|
|
185
|
+
entrance: 'slideUp',
|
|
186
|
+
exit: 'fadeOut',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Event Handling
|
|
193
|
+
|
|
194
|
+
### Available Events
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// Ad Break Events
|
|
198
|
+
adsManager.on('adBreakReady', (event) => {
|
|
199
|
+
console.log('Ad break ready:', event.adBreak);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
adsManager.on('adBreakStarted', (event) => {
|
|
203
|
+
console.log('Ad break started:', event.adBreak);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
adsManager.on('adBreakCompleted', (event) => {
|
|
207
|
+
console.log('Ad break completed:', event.adBreak);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Individual Ad Events
|
|
211
|
+
adsManager.on('loaded', (event) => {
|
|
212
|
+
console.log('Ad loaded:', event.ad);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
adsManager.on('started', (event) => {
|
|
216
|
+
console.log('Ad started:', event.ad);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
adsManager.on('firstQuartile', (event) => {
|
|
220
|
+
console.log('Ad 25% complete');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
adsManager.on('midpoint', (event) => {
|
|
224
|
+
console.log('Ad 50% complete');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
adsManager.on('thirdQuartile', (event) => {
|
|
228
|
+
console.log('Ad 75% complete');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
adsManager.on('completed', (event) => {
|
|
232
|
+
console.log('Ad completed:', event.ad);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
adsManager.on('skipped', (event) => {
|
|
236
|
+
console.log('Ad skipped:', event.ad);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
adsManager.on('clicked', (event) => {
|
|
240
|
+
console.log('Ad clicked:', event.ad);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// Error Events
|
|
244
|
+
adsManager.on('adError', (event) => {
|
|
245
|
+
console.error('Ad error:', event.customData);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// All Ads Complete
|
|
249
|
+
adsManager.on('allAdsCompleted', () => {
|
|
250
|
+
console.log('All ads completed');
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Backend API Integration
|
|
255
|
+
|
|
256
|
+
### GET /api/ads/config
|
|
257
|
+
|
|
258
|
+
Request ad configuration from your backend:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Query Parameters
|
|
262
|
+
{
|
|
263
|
+
contentId: 'video_123',
|
|
264
|
+
userId: 'user_456',
|
|
265
|
+
sessionId: 'session_abc',
|
|
266
|
+
placement: 'preroll|midroll|postroll|pause|overlay',
|
|
267
|
+
position: 300, // for midroll, time in seconds
|
|
268
|
+
width: 1920,
|
|
269
|
+
height: 1080,
|
|
270
|
+
deviceType: 'desktop|mobile|tablet|tv',
|
|
271
|
+
browser: 'Chrome/91.0',
|
|
272
|
+
language: 'en-US',
|
|
273
|
+
referrer: 'https://example.com',
|
|
274
|
+
gdprConsent: true,
|
|
275
|
+
coppa: false,
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Response format:
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"status": "success",
|
|
284
|
+
"data": {
|
|
285
|
+
"adBreaks": [
|
|
286
|
+
{
|
|
287
|
+
"id": "preroll-1",
|
|
288
|
+
"type": "preroll",
|
|
289
|
+
"position": "start",
|
|
290
|
+
"ads": [
|
|
291
|
+
{
|
|
292
|
+
"id": "ad-123",
|
|
293
|
+
"type": "SKIPPABLE_IN_STREAM",
|
|
294
|
+
"vastUrl": "https://...",
|
|
295
|
+
"metadata": {
|
|
296
|
+
"id": "ad-123",
|
|
297
|
+
"title": "Advertisement",
|
|
298
|
+
"duration": 30,
|
|
299
|
+
"skippable": true,
|
|
300
|
+
"skipOffset": 5
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
],
|
|
306
|
+
"companionAds": [],
|
|
307
|
+
"settings": {
|
|
308
|
+
"maxAdsPerBreak": 3,
|
|
309
|
+
"maxTotalAds": 10
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### POST /api/ads/track/event
|
|
316
|
+
|
|
317
|
+
Track ad events to your backend:
|
|
318
|
+
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"eventType": "started|firstQuartile|midpoint|thirdQuartile|completed|skipped|clicked",
|
|
322
|
+
"adId": "ad-123",
|
|
323
|
+
"sessionId": "session_abc",
|
|
324
|
+
"contentId": "video_123",
|
|
325
|
+
"userId": "user_456",
|
|
326
|
+
"timestamp": "2024-12-19T10:30:00Z",
|
|
327
|
+
"playerTime": 45.5,
|
|
328
|
+
"customData": {}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Advanced Usage
|
|
333
|
+
|
|
334
|
+
### Manual Ad Control
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
// Request specific ad breaks manually
|
|
338
|
+
adsManager.requestPrerollAds();
|
|
339
|
+
adsManager.requestMidrollAds(300); // at 5 minutes
|
|
340
|
+
adsManager.requestPostrollAds();
|
|
341
|
+
|
|
342
|
+
// Control ad playback
|
|
343
|
+
adsManager.pause();
|
|
344
|
+
adsManager.resume();
|
|
345
|
+
adsManager.skip();
|
|
346
|
+
|
|
347
|
+
// Resize ads (e.g., on window resize)
|
|
348
|
+
adsManager.resize(1920, 1080);
|
|
349
|
+
|
|
350
|
+
// Clean up
|
|
351
|
+
adsManager.destroy();
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### TypeScript Types
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import type {
|
|
358
|
+
AdsManagerConfig,
|
|
359
|
+
Ad,
|
|
360
|
+
AdBreak,
|
|
361
|
+
AdEvent,
|
|
362
|
+
AdError,
|
|
363
|
+
AdType,
|
|
364
|
+
AdPlacement,
|
|
365
|
+
AdEventType,
|
|
366
|
+
} from 'unified-video-framework/web';
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Browser Support
|
|
370
|
+
|
|
371
|
+
- Chrome 90+
|
|
372
|
+
- Firefox 88+
|
|
373
|
+
- Safari 14+
|
|
374
|
+
- Edge 90+
|
|
375
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
376
|
+
|
|
377
|
+
## Google IMA SDK
|
|
378
|
+
|
|
379
|
+
The ads manager automatically loads the Google IMA SDK v3. No manual script inclusion needed.
|
|
380
|
+
|
|
381
|
+
- SDK URL: `https://imasdk.googleapis.com/js/sdkloader/ima3.js`
|
|
382
|
+
- Documentation: https://developers.google.com/interactive-media-ads
|
|
383
|
+
|
|
384
|
+
## Best Practices
|
|
385
|
+
|
|
386
|
+
1. **Always provide fallbacks**: Handle ad errors gracefully
|
|
387
|
+
2. **Respect user privacy**: Implement GDPR/COPPA compliance
|
|
388
|
+
3. **Track events**: Monitor ad performance with backend tracking
|
|
389
|
+
4. **Optimize for mobile**: Test on mobile devices for UX
|
|
390
|
+
5. **Test thoroughly**: Use IMA Video Suite for testing: https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vastinspector
|
|
391
|
+
|
|
392
|
+
## Examples
|
|
393
|
+
|
|
394
|
+
See the `/examples` directory for complete implementation examples:
|
|
395
|
+
- Basic Google IMA ads
|
|
396
|
+
- Backend API integration
|
|
397
|
+
- Pause overlay ads
|
|
398
|
+
- Interactive ads
|
|
399
|
+
- React integration
|
|
400
|
+
|
|
401
|
+
## License
|
|
402
|
+
|
|
403
|
+
MIT License - Flicknexs Team
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ads Module - Google Ads Integration for Unified Video Framework
|
|
3
|
+
* Author: Flicknexs Team
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export * from './types';
|
|
7
|
+
export { AdsManager } from './AdsManager';
|
|
8
|
+
|
|
9
|
+
// Re-export commonly used types for convenience
|
|
10
|
+
export type {
|
|
11
|
+
AdsManagerConfig,
|
|
12
|
+
Ad,
|
|
13
|
+
AdBreak,
|
|
14
|
+
AdEvent,
|
|
15
|
+
AdError,
|
|
16
|
+
AdMetadata,
|
|
17
|
+
} from './types';
|