unified-video-framework 1.4.445 → 1.4.447

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 (108) hide show
  1. package/package.json +1 -1
  2. package/packages/core/dist/interfaces.d.ts +14 -0
  3. package/packages/core/dist/interfaces.d.ts.map +1 -1
  4. package/packages/core/dist/version.d.ts +1 -1
  5. package/packages/core/dist/version.js +1 -1
  6. package/packages/core/src/interfaces.ts +24 -0
  7. package/packages/core/src/version.ts +1 -1
  8. package/packages/web/dist/WebPlayer.d.ts +364 -0
  9. package/packages/web/dist/WebPlayer.d.ts.map +1 -1
  10. package/packages/web/dist/WebPlayer.js +308 -6
  11. package/packages/web/dist/WebPlayer.js.map +1 -1
  12. package/packages/web/dist/chapters/ChapterManager.js +3 -3
  13. package/packages/web/dist/chapters/SkipButtonController.js +1 -1
  14. package/packages/web/dist/chapters/index.js +7 -7
  15. package/packages/web/dist/drm/BunnyCDNDRMProvider.d.ts +13 -0
  16. package/packages/web/dist/drm/BunnyCDNDRMProvider.d.ts.map +1 -0
  17. package/packages/web/dist/drm/BunnyCDNDRMProvider.js +65 -0
  18. package/packages/web/dist/drm/BunnyCDNDRMProvider.js.map +1 -0
  19. package/packages/web/dist/drm/DRMManager.d.ts +20 -0
  20. package/packages/web/dist/drm/DRMManager.d.ts.map +1 -0
  21. package/packages/web/dist/drm/DRMManager.js +130 -0
  22. package/packages/web/dist/drm/DRMManager.js.map +1 -0
  23. package/packages/web/dist/drm/FairPlayDRMHandler.d.ts +24 -0
  24. package/packages/web/dist/drm/FairPlayDRMHandler.d.ts.map +1 -0
  25. package/packages/web/dist/drm/FairPlayDRMHandler.js +190 -0
  26. package/packages/web/dist/drm/FairPlayDRMHandler.js.map +1 -0
  27. package/packages/web/dist/drm/WidevineDRMHandler.d.ts +21 -0
  28. package/packages/web/dist/drm/WidevineDRMHandler.d.ts.map +1 -0
  29. package/packages/web/dist/drm/WidevineDRMHandler.js +143 -0
  30. package/packages/web/dist/drm/WidevineDRMHandler.js.map +1 -0
  31. package/packages/web/dist/drm/index.d.ts +15 -0
  32. package/packages/web/dist/drm/index.d.ts.map +1 -0
  33. package/packages/web/dist/drm/index.js +13 -0
  34. package/packages/web/dist/drm/index.js.map +1 -0
  35. package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts +19 -0
  36. package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts.map +1 -0
  37. package/packages/web/dist/drm/providers/BunnyNetProvider.js +112 -0
  38. package/packages/web/dist/drm/providers/BunnyNetProvider.js.map +1 -0
  39. package/packages/web/dist/drm/providers/GenericProvider.d.ts +30 -0
  40. package/packages/web/dist/drm/providers/GenericProvider.d.ts.map +1 -0
  41. package/packages/web/dist/drm/providers/GenericProvider.js +104 -0
  42. package/packages/web/dist/drm/providers/GenericProvider.js.map +1 -0
  43. package/packages/web/dist/drm/systems/BaseDRM.d.ts +18 -0
  44. package/packages/web/dist/drm/systems/BaseDRM.d.ts.map +1 -0
  45. package/packages/web/dist/drm/systems/BaseDRM.js +29 -0
  46. package/packages/web/dist/drm/systems/BaseDRM.js.map +1 -0
  47. package/packages/web/dist/drm/systems/FairPlayDRM.d.ts +32 -0
  48. package/packages/web/dist/drm/systems/FairPlayDRM.d.ts.map +1 -0
  49. package/packages/web/dist/drm/systems/FairPlayDRM.js +208 -0
  50. package/packages/web/dist/drm/systems/FairPlayDRM.js.map +1 -0
  51. package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts +9 -0
  52. package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts.map +1 -0
  53. package/packages/web/dist/drm/systems/PlayReadyDRM.js +114 -0
  54. package/packages/web/dist/drm/systems/PlayReadyDRM.js.map +1 -0
  55. package/packages/web/dist/drm/systems/WidevineDRM.d.ts +9 -0
  56. package/packages/web/dist/drm/systems/WidevineDRM.d.ts.map +1 -0
  57. package/packages/web/dist/drm/systems/WidevineDRM.js +159 -0
  58. package/packages/web/dist/drm/systems/WidevineDRM.js.map +1 -0
  59. package/packages/web/dist/drm/types/BunnyNetTypes.d.ts +20 -0
  60. package/packages/web/dist/drm/types/BunnyNetTypes.d.ts.map +1 -0
  61. package/packages/web/dist/drm/types/BunnyNetTypes.js +8 -0
  62. package/packages/web/dist/drm/types/BunnyNetTypes.js.map +1 -0
  63. package/packages/web/dist/drm/types/DRMTypes.d.ts +60 -0
  64. package/packages/web/dist/drm/types/DRMTypes.d.ts.map +1 -0
  65. package/packages/web/dist/drm/types/DRMTypes.js +22 -0
  66. package/packages/web/dist/drm/types/DRMTypes.js.map +1 -0
  67. package/packages/web/dist/drm/utils/BrowserDetector.d.ts +20 -0
  68. package/packages/web/dist/drm/utils/BrowserDetector.d.ts.map +1 -0
  69. package/packages/web/dist/drm/utils/BrowserDetector.js +211 -0
  70. package/packages/web/dist/drm/utils/BrowserDetector.js.map +1 -0
  71. package/packages/web/dist/drm/utils/CertificateManager.d.ts +15 -0
  72. package/packages/web/dist/drm/utils/CertificateManager.d.ts.map +1 -0
  73. package/packages/web/dist/drm/utils/CertificateManager.js +46 -0
  74. package/packages/web/dist/drm/utils/CertificateManager.js.map +1 -0
  75. package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts +7 -0
  76. package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts.map +1 -0
  77. package/packages/web/dist/drm/utils/DRMErrorHandler.js +49 -0
  78. package/packages/web/dist/drm/utils/DRMErrorHandler.js.map +1 -0
  79. package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts +15 -0
  80. package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts.map +1 -0
  81. package/packages/web/dist/drm/utils/LicenseRequestHandler.js +110 -0
  82. package/packages/web/dist/drm/utils/LicenseRequestHandler.js.map +1 -0
  83. package/packages/web/dist/drm.js +5 -0
  84. package/packages/web/dist/index.js +4 -4
  85. package/packages/web/dist/paywall/PaywallController.js +1 -1
  86. package/packages/web/dist/react/EPG.js +6 -6
  87. package/packages/web/dist/react/WebPlayerView.d.ts +399 -0
  88. package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
  89. package/packages/web/dist/react/WebPlayerView.js +19 -6
  90. package/packages/web/dist/react/WebPlayerView.js.map +1 -1
  91. package/packages/web/dist/react/WebPlayerViewWithEPG.js +2 -2
  92. package/packages/web/dist/react/components/ChapterProgress.js +1 -1
  93. package/packages/web/dist/react/components/EPGOverlay-improved-positioning.js +5 -5
  94. package/packages/web/dist/react/components/EPGOverlay.js +5 -5
  95. package/packages/web/dist/react/components/EPGProgramDetails.js +1 -1
  96. package/packages/web/dist/react/components/EPGProgramGrid.js +1 -1
  97. package/packages/web/dist/react/components/EPGTimelineHeader.js +1 -1
  98. package/packages/web/dist/react/components/SkipButton.js +1 -1
  99. package/packages/web/dist/react/examples/google-ads-example.js +1 -1
  100. package/packages/web/dist/react/types/ThumbnailPreviewTypes.d.ts +26 -0
  101. package/packages/web/dist/react/types/ThumbnailPreviewTypes.d.ts.map +1 -0
  102. package/packages/web/dist/react/types/ThumbnailPreviewTypes.js +2 -0
  103. package/packages/web/dist/react/types/ThumbnailPreviewTypes.js.map +1 -0
  104. package/packages/web/dist/test/epg-test.js +1 -1
  105. package/packages/web/src/WebPlayer.ts +389 -3
  106. package/packages/web/src/react/WebPlayerView.tsx +21 -2
  107. package/packages/web/src/react/types/ThumbnailPreviewTypes.ts +62 -0
  108. package/scripts/fix-imports.js +61 -23
