unified-video-framework 1.4.412 → 1.4.413

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 (87) hide show
  1. package/package.json +1 -1
  2. package/packages/core/dist/interfaces/IVideoPlayer.d.ts +0 -22
  3. package/packages/core/dist/interfaces/IVideoPlayer.d.ts.map +1 -1
  4. package/packages/core/src/interfaces/IVideoPlayer.ts +0 -27
  5. package/packages/web/dist/WebPlayer.d.ts +0 -4
  6. package/packages/web/dist/WebPlayer.d.ts.map +1 -1
  7. package/packages/web/dist/WebPlayer.js +62 -73
  8. package/packages/web/dist/WebPlayer.js.map +1 -1
  9. package/packages/web/dist/drm/DRMManager.d.ts +16 -9
  10. package/packages/web/dist/drm/DRMManager.d.ts.map +1 -1
  11. package/packages/web/dist/drm/DRMManager.js +109 -42
  12. package/packages/web/dist/drm/DRMManager.js.map +1 -1
  13. package/packages/web/dist/drm/index.d.ts +15 -0
  14. package/packages/web/dist/drm/index.d.ts.map +1 -0
  15. package/packages/web/dist/drm/index.js +13 -0
  16. package/packages/web/dist/drm/index.js.map +1 -0
  17. package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts +19 -0
  18. package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts.map +1 -0
  19. package/packages/web/dist/drm/providers/BunnyNetProvider.js +112 -0
  20. package/packages/web/dist/drm/providers/BunnyNetProvider.js.map +1 -0
  21. package/packages/web/dist/drm/providers/GenericProvider.d.ts +30 -0
  22. package/packages/web/dist/drm/providers/GenericProvider.d.ts.map +1 -0
  23. package/packages/web/dist/drm/providers/GenericProvider.js +102 -0
  24. package/packages/web/dist/drm/providers/GenericProvider.js.map +1 -0
  25. package/packages/web/dist/drm/systems/BaseDRM.d.ts +18 -0
  26. package/packages/web/dist/drm/systems/BaseDRM.d.ts.map +1 -0
  27. package/packages/web/dist/drm/systems/BaseDRM.js +29 -0
  28. package/packages/web/dist/drm/systems/BaseDRM.js.map +1 -0
  29. package/packages/web/dist/drm/systems/FairPlayDRM.d.ts +32 -0
  30. package/packages/web/dist/drm/systems/FairPlayDRM.d.ts.map +1 -0
  31. package/packages/web/dist/drm/systems/FairPlayDRM.js +198 -0
  32. package/packages/web/dist/drm/systems/FairPlayDRM.js.map +1 -0
  33. package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts +9 -0
  34. package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts.map +1 -0
  35. package/packages/web/dist/drm/systems/PlayReadyDRM.js +92 -0
  36. package/packages/web/dist/drm/systems/PlayReadyDRM.js.map +1 -0
  37. package/packages/web/dist/drm/systems/WidevineDRM.d.ts +9 -0
  38. package/packages/web/dist/drm/systems/WidevineDRM.d.ts.map +1 -0
  39. package/packages/web/dist/drm/systems/WidevineDRM.js +73 -0
  40. package/packages/web/dist/drm/systems/WidevineDRM.js.map +1 -0
  41. package/packages/web/dist/drm/types/BunnyNetTypes.d.ts +20 -0
  42. package/packages/web/dist/drm/types/BunnyNetTypes.d.ts.map +1 -0
  43. package/packages/web/dist/drm/types/BunnyNetTypes.js +8 -0
  44. package/packages/web/dist/drm/types/BunnyNetTypes.js.map +1 -0
  45. package/packages/web/dist/drm/types/DRMTypes.d.ts +56 -49
  46. package/packages/web/dist/drm/types/DRMTypes.d.ts.map +1 -1
  47. package/packages/web/dist/drm/types/DRMTypes.js +19 -13
  48. package/packages/web/dist/drm/types/DRMTypes.js.map +1 -1
  49. package/packages/web/dist/drm/utils/BrowserDetector.d.ts +20 -0
  50. package/packages/web/dist/drm/utils/BrowserDetector.d.ts.map +1 -0
  51. package/packages/web/dist/drm/utils/BrowserDetector.js +168 -0
  52. package/packages/web/dist/drm/utils/BrowserDetector.js.map +1 -0
  53. package/packages/web/dist/drm/utils/CertificateManager.d.ts +15 -0
  54. package/packages/web/dist/drm/utils/CertificateManager.d.ts.map +1 -0
  55. package/packages/web/dist/drm/utils/CertificateManager.js +46 -0
  56. package/packages/web/dist/drm/utils/CertificateManager.js.map +1 -0
  57. package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts +7 -0
  58. package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts.map +1 -0
  59. package/packages/web/dist/drm/utils/DRMErrorHandler.js +49 -0
  60. package/packages/web/dist/drm/utils/DRMErrorHandler.js.map +1 -0
  61. package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts +15 -0
  62. package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts.map +1 -0
  63. package/packages/web/dist/drm/utils/LicenseRequestHandler.js +110 -0
  64. package/packages/web/dist/drm/utils/LicenseRequestHandler.js.map +1 -0
  65. package/packages/web/dist/react/WebPlayerView.d.ts +1 -18
  66. package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
  67. package/packages/web/dist/react/WebPlayerView.js +0 -5
  68. package/packages/web/dist/react/WebPlayerView.js.map +1 -1
  69. package/packages/web/src/WebPlayer.ts +79 -106
  70. package/packages/web/src/drm/DRMManager.ts +172 -58
  71. package/packages/web/src/drm/index.ts +37 -0
  72. package/packages/web/src/drm/providers/BunnyNetProvider.ts +170 -0
  73. package/packages/web/src/drm/providers/GenericProvider.ts +148 -0
  74. package/packages/web/src/drm/systems/BaseDRM.ts +68 -0
  75. package/packages/web/src/drm/systems/FairPlayDRM.ts +305 -0
  76. package/packages/web/src/drm/systems/PlayReadyDRM.ts +131 -0
  77. package/packages/web/src/drm/systems/WidevineDRM.ts +105 -0
  78. package/packages/web/src/drm/types/BunnyNetTypes.ts +35 -0
  79. package/packages/web/src/drm/types/DRMTypes.ts +70 -76
  80. package/packages/web/src/drm/utils/BrowserDetector.ts +232 -0
  81. package/packages/web/src/drm/utils/CertificateManager.ts +86 -0
  82. package/packages/web/src/drm/utils/DRMErrorHandler.ts +84 -0
  83. package/packages/web/src/drm/utils/LicenseRequestHandler.ts +180 -0
  84. package/packages/web/src/react/WebPlayerView.tsx +1 -28
  85. package/packages/web/src/drm/BunnyCDNDRMProvider.ts +0 -104
  86. package/packages/web/src/drm/FairPlayDRMHandler.ts +0 -322
  87. package/packages/web/src/drm/WidevineDRMHandler.ts +0 -246
@@ -1,97 +1,91 @@
1
1
  /**
2
- * DRM Types and Interfaces
3
- * Core types for the web DRM system supporting Bunny CDN and generic DRM providers
2
+ * DRM Type Definitions
3
+ * Core type definitions and enums for DRM functionality
4
4
  */
5
5
 
6
- // Token provider interface - allows flexible token injection strategies
7
- export interface DRMTokenProvider {
8
- // Get token for manifest/playlist requests
9
- getManifestToken(): Promise<DRMToken | null>;
6
+ import { DRMConfig, DRMType } from '@unified-video/core';
10
7
 
11
- // Get token for media segment requests
12
- getSegmentToken(): Promise<DRMToken | null>;
8
+ // Extended DRM configuration for internal use
9
+ export interface ExtendedDRMConfig extends DRMConfig {
10
+ // Provider-specific settings
11
+ provider?: 'bunny' | 'generic' | string;
13
12
 
14
- // Get token for license server requests
15
- getLicenseToken(): Promise<DRMToken | null>;
13
+ // Library/Video IDs for Bunny.net
14
+ libraryId?: string;
15
+ videoId?: string;
16
16
 
17
- // Check if token needs renewal
18
- shouldRenewToken(token: DRMToken): boolean;
17
+ // Advanced options
18
+ retryConfig?: {
19
+ maxRetries: number;
20
+ retryDelay: number;
21
+ };
19
22
 
20
- // Refresh/renew token
21
- renewToken(token: DRMToken): Promise<DRMToken>;
23
+ // Debugging
24
+ debug?: boolean;
22
25
  }
23
26
 
24
- // Token structure
25
- export interface DRMToken {
26
- token: string; // The actual token value
27
- expires: number; // Unix timestamp (seconds)
28
- tokenVer?: string; // Optional token version
27
+ // Browser DRM capabilities
28
+ export interface DRMCapabilities {
29
+ widevine: boolean;
30
+ fairplay: boolean;
31
+ playready: boolean;
32
+ supportedType: DRMType | null;
29
33
  }
30
34
 
31
- // Bunny CDN specific configuration
32
- export interface BunnyCDNDRMConfig {
33
- libraryId: string; // Bunny CDN library ID
34
- videoId: string; // Video ID on Bunny CDN
35
- pullZoneUrl: string; // e.g., "stream.example.com"
36
- tokenProvider: DRMTokenProvider; // Token provider implementation
37
- certificateUrl?: string; // Override default FairPlay certificate URL
38
- licenseUrl?: string; // Override default license URL
39
- enableReferrerProtection?: boolean; // Enable referrer header validation
35
+ // License request/response types
36
+ export interface LicenseRequest {
37
+ url: string;
38
+ method: 'POST' | 'GET';
39
+ headers: Record<string, string>;
40
+ body: ArrayBuffer | string;
41
+ responseType: 'arraybuffer' | 'text' | 'json';
40
42
  }
41
43
 
42
- // Generic DRM configuration (for non-Bunny providers)
43
- export interface GenericDRMConfig {
44
- type: 'widevine' | 'fairplay';
45
- licenseUrl: string;
46
- certificateUrl?: string; // Required for FairPlay
47
- headers?: Record<string, string>; // Custom headers for license requests
48
- certificateHeaders?: Record<string, string>; // Custom headers for certificate requests
44
+ export interface LicenseResponse {
45
+ license: ArrayBuffer;
46
+ metadata?: any;
49
47
  }
50
48
 
51
- // Unified DRM configuration
52
- export interface WebDRMConfig {
53
- // Provider type
54
- provider: 'bunny' | 'generic';
55
-
56
- // Provider-specific config
57
- bunny?: BunnyCDNDRMConfig;
58
- generic?: GenericDRMConfig;
49
+ // EME event types
50
+ export interface EMEMessageEvent {
51
+ messageType: string;
52
+ message: ArrayBuffer;
59
53
  }
60
54
 
61
- // DRM Handler interface (implemented by Widevine and FairPlay handlers)
62
- export interface IDRMHandler {
63
- // Initialize DRM system
64
- initialize(): Promise<void>;
65
-
66
- // Setup DRM for video element
67
- setupDRM(videoElement: HTMLVideoElement, manifestUrl: string): Promise<void>;
68
-
69
- // Handle license requests
70
- onLicenseRequest(licenseRequest: ArrayBuffer): Promise<ArrayBuffer>;
71
-
72
- // Cleanup resources
73
- destroy(): void;
74
-
75
- // Check if DRM is supported in current browser
76
- isSupported(): boolean;
55
+ // DRM initialization result
56
+ export interface DRMInitResult {
57
+ success: boolean;
58
+ drmType: DRMType;
59
+ keySystem: string;
60
+ error?: DRMError;
77
61
  }
78
62
 
79
- // EME key system identifiers
80
- export const DRM_KEY_SYSTEMS = {
81
- WIDEVINE: 'com.widevine.alpha',
82
- FAIRPLAY: 'com.apple.fps.1_0',
83
- PLAYREADY: 'com.microsoft.playready',
84
- CLEARKEY: 'org.w3.clearkey'
85
- } as const;
63
+ // DRM-specific errors
64
+ export interface DRMError {
65
+ code: DRMErrorCode;
66
+ message: string;
67
+ fatal: boolean;
68
+ details?: any;
69
+ systemError?: any;
70
+ }
86
71
 
87
- // Error types
88
- export class DRMError extends Error {
89
- constructor(
90
- message: string,
91
- public code: string,
92
- public details?: any
93
- ) {
94
- super(message);
95
- this.name = 'DRMError';
96
- }
72
+ export enum DRMErrorCode {
73
+ UNSUPPORTED_BROWSER = 'DRM_UNSUPPORTED_BROWSER',
74
+ CERTIFICATE_LOAD_FAILED = 'DRM_CERTIFICATE_LOAD_FAILED',
75
+ LICENSE_REQUEST_FAILED = 'DRM_LICENSE_REQUEST_FAILED',
76
+ KEY_SYSTEM_ACCESS_DENIED = 'DRM_KEY_SYSTEM_ACCESS_DENIED',
77
+ MEDIA_KEYS_CREATION_FAILED = 'DRM_MEDIA_KEYS_CREATION_FAILED',
78
+ SESSION_CREATION_FAILED = 'DRM_SESSION_CREATION_FAILED',
79
+ LICENSE_INVALID = 'DRM_LICENSE_INVALID',
80
+ CONFIGURATION_ERROR = 'DRM_CONFIGURATION_ERROR',
81
+ NETWORK_ERROR = 'DRM_NETWORK_ERROR',
82
+ TIMEOUT = 'DRM_TIMEOUT',
97
83
  }
84
+
85
+ // Key system mappings
86
+ export const KEY_SYSTEMS: Record<DRMType, string[]> = {
87
+ [DRMType.WIDEVINE]: ['com.widevine.alpha'],
88
+ [DRMType.PLAYREADY]: ['com.microsoft.playready', 'com.microsoft.playready.recommendation'],
89
+ [DRMType.FAIRPLAY]: ['com.apple.fps.1_0', 'com.apple.fps'],
90
+ [DRMType.CLEARKEY]: ['webkit-org.w3.clearkey', 'org.w3.clearkey'],
91
+ };
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Browser DRM Detector
3
+ * Detects browser capabilities and determines optimal DRM system
4
+ */
5
+
6
+ import { DRMType } from '@unified-video/core';
7
+ import { DRMCapabilities, KEY_SYSTEMS } from '../types/DRMTypes';
8
+
9
+ export class BrowserDetector {
10
+ private static instance: BrowserDetector;
11
+ private capabilities: DRMCapabilities | null = null;
12
+
13
+ private constructor() {}
14
+
15
+ static getInstance(): BrowserDetector {
16
+ if (!BrowserDetector.instance) {
17
+ BrowserDetector.instance = new BrowserDetector();
18
+ }
19
+ return BrowserDetector.instance;
20
+ }
21
+
22
+ /**
23
+ * Detect DRM capabilities of current browser
24
+ */
25
+ async detectCapabilities(): Promise<DRMCapabilities> {
26
+ if (this.capabilities) {
27
+ return this.capabilities;
28
+ }
29
+
30
+ const capabilities: DRMCapabilities = {
31
+ widevine: false,
32
+ fairplay: false,
33
+ playready: false,
34
+ supportedType: null,
35
+ };
36
+
37
+ // Check for FairPlay (Safari/iOS) - highest priority on Apple devices
38
+ if (this.isSafari() || this.isWebKitBased()) {
39
+ capabilities.fairplay = await this.checkFairPlaySupport();
40
+ if (capabilities.fairplay) {
41
+ capabilities.supportedType = DRMType.FAIRPLAY;
42
+ }
43
+ }
44
+
45
+ // Check for Widevine (Chrome, Firefox, Edge)
46
+ if (!capabilities.supportedType) {
47
+ capabilities.widevine = await this.checkWidevineSupport();
48
+ if (capabilities.widevine) {
49
+ capabilities.supportedType = DRMType.WIDEVINE;
50
+ }
51
+ }
52
+
53
+ // Check for PlayReady (Edge, IE)
54
+ if (!capabilities.supportedType && this.isEdge()) {
55
+ capabilities.playready = await this.checkPlayReadySupport();
56
+ if (capabilities.playready) {
57
+ capabilities.supportedType = DRMType.PLAYREADY;
58
+ }
59
+ }
60
+
61
+ this.capabilities = capabilities;
62
+ return capabilities;
63
+ }
64
+
65
+ /**
66
+ * Get recommended DRM type for current browser
67
+ */
68
+ async getRecommendedDRMType(): Promise<DRMType | null> {
69
+ const caps = await this.detectCapabilities();
70
+ return caps.supportedType;
71
+ }
72
+
73
+ /**
74
+ * Check if specific DRM type is supported
75
+ */
76
+ async isDRMTypeSupported(drmType: DRMType): Promise<boolean> {
77
+ const caps = await this.detectCapabilities();
78
+ switch (drmType) {
79
+ case DRMType.WIDEVINE:
80
+ return caps.widevine;
81
+ case DRMType.FAIRPLAY:
82
+ return caps.fairplay;
83
+ case DRMType.PLAYREADY:
84
+ return caps.playready;
85
+ default:
86
+ return false;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Check if browser is Safari
92
+ */
93
+ private isSafari(): boolean {
94
+ const ua = navigator.userAgent.toLowerCase();
95
+ return ua.includes('safari') && !ua.includes('chrome') && !ua.includes('chromium');
96
+ }
97
+
98
+ /**
99
+ * Check if browser is WebKit-based
100
+ */
101
+ private isWebKitBased(): boolean {
102
+ return 'WebKitMediaKeys' in window;
103
+ }
104
+
105
+ /**
106
+ * Check if browser is Edge
107
+ */
108
+ private isEdge(): boolean {
109
+ const ua = navigator.userAgent.toLowerCase();
110
+ return ua.includes('edg/');
111
+ }
112
+
113
+ /**
114
+ * Check FairPlay support
115
+ */
116
+ private async checkFairPlaySupport(): Promise<boolean> {
117
+ try {
118
+ // Check for WebKit-specific FairPlay API
119
+ if ('WebKitMediaKeys' in window) {
120
+ return true;
121
+ }
122
+
123
+ // Check via EME API
124
+ if (navigator.requestMediaKeySystemAccess) {
125
+ const config: MediaKeySystemConfiguration[] = [{
126
+ initDataTypes: ['sinf', 'skd'],
127
+ videoCapabilities: [{ contentType: 'application/vnd.apple.mpegurl' }],
128
+ }];
129
+
130
+ for (const keySystem of KEY_SYSTEMS[DRMType.FAIRPLAY]) {
131
+ try {
132
+ await navigator.requestMediaKeySystemAccess(keySystem, config);
133
+ return true;
134
+ } catch (e) {
135
+ // Try next key system
136
+ continue;
137
+ }
138
+ }
139
+ }
140
+
141
+ return false;
142
+ } catch {
143
+ return false;
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Check Widevine support
149
+ */
150
+ private async checkWidevineSupport(): Promise<boolean> {
151
+ try {
152
+ if (!navigator.requestMediaKeySystemAccess) {
153
+ return false;
154
+ }
155
+
156
+ const config: MediaKeySystemConfiguration[] = [{
157
+ initDataTypes: ['cenc'],
158
+ videoCapabilities: [{
159
+ contentType: 'video/mp4; codecs="avc1.42E01E"',
160
+ }],
161
+ }];
162
+
163
+ for (const keySystem of KEY_SYSTEMS[DRMType.WIDEVINE]) {
164
+ try {
165
+ await navigator.requestMediaKeySystemAccess(keySystem, config);
166
+ return true;
167
+ } catch (e) {
168
+ // Try next key system
169
+ continue;
170
+ }
171
+ }
172
+
173
+ return false;
174
+ } catch {
175
+ return false;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Check PlayReady support
181
+ */
182
+ private async checkPlayReadySupport(): Promise<boolean> {
183
+ try {
184
+ if (!navigator.requestMediaKeySystemAccess) {
185
+ return false;
186
+ }
187
+
188
+ const config: MediaKeySystemConfiguration[] = [{
189
+ initDataTypes: ['cenc'],
190
+ videoCapabilities: [{
191
+ contentType: 'video/mp4; codecs="avc1.42E01E"',
192
+ }],
193
+ }];
194
+
195
+ for (const keySystem of KEY_SYSTEMS[DRMType.PLAYREADY]) {
196
+ try {
197
+ await navigator.requestMediaKeySystemAccess(keySystem, config);
198
+ return true;
199
+ } catch (e) {
200
+ // Try next key system
201
+ continue;
202
+ }
203
+ }
204
+
205
+ return false;
206
+ } catch {
207
+ return false;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Get user-friendly browser name
213
+ */
214
+ getBrowserName(): string {
215
+ const ua = navigator.userAgent.toLowerCase();
216
+
217
+ if (ua.includes('edg/')) return 'Edge';
218
+ if (ua.includes('chrome') || ua.includes('chromium')) return 'Chrome';
219
+ if (ua.includes('firefox')) return 'Firefox';
220
+ if (ua.includes('safari')) return 'Safari';
221
+ if (ua.includes('opera') || ua.includes('opr/')) return 'Opera';
222
+
223
+ return 'Unknown';
224
+ }
225
+
226
+ /**
227
+ * Reset cached capabilities (useful for testing)
228
+ */
229
+ resetCapabilities(): void {
230
+ this.capabilities = null;
231
+ }
232
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Certificate Manager
3
+ * Manages FairPlay DRM certificates with in-memory caching
4
+ */
5
+
6
+ export class CertificateManager {
7
+ private static instance: CertificateManager;
8
+ private cache: Map<string, ArrayBuffer>;
9
+ private maxCacheSize: number = 10; // Max number of certificates to cache
10
+
11
+ private constructor() {
12
+ this.cache = new Map();
13
+ }
14
+
15
+ static getInstance(): CertificateManager {
16
+ if (!CertificateManager.instance) {
17
+ CertificateManager.instance = new CertificateManager();
18
+ }
19
+ return CertificateManager.instance;
20
+ }
21
+
22
+ /**
23
+ * Get certificate from cache
24
+ */
25
+ getCertificate(url: string): ArrayBuffer | null {
26
+ return this.cache.get(url) || null;
27
+ }
28
+
29
+ /**
30
+ * Store certificate in cache
31
+ */
32
+ setCertificate(url: string, certificate: ArrayBuffer): void {
33
+ // Implement LRU eviction if cache is full
34
+ if (this.cache.size >= this.maxCacheSize && !this.cache.has(url)) {
35
+ const firstKey = this.cache.keys().next().value;
36
+ if (firstKey) {
37
+ this.cache.delete(firstKey);
38
+ }
39
+ }
40
+
41
+ this.cache.set(url, certificate);
42
+ }
43
+
44
+ /**
45
+ * Check if certificate is cached
46
+ */
47
+ hasCertificate(url: string): boolean {
48
+ return this.cache.has(url);
49
+ }
50
+
51
+ /**
52
+ * Clear all cached certificates
53
+ */
54
+ clearCache(): void {
55
+ this.cache.clear();
56
+ }
57
+
58
+ /**
59
+ * Remove specific certificate from cache
60
+ */
61
+ removeCertificate(url: string): boolean {
62
+ return this.cache.delete(url);
63
+ }
64
+
65
+ /**
66
+ * Get cache size
67
+ */
68
+ getCacheSize(): number {
69
+ return this.cache.size;
70
+ }
71
+
72
+ /**
73
+ * Set max cache size
74
+ */
75
+ setMaxCacheSize(size: number): void {
76
+ this.maxCacheSize = size;
77
+
78
+ // Evict old entries if current size exceeds new max
79
+ while (this.cache.size > this.maxCacheSize) {
80
+ const firstKey = this.cache.keys().next().value;
81
+ if (firstKey) {
82
+ this.cache.delete(firstKey);
83
+ }
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * DRM Error Handler
3
+ * Converts DRM errors to user-friendly messages
4
+ */
5
+
6
+ import { DRMError, DRMErrorCode } from '../types/DRMTypes';
7
+
8
+ export class DRMErrorHandler {
9
+ /**
10
+ * Get user-friendly error message
11
+ */
12
+ static getUserFriendlyMessage(error: DRMError): string {
13
+ switch (error.code) {
14
+ case DRMErrorCode.UNSUPPORTED_BROWSER:
15
+ return 'DRM is not supported in this browser. Please use Chrome, Safari, Firefox, or Edge.';
16
+
17
+ case DRMErrorCode.CERTIFICATE_LOAD_FAILED:
18
+ return 'Failed to load DRM certificate. Please check your internet connection.';
19
+
20
+ case DRMErrorCode.LICENSE_REQUEST_FAILED:
21
+ return 'Failed to obtain content license. Please check your internet connection and try again.';
22
+
23
+ case DRMErrorCode.KEY_SYSTEM_ACCESS_DENIED:
24
+ return 'Access to DRM system was denied. Please ensure DRM is enabled in your browser settings.';
25
+
26
+ case DRMErrorCode.MEDIA_KEYS_CREATION_FAILED:
27
+ return 'Failed to initialize DRM protection. Please try refreshing the page.';
28
+
29
+ case DRMErrorCode.SESSION_CREATION_FAILED:
30
+ return 'Failed to create secure playback session. Please try again.';
31
+
32
+ case DRMErrorCode.LICENSE_INVALID:
33
+ return 'Invalid or expired content license. You may not have permission to view this content.';
34
+
35
+ case DRMErrorCode.CONFIGURATION_ERROR:
36
+ return 'DRM configuration error. Please contact support.';
37
+
38
+ case DRMErrorCode.NETWORK_ERROR:
39
+ return 'Network error while loading protected content. Please check your internet connection.';
40
+
41
+ case DRMErrorCode.TIMEOUT:
42
+ return 'DRM initialization timed out. Please try again.';
43
+
44
+ default:
45
+ return 'An error occurred while loading protected content. Please try again.';
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Get technical error message for developers
51
+ */
52
+ static getTechnicalMessage(error: DRMError): string {
53
+ let message = `[${error.code}] ${error.message}`;
54
+
55
+ if (error.details) {
56
+ message += `\nDetails: ${JSON.stringify(error.details, null, 2)}`;
57
+ }
58
+
59
+ if (error.systemError) {
60
+ message += `\nSystem Error: ${error.systemError}`;
61
+ }
62
+
63
+ return message;
64
+ }
65
+
66
+ /**
67
+ * Create standardized DRM error
68
+ */
69
+ static createError(
70
+ code: DRMErrorCode,
71
+ message: string,
72
+ fatal: boolean = true,
73
+ details?: any,
74
+ systemError?: any
75
+ ): DRMError {
76
+ return {
77
+ code,
78
+ message,
79
+ fatal,
80
+ details,
81
+ systemError,
82
+ };
83
+ }
84
+ }