@@ -1,6 +1,6 @@
1
- import { DEFAULT_CHAPTER_CONFIG, SEGMENT_COLORS } from "./types/ChapterTypes.js";
2
- import { SkipButtonController } from "./SkipButtonController.js";
3
- import { CreditsButtonController } from "./CreditsButtonController.js";
1
+ import { DEFAULT_CHAPTER_CONFIG, SEGMENT_COLORS } from './types/ChapterTypes.js';
2
+ import { SkipButtonController } from './SkipButtonController.js';
3
+ import { CreditsButtonController } from './CreditsButtonController.js';
4
4
  export class ChapterManager {
5
5
  constructor(playerContainer, videoElement, config = DEFAULT_CHAPTER_CONFIG) {
6
6
  this.playerContainer = playerContainer;
@@ -1,4 +1,4 @@
1
- import { DEFAULT_SKIP_LABELS } from "./types/ChapterTypes.js";
1
+ import { DEFAULT_SKIP_LABELS } from './types/ChapterTypes.js';
2
2
  export class SkipButtonController {
3
3
  constructor(playerContainer, config, onSkip, onButtonShown, onButtonHidden) {
4
4
  this.playerContainer = playerContainer;
@@ -1,8 +1,8 @@
1
- export { ChapterManager } from "./ChapterManager.js";
2
- export { SkipButtonController } from "./SkipButtonController.js";
3
- export { UserPreferencesManager } from "./UserPreferencesManager.js";
4
- export * from "./types/ChapterTypes.js";
5
- export { useChapters } from "../react/hooks/useChapters.js";
6
- export { SkipButton } from "../react/components/SkipButton.js";
7
- export { ChapterProgress } from "../react/components/ChapterProgress.js";
1
+ export { ChapterManager } from './ChapterManager.js';
2
+ export { SkipButtonController } from './SkipButtonController.js';
3
+ export { UserPreferencesManager } from './UserPreferencesManager.js';
4
+ export * from './types/ChapterTypes.js';
5
+ export { useChapters } from '../react/hooks/useChapters.js';
6
+ export { SkipButton } from '../react/components/SkipButton.js';
7
+ export { ChapterProgress } from '../react/components/ChapterProgress.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,13 @@
1
+ import { BunnyCDNDRMConfig, DRMToken } from './types/DRMTypes';
2
+ export declare class BunnyCDNDRMProvider {
3
+ private config;
4
+ constructor(config: BunnyCDNDRMConfig);
5
+ getFairPlayCertificateUrl(): string;
6
+ getFairPlayLicenseUrl(): string;
7
+ getWidevineLicenseUrl(): string;
8
+ getManifestUrl(): Promise<string>;
9
+ injectToken(url: string, token: DRMToken): string;
10
+ getLicenseHeaders(): Promise<Record<string, string>>;
11
+ shouldRenewToken(token: DRMToken): boolean;
12
+ }
13
+ //# sourceMappingURL=BunnyCDNDRMProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunnyCDNDRMProvider.d.ts","sourceRoot":"","sources":["../../src/drm/BunnyCDNDRMProvider.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAY,MAAM,kBAAkB,CAAC;AAEzE,qBAAa,mBAAmB;IAClB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAK7C,yBAAyB,IAAI,MAAM;IAUnC,qBAAqB,IAAI,MAAM;IAU/B,qBAAqB,IAAI,MAAM;IAWzB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAcvC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM;IAa3C,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA2B1D,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;CAK3C"}
@@ -0,0 +1,65 @@
1
+ import { DRMError } from "./types/DRMTypes.js";
2
+ export class BunnyCDNDRMProvider {
3
+ constructor(config) {
4
+ this.config = config;
5
+ }
6
+ getFairPlayCertificateUrl() {
7
+ if (this.config.certificateUrl) {
8
+ return this.config.certificateUrl;
9
+ }
10
+ return `https://video.bunnycdn.com/FairPlay/${this.config.libraryId}/certificate`;
11
+ }
12
+ getFairPlayLicenseUrl() {
13
+ if (this.config.licenseUrl) {
14
+ return this.config.licenseUrl;
15
+ }
16
+ return `https://video.bunnycdn.com/FairPlay/${this.config.libraryId}/license/?videoId=${this.config.videoId}`;
17
+ }
18
+ getWidevineLicenseUrl() {
19
+ if (this.config.licenseUrl) {
20
+ return this.config.licenseUrl;
21
+ }
22
+ return `https://video.bunnycdn.com/Widevine/${this.config.libraryId}/license/?videoId=${this.config.videoId}`;
23
+ }
24
+ async getManifestUrl() {
25
+ const baseUrl = `https://${this.config.pullZoneUrl}.b-cdn.net/${this.config.videoId}/playlist.m3u8`;
26
+ const token = await this.config.tokenProvider.getManifestToken();
27
+ if (!token) {
28
+ throw new DRMError('No manifest token available', 'MANIFEST_TOKEN_ERROR');
29
+ }
30
+ return this.injectToken(baseUrl, token);
31
+ }
32
+ injectToken(url, token) {
33
+ const urlObj = new URL(url);
34
+ urlObj.searchParams.set('token', token.token);
35
+ urlObj.searchParams.set('expires', token.expires.toString());
36
+ if (token.tokenVer) {
37
+ urlObj.searchParams.set('token_ver', token.tokenVer);
38
+ }
39
+ return urlObj.toString();
40
+ }
41
+ async getLicenseHeaders() {
42
+ const token = await this.config.tokenProvider.getLicenseToken();
43
+ if (!token) {
44
+ throw new DRMError('No license token available', 'LICENSE_TOKEN_ERROR');
45
+ }
46
+ const headers = {
47
+ 'Content-Type': 'application/octet-stream',
48
+ 'X-Bunny-Token': token.token,
49
+ 'X-Bunny-Expires': token.expires.toString(),
50
+ };
51
+ if (token.tokenVer) {
52
+ headers['X-Bunny-Token-Version'] = token.tokenVer;
53
+ }
54
+ if (this.config.enableReferrerProtection) {
55
+ headers['Referer'] = window.location.origin;
56
+ }
57
+ return headers;
58
+ }
59
+ shouldRenewToken(token) {
60
+ const nowSeconds = Math.floor(Date.now() / 1000);
61
+ const bufferSeconds = 300;
62
+ return token.expires - nowSeconds < bufferSeconds;
63
+ }
64
+ }
65
+ //# sourceMappingURL=BunnyCDNDRMProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunnyCDNDRMProvider.js","sourceRoot":"","sources":["../../src/drm/BunnyCDNDRMProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { DRMConfig } from '@unified-video/core';
2
+ import { DRMInitResult } from './types/DRMTypes';
3
+ export declare class DRMManager {
4
+ private videoElement;
5
+ private config;
6
+ private drmSystem;
7
+ private browserDetector;
8
+ private debug;
9
+ constructor(videoElement: HTMLVideoElement, config: DRMConfig, debug?: boolean);
10
+ initialize(): Promise<DRMInitResult>;
11
+ getHLSConfig(): any;
12
+ getDashProtectionData(): any;
13
+ destroy(): Promise<void>;
14
+ private selectDRMType;
15
+ private isDRMTypeSupported;
16
+ private createDRMSystem;
17
+ private normalizeConfig;
18
+ private log;
19
+ }
20
+ //# sourceMappingURL=DRMManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DRMManager.d.ts","sourceRoot":"","sources":["../../src/drm/DRMManager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAqB,aAAa,EAA2C,MAAM,kBAAkB,CAAC;AAS7G,qBAAa,UAAU;IACrB,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,KAAK,CAAkB;gBAEnB,YAAY,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAE,OAAe;IAU/E,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IAmE1C,YAAY,IAAI,GAAG;IAWnB,qBAAqB,IAAI,GAAG;IAWtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,GAAG;CAKZ"}
@@ -0,0 +1,130 @@
1
+ import { DRMType as DRMTypeEnum } from "../../../core/dist/index.js";
2
+ import { DRMErrorCode } from "./types/DRMTypes.js";
3
+ import { BrowserDetector } from "./utils/BrowserDetector.js";
4
+ import { BunnyNetProvider } from "./providers/BunnyNetProvider.js";
5
+ import { WidevineDRM } from "./systems/WidevineDRM.js";
6
+ import { FairPlayDRM } from "./systems/FairPlayDRM.js";
7
+ import { PlayReadyDRM } from "./systems/PlayReadyDRM.js";
8
+ import { DRMErrorHandler } from "./utils/DRMErrorHandler.js";
9
+ export class DRMManager {
10
+ constructor(videoElement, config, debug = false) {
11
+ this.drmSystem = null;
12
+ this.debug = false;
13
+ this.videoElement = videoElement;
14
+ this.config = this.normalizeConfig(config);
15
+ this.debug = debug || this.config.debug || false;
16
+ this.browserDetector = BrowserDetector.getInstance();
17
+ }
18
+ async initialize() {
19
+ try {
20
+ this.log('Initializing DRM system...');
21
+ if (typeof window !== 'undefined' && !window.isSecureContext) {
22
+ throw DRMErrorHandler.createError(DRMErrorCode.SECURE_CONTEXT_REQUIRED, 'DRM requires a secure context (HTTPS or localhost). Please ensure your site is running over HTTPS.', true);
23
+ }
24
+ const capabilities = await this.browserDetector.detectCapabilities();
25
+ this.log('Browser DRM capabilities:', capabilities);
26
+ const drmType = this.selectDRMType(capabilities);
27
+ if (!drmType) {
28
+ const browserName = this.browserDetector.getBrowserName();
29
+ throw DRMErrorHandler.createError(DRMErrorCode.UNSUPPORTED_BROWSER, `No supported DRM system found in ${browserName}. Please use Chrome, Safari, Firefox, or Edge.`, true, { browser: browserName, capabilities });
30
+ }
31
+ this.log(`Selected DRM type: ${drmType}`);
32
+ this.drmSystem = this.createDRMSystem(drmType);
33
+ await this.drmSystem.initialize();
34
+ return {
35
+ success: true,
36
+ drmType,
37
+ keySystem: this.drmSystem.getKeySystem(),
38
+ };
39
+ }
40
+ catch (error) {
41
+ this.log('DRM initialization failed:', error);
42
+ const capabilities = await this.browserDetector.detectCapabilities();
43
+ const drmError = error.code && error.code.startsWith('DRM_')
44
+ ? error
45
+ : DRMErrorHandler.createError(DRMErrorCode.CONFIGURATION_ERROR, error.message || 'DRM initialization failed', true, { ...error, capabilities });
46
+ return {
47
+ success: false,
48
+ drmType: this.config.type,
49
+ keySystem: '',
50
+ error: drmError,
51
+ };
52
+ }
53
+ }
54
+ getHLSConfig() {
55
+ if (!this.drmSystem) {
56
+ throw new Error('DRM system not initialized. Call initialize() first.');
57
+ }
58
+ return this.drmSystem.getHLSConfig();
59
+ }
60
+ getDashProtectionData() {
61
+ if (!this.drmSystem) {
62
+ throw new Error('DRM system not initialized. Call initialize() first.');
63
+ }
64
+ return this.drmSystem.getDashProtectionData();
65
+ }
66
+ async destroy() {
67
+ if (this.drmSystem) {
68
+ this.log('Destroying DRM system');
69
+ await this.drmSystem.destroy();
70
+ this.drmSystem = null;
71
+ }
72
+ }
73
+ selectDRMType(capabilities) {
74
+ if (this.config.type) {
75
+ const typeSupported = this.isDRMTypeSupported(this.config.type, capabilities);
76
+ if (typeSupported) {
77
+ return this.config.type;
78
+ }
79
+ this.log(`Requested DRM type ${this.config.type} not supported, falling back to browser default`);
80
+ }
81
+ return capabilities.supportedType;
82
+ }
83
+ isDRMTypeSupported(drmType, capabilities) {
84
+ switch (drmType) {
85
+ case DRMTypeEnum.WIDEVINE:
86
+ return capabilities.widevine;
87
+ case DRMTypeEnum.FAIRPLAY:
88
+ return capabilities.fairplay;
89
+ case DRMTypeEnum.PLAYREADY:
90
+ return capabilities.playready;
91
+ default:
92
+ return false;
93
+ }
94
+ }
95
+ createDRMSystem(drmType) {
96
+ switch (drmType) {
97
+ case DRMTypeEnum.FAIRPLAY:
98
+ return new FairPlayDRM(this.videoElement, this.config, this.debug);
99
+ case DRMTypeEnum.WIDEVINE:
100
+ return new WidevineDRM(this.videoElement, this.config, this.debug);
101
+ case DRMTypeEnum.PLAYREADY:
102
+ return new PlayReadyDRM(this.videoElement, this.config, this.debug);
103
+ default:
104
+ throw DRMErrorHandler.createError(DRMErrorCode.CONFIGURATION_ERROR, `Unsupported DRM type: ${drmType}`, true);
105
+ }
106
+ }
107
+ normalizeConfig(config) {
108
+ const extended = { ...config };
109
+ if (BunnyNetProvider.isBunnyNetConfig(config)) {
110
+ extended.provider = 'bunny';
111
+ const ids = BunnyNetProvider.extractIdsFromUrl(config.licenseUrl);
112
+ if (ids.libraryId)
113
+ extended.libraryId = ids.libraryId;
114
+ if (ids.videoId)
115
+ extended.videoId = ids.videoId;
116
+ this.log('Detected Bunny.net DRM configuration');
117
+ }
118
+ extended.retryConfig = extended.retryConfig || {
119
+ maxRetries: 3,
120
+ retryDelay: 1000,
121
+ };
122
+ return extended;
123
+ }
124
+ log(...args) {
125
+ if (this.debug) {
126
+ console.log('[DRMManager]', ...args);
127
+ }
128
+ }
129
+ }
130
+ //# sourceMappingURL=DRMManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DRMManager.js","sourceRoot":"","sources":["../../src/drm/DRMManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { IDRMHandler, WebDRMConfig } from './types/DRMTypes';
2
+ export declare class FairPlayDRMHandler implements IDRMHandler {
3
+ private config;
4
+ private bunnyProvider;
5
+ private videoElement;
6
+ private certificateData;
7
+ private pendingSessions;
8
+ constructor(config: WebDRMConfig);
9
+ isSupported(): boolean;
10
+ initialize(): Promise<void>;
11
+ private fetchCertificate;
12
+ private getCertificateUrl;
13
+ private getCertificateHeaders;
14
+ setupDRM(videoElement: HTMLVideoElement, manifestUrl: string): Promise<void>;
15
+ private onWebkitNeedKey;
16
+ private extractContentId;
17
+ private onKeyMessage;
18
+ private requestLicense;
19
+ private getLicenseUrl;
20
+ private getLicenseHeaders;
21
+ onLicenseRequest(licenseRequest: ArrayBuffer): Promise<ArrayBuffer>;
22
+ destroy(): void;
23
+ }
24
+ //# sourceMappingURL=FairPlayDRMHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FairPlayDRMHandler.d.ts","sourceRoot":"","sources":["../../src/drm/FairPlayDRMHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAY,MAAM,kBAAkB,CAAC;AAGvE,qBAAa,kBAAmB,YAAW,WAAW;IACpD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,eAAe,CAAuB;gBAElC,MAAM,EAAE,YAAY;IAWhC,WAAW,IAAI,OAAO;IAahB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YA4BnB,gBAAgB;IA6B9B,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,qBAAqB;IAUvB,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAgBpE,eAAe;IAgD7B,OAAO,CAAC,gBAAgB;YAiBV,YAAY;YA+BZ,cAAc;IAsC5B,OAAO,CAAC,aAAa;YAYP,iBAAiB;IAYzB,gBAAgB,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAOzE,OAAO,IAAI,IAAI;CAmBhB"}
@@ -0,0 +1,190 @@
1
+ import { DRMError } from "./types/DRMTypes.js";
2
+ import { BunnyCDNDRMProvider } from "./BunnyCDNDRMProvider.js";
3
+ export class FairPlayDRMHandler {
4
+ constructor(config) {
5
+ this.bunnyProvider = null;
6
+ this.videoElement = null;
7
+ this.certificateData = null;
8
+ this.pendingSessions = new Set();
9
+ this.config = config;
10
+ if (config.provider === 'bunny' && config.bunny) {
11
+ this.bunnyProvider = new BunnyCDNDRMProvider(config.bunny);
12
+ }
13
+ }
14
+ isSupported() {
15
+ const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
16
+ return !!(isSafari &&
17
+ window.WebKitMediaKeys &&
18
+ navigator.requestMediaKeySystemAccess);
19
+ }
20
+ async initialize() {
21
+ if (!this.isSupported()) {
22
+ throw new DRMError('FairPlay DRM is not supported in this browser', 'FAIRPLAY_NOT_SUPPORTED');
23
+ }
24
+ console.log('[FairPlay] Initializing DRM system...');
25
+ try {
26
+ this.certificateData = await this.fetchCertificate();
27
+ console.log('[FairPlay] Certificate loaded:', this.certificateData.byteLength, 'bytes');
28
+ }
29
+ catch (error) {
30
+ console.error('[FairPlay] Failed to initialize:', error);
31
+ throw new DRMError('Failed to initialize FairPlay DRM', 'FAIRPLAY_INIT_ERROR', error);
32
+ }
33
+ }
34
+ async fetchCertificate() {
35
+ const certificateUrl = this.getCertificateUrl();
36
+ const headers = this.getCertificateHeaders();
37
+ console.log('[FairPlay] Fetching certificate from:', certificateUrl);
38
+ try {
39
+ const response = await fetch(certificateUrl, { headers });
40
+ if (!response.ok) {
41
+ throw new Error(`Certificate fetch failed: ${response.status} ${response.statusText}`);
42
+ }
43
+ const certificate = await response.arrayBuffer();
44
+ return certificate;
45
+ }
46
+ catch (error) {
47
+ console.error('[FairPlay] Certificate fetch failed:', error);
48
+ throw new DRMError('Failed to fetch FairPlay certificate', 'CERTIFICATE_FETCH_ERROR', error);
49
+ }
50
+ }
51
+ getCertificateUrl() {
52
+ if (this.config.provider === 'bunny' && this.bunnyProvider) {
53
+ return this.bunnyProvider.getFairPlayCertificateUrl();
54
+ }
55
+ else if (this.config.provider === 'generic' && this.config.generic) {
56
+ if (!this.config.generic.certificateUrl) {
57
+ throw new DRMError('FairPlay certificate URL is required', 'NO_CERTIFICATE_URL');
58
+ }
59
+ return this.config.generic.certificateUrl;
60
+ }
61
+ throw new DRMError('No certificate URL configured', 'NO_CERTIFICATE_URL');
62
+ }
63
+ getCertificateHeaders() {
64
+ if (this.config.provider === 'generic' && this.config.generic?.certificateHeaders) {
65
+ return this.config.generic.certificateHeaders;
66
+ }
67
+ return {};
68
+ }
69
+ async setupDRM(videoElement, manifestUrl) {
70
+ if (!this.certificateData) {
71
+ throw new DRMError('Certificate not loaded', 'CERTIFICATE_NOT_LOADED');
72
+ }
73
+ this.videoElement = videoElement;
74
+ videoElement.addEventListener('webkitneedkey', this.onWebkitNeedKey.bind(this));
75
+ console.log('[FairPlay] DRM setup complete, waiting for key requests');
76
+ }
77
+ async onWebkitNeedKey(event) {
78
+ console.log('[FairPlay] Key request event received');
79
+ try {
80
+ if (!this.certificateData || !this.videoElement) {
81
+ throw new DRMError('DRM not properly initialized', 'DRM_NOT_INITIALIZED');
82
+ }
83
+ const contentId = this.extractContentId(event.initData);
84
+ const keySession = event.target.webkitKeys.createSession('video/mp4', event.initData);
85
+ if (!keySession) {
86
+ throw new DRMError('Failed to create key session', 'SESSION_CREATE_ERROR');
87
+ }
88
+ this.pendingSessions.add(keySession);
89
+ keySession.addEventListener('webkitkeymessage', async (messageEvent) => {
90
+ await this.onKeyMessage(keySession, messageEvent, contentId);
91
+ });
92
+ keySession.addEventListener('webkitkeyadded', () => {
93
+ console.log('[FairPlay] Key added successfully');
94
+ this.pendingSessions.delete(keySession);
95
+ });
96
+ keySession.addEventListener('webkitkeyerror', () => {
97
+ console.error('[FairPlay] Key error:', keySession.error);
98
+ this.pendingSessions.delete(keySession);
99
+ });
100
+ }
101
+ catch (error) {
102
+ console.error('[FairPlay] Failed to handle key request:', error);
103
+ throw new DRMError('Failed to process FairPlay key request', 'KEY_REQUEST_ERROR', error);
104
+ }
105
+ }
106
+ extractContentId(initData) {
107
+ const initDataString = String.fromCharCode.apply(null, Array.from(new Uint8Array(initData)));
108
+ const contentIdMatch = initDataString.match(/skd:\/\/([^"'\s]+)/);
109
+ if (contentIdMatch && contentIdMatch[1]) {
110
+ return contentIdMatch[1];
111
+ }
112
+ return initDataString;
113
+ }
114
+ async onKeyMessage(keySession, event, contentId) {
115
+ console.log('[FairPlay] Key message received, requesting license');
116
+ try {
117
+ const spcData = event.message;
118
+ const ckcData = await this.requestLicense(spcData, contentId);
119
+ keySession.update(new Uint8Array(ckcData));
120
+ console.log('[FairPlay] License applied successfully');
121
+ }
122
+ catch (error) {
123
+ console.error('[FairPlay] Failed to process license:', error);
124
+ throw new DRMError('Failed to process FairPlay license', 'LICENSE_PROCESS_ERROR', error);
125
+ }
126
+ }
127
+ async requestLicense(spcData, contentId) {
128
+ const licenseUrl = this.getLicenseUrl(contentId);
129
+ const headers = await this.getLicenseHeaders();
130
+ console.log('[FairPlay] Requesting license from:', licenseUrl);
131
+ try {
132
+ const response = await fetch(licenseUrl, {
133
+ method: 'POST',
134
+ headers: {
135
+ ...headers,
136
+ 'Content-Type': 'application/octet-stream'
137
+ },
138
+ body: spcData
139
+ });
140
+ if (!response.ok) {
141
+ throw new Error(`License request failed: ${response.status} ${response.statusText}`);
142
+ }
143
+ const ckcData = await response.arrayBuffer();
144
+ console.log('[FairPlay] License received:', ckcData.byteLength, 'bytes');
145
+ return ckcData;
146
+ }
147
+ catch (error) {
148
+ console.error('[FairPlay] License request failed:', error);
149
+ throw new DRMError('Failed to retrieve FairPlay license', 'LICENSE_FETCH_ERROR', error);
150
+ }
151
+ }
152
+ getLicenseUrl(contentId) {
153
+ if (this.config.provider === 'bunny' && this.bunnyProvider) {
154
+ return this.bunnyProvider.getFairPlayLicenseUrl();
155
+ }
156
+ else if (this.config.provider === 'generic' && this.config.generic) {
157
+ return this.config.generic.licenseUrl;
158
+ }
159
+ throw new DRMError('No license URL configured', 'NO_LICENSE_URL');
160
+ }
161
+ async getLicenseHeaders() {
162
+ if (this.config.provider === 'bunny' && this.bunnyProvider) {
163
+ return await this.bunnyProvider.getLicenseHeaders();
164
+ }
165
+ else if (this.config.provider === 'generic' && this.config.generic) {
166
+ return this.config.generic.headers || {};
167
+ }
168
+ return {};
169
+ }
170
+ async onLicenseRequest(licenseRequest) {
171
+ return await this.requestLicense(new Uint8Array(licenseRequest), '');
172
+ }
173
+ destroy() {
174
+ if (this.videoElement) {
175
+ this.videoElement.removeEventListener('webkitneedkey', this.onWebkitNeedKey.bind(this));
176
+ this.videoElement = null;
177
+ }
178
+ this.pendingSessions.forEach(session => {
179
+ try {
180
+ session.close();
181
+ }
182
+ catch (e) {
183
+ }
184
+ });
185
+ this.pendingSessions.clear();
186
+ this.certificateData = null;
187
+ this.bunnyProvider = null;
188
+ }
189
+ }
190
+ //# sourceMappingURL=FairPlayDRMHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FairPlayDRMHandler.js","sourceRoot":"","sources":["../../src/drm/FairPlayDRMHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { IDRMHandler, WebDRMConfig } from './types/DRMTypes';
2
+ export declare class WidevineDRMHandler implements IDRMHandler {
3
+ private mediaKeys;
4
+ private config;
5
+ private bunnyProvider;
6
+ private videoElement;
7
+ private pendingLicenseRequests;
8
+ constructor(config: WebDRMConfig);
9
+ isSupported(): boolean;
10
+ initialize(): Promise<void>;
11
+ private getKeySystemConfiguration;
12
+ setupDRM(videoElement: HTMLVideoElement, manifestUrl: string): Promise<void>;
13
+ private onEncrypted;
14
+ private onMessage;
15
+ private requestLicense;
16
+ private getLicenseUrl;
17
+ private getLicenseHeaders;
18
+ onLicenseRequest(licenseRequest: ArrayBuffer): Promise<ArrayBuffer>;
19
+ destroy(): void;
20
+ }
21
+ //# sourceMappingURL=WidevineDRMHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidevineDRMHandler.d.ts","sourceRoot":"","sources":["../../src/drm/WidevineDRMHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,YAAY,EAA6B,MAAM,kBAAkB,CAAC;AAGxF,qBAAa,kBAAmB,YAAW,WAAW;IACpD,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,sBAAsB,CAA0D;gBAE5E,MAAM,EAAE,YAAY;IAWhC,WAAW,IAAI,OAAO;IAUhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCjC,OAAO,CAAC,yBAAyB;IAsB3B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAkBpE,WAAW;YAiCX,SAAS;YA2BT,cAAc;IAmC5B,OAAO,CAAC,aAAa;YAYP,iBAAiB;IAYzB,gBAAgB,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAOzE,OAAO,IAAI,IAAI;CAShB"}