unified-video-framework 1.4.410 → 1.4.412
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/package.json +1 -1
- package/packages/core/dist/interfaces/IVideoPlayer.d.ts +22 -0
- package/packages/core/dist/interfaces/IVideoPlayer.d.ts.map +1 -1
- package/packages/core/src/interfaces/IVideoPlayer.ts +27 -0
- package/packages/web/dist/WebPlayer.d.ts +4 -0
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +68 -4
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/dist/drm/BunnyCDNDRMProvider.d.ts +13 -0
- package/packages/web/dist/drm/BunnyCDNDRMProvider.d.ts.map +1 -0
- package/packages/web/dist/drm/BunnyCDNDRMProvider.js +65 -0
- package/packages/web/dist/drm/BunnyCDNDRMProvider.js.map +1 -0
- package/packages/web/dist/drm/DRMManager.d.ts +13 -0
- package/packages/web/dist/drm/DRMManager.d.ts.map +1 -0
- package/packages/web/dist/drm/DRMManager.js +59 -0
- package/packages/web/dist/drm/DRMManager.js.map +1 -0
- package/packages/web/dist/drm/FairPlayDRMHandler.d.ts +24 -0
- package/packages/web/dist/drm/FairPlayDRMHandler.d.ts.map +1 -0
- package/packages/web/dist/drm/FairPlayDRMHandler.js +190 -0
- package/packages/web/dist/drm/FairPlayDRMHandler.js.map +1 -0
- package/packages/web/dist/drm/WidevineDRMHandler.d.ts +21 -0
- package/packages/web/dist/drm/WidevineDRMHandler.d.ts.map +1 -0
- package/packages/web/dist/drm/WidevineDRMHandler.js +143 -0
- package/packages/web/dist/drm/WidevineDRMHandler.js.map +1 -0
- package/packages/web/dist/drm/types/DRMTypes.d.ts +52 -0
- package/packages/web/dist/drm/types/DRMTypes.d.ts.map +1 -0
- package/packages/web/dist/drm/types/DRMTypes.js +15 -0
- package/packages/web/dist/drm/types/DRMTypes.js.map +1 -0
- package/packages/web/dist/react/WebPlayerView.d.ts +18 -1
- package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
- package/packages/web/dist/react/WebPlayerView.js +28 -0
- package/packages/web/dist/react/WebPlayerView.js.map +1 -1
- package/packages/web/src/WebPlayer.ts +96 -4
- package/packages/web/src/drm/BunnyCDNDRMProvider.ts +104 -0
- package/packages/web/src/drm/DRMManager.ts +99 -0
- package/packages/web/src/drm/FairPlayDRMHandler.ts +322 -0
- package/packages/web/src/drm/WidevineDRMHandler.ts +246 -0
- package/packages/web/src/drm/types/DRMTypes.ts +97 -0
- package/packages/web/src/react/WebPlayerView.tsx +55 -3
|
@@ -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,13 @@
|
|
|
1
|
+
import { WebDRMConfig } from './types/DRMTypes';
|
|
2
|
+
export declare class DRMManager {
|
|
3
|
+
private handler;
|
|
4
|
+
private config;
|
|
5
|
+
constructor(config: WebDRMConfig);
|
|
6
|
+
private detectDRMHandler;
|
|
7
|
+
initialize(): Promise<void>;
|
|
8
|
+
setupDRM(videoElement: HTMLVideoElement, manifestUrl: string): Promise<void>;
|
|
9
|
+
isActive(): boolean;
|
|
10
|
+
getHandlerType(): 'widevine' | 'fairplay' | null;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=DRMManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DRMManager.d.ts","sourceRoot":"","sources":["../../src/drm/DRMManager.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,YAAY,EAAY,MAAM,kBAAkB,CAAC;AAIvE,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAOhC,OAAO,CAAC,gBAAgB;IAgBlB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlF,QAAQ,IAAI,OAAO;IAOnB,cAAc,IAAI,UAAU,GAAG,UAAU,GAAG,IAAI;IAQhD,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DRMError } from "./types/DRMTypes.js";
|
|
2
|
+
import { WidevineDRMHandler } from "./WidevineDRMHandler.js";
|
|
3
|
+
import { FairPlayDRMHandler } from "./FairPlayDRMHandler.js";
|
|
4
|
+
export class DRMManager {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.handler = null;
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
detectDRMHandler() {
|
|
10
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
11
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
12
|
+
if (isSafari) {
|
|
13
|
+
console.log('[DRM] Detected Safari - using FairPlay DRM');
|
|
14
|
+
return new FairPlayDRMHandler(this.config);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log('[DRM] Detected non-Safari browser - using Widevine DRM');
|
|
18
|
+
return new WidevineDRMHandler(this.config);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async initialize() {
|
|
22
|
+
console.log('[DRM] Initializing DRM Manager...');
|
|
23
|
+
try {
|
|
24
|
+
this.handler = this.detectDRMHandler();
|
|
25
|
+
if (!this.handler.isSupported()) {
|
|
26
|
+
throw new DRMError('DRM is not supported in this browser', 'DRM_NOT_SUPPORTED');
|
|
27
|
+
}
|
|
28
|
+
await this.handler.initialize();
|
|
29
|
+
console.log('[DRM] DRM Manager initialized successfully');
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error('[DRM] Failed to initialize DRM Manager:', error);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async setupDRM(videoElement, manifestUrl) {
|
|
37
|
+
if (!this.handler) {
|
|
38
|
+
throw new DRMError('DRM Manager not initialized', 'DRM_NOT_INITIALIZED');
|
|
39
|
+
}
|
|
40
|
+
console.log('[DRM] Setting up DRM for video element');
|
|
41
|
+
await this.handler.setupDRM(videoElement, manifestUrl);
|
|
42
|
+
}
|
|
43
|
+
isActive() {
|
|
44
|
+
return this.handler !== null;
|
|
45
|
+
}
|
|
46
|
+
getHandlerType() {
|
|
47
|
+
if (!this.handler)
|
|
48
|
+
return null;
|
|
49
|
+
return this.handler instanceof FairPlayDRMHandler ? 'fairplay' : 'widevine';
|
|
50
|
+
}
|
|
51
|
+
destroy() {
|
|
52
|
+
if (this.handler) {
|
|
53
|
+
console.log('[DRM] Destroying DRM Manager');
|
|
54
|
+
this.handler.destroy();
|
|
55
|
+
this.handler = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=DRMManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DRMManager.js","sourceRoot":"","sources":["../../src/drm/DRMManager.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6B,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,OAAO,UAAU;IAIrB,YAAY,MAAoB;QAHxB,YAAO,GAAuB,IAAI,CAAC;QAIzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAKO,gBAAgB;QACtB,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,gCAAgC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE5E,IAAI,QAAQ,EAAE;YACZ,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YAC1D,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC5C;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;YACtE,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC5C;IACH,CAAC;IAKD,KAAK,CAAC,UAAU;QACd,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAEjD,IAAI;YAEF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAGvC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE;gBAC/B,MAAM,IAAI,QAAQ,CAChB,sCAAsC,EACtC,mBAAmB,CACpB,CAAC;aACH;YAGD,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;SAE3D;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;YAChE,MAAM,KAAK,CAAC;SACb;IACH,CAAC;IAKD,KAAK,CAAC,QAAQ,CAAC,YAA8B,EAAE,WAAmB;QAChE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,MAAM,IAAI,QAAQ,CAAC,6BAA6B,EAAE,qBAAqB,CAAC,CAAC;SAC1E;QAED,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IAKD,QAAQ;QACN,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC;IAC/B,CAAC;IAKD,cAAc;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC/B,OAAO,IAAI,CAAC,OAAO,YAAY,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;IAC9E,CAAC;IAKD,OAAO;QACL,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;SACrB;IACH,CAAC;CACF"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { DRM_KEY_SYSTEMS, DRMError } from "./types/DRMTypes.js";
|
|
2
|
+
import { BunnyCDNDRMProvider } from "./BunnyCDNDRMProvider.js";
|
|
3
|
+
export class WidevineDRMHandler {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.mediaKeys = null;
|
|
6
|
+
this.bunnyProvider = null;
|
|
7
|
+
this.videoElement = null;
|
|
8
|
+
this.pendingLicenseRequests = new Map();
|
|
9
|
+
this.config = config;
|
|
10
|
+
if (config.provider === 'bunny' && config.bunny) {
|
|
11
|
+
this.bunnyProvider = new BunnyCDNDRMProvider(config.bunny);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
isSupported() {
|
|
15
|
+
return !!(typeof navigator.requestMediaKeySystemAccess === 'function' &&
|
|
16
|
+
typeof window.MediaKeySystemAccess !== 'undefined');
|
|
17
|
+
}
|
|
18
|
+
async initialize() {
|
|
19
|
+
if (!this.isSupported()) {
|
|
20
|
+
throw new DRMError('Widevine DRM is not supported in this browser', 'WIDEVINE_NOT_SUPPORTED');
|
|
21
|
+
}
|
|
22
|
+
console.log('[Widevine] Initializing DRM system...');
|
|
23
|
+
try {
|
|
24
|
+
const keySystemAccess = await navigator.requestMediaKeySystemAccess(DRM_KEY_SYSTEMS.WIDEVINE, this.getKeySystemConfiguration());
|
|
25
|
+
this.mediaKeys = await keySystemAccess.createMediaKeys();
|
|
26
|
+
console.log('[Widevine] MediaKeys created successfully');
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.error('[Widevine] Failed to initialize:', error);
|
|
30
|
+
throw new DRMError('Failed to initialize Widevine DRM', 'WIDEVINE_INIT_ERROR', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
getKeySystemConfiguration() {
|
|
34
|
+
return [{
|
|
35
|
+
initDataTypes: ['cenc', 'webm'],
|
|
36
|
+
audioCapabilities: [
|
|
37
|
+
{ contentType: 'audio/mp4; codecs="mp4a.40.2"' },
|
|
38
|
+
{ contentType: 'audio/webm; codecs="opus"' }
|
|
39
|
+
],
|
|
40
|
+
videoCapabilities: [
|
|
41
|
+
{ contentType: 'video/mp4; codecs="avc1.42E01E"' },
|
|
42
|
+
{ contentType: 'video/mp4; codecs="avc1.4D401E"' },
|
|
43
|
+
{ contentType: 'video/mp4; codecs="avc1.640028"' },
|
|
44
|
+
{ contentType: 'video/webm; codecs="vp9"' }
|
|
45
|
+
],
|
|
46
|
+
distinctiveIdentifier: 'optional',
|
|
47
|
+
persistentState: 'optional',
|
|
48
|
+
sessionTypes: ['temporary']
|
|
49
|
+
}];
|
|
50
|
+
}
|
|
51
|
+
async setupDRM(videoElement, manifestUrl) {
|
|
52
|
+
if (!this.mediaKeys) {
|
|
53
|
+
throw new DRMError('MediaKeys not initialized', 'MEDIAKEYS_NOT_INITIALIZED');
|
|
54
|
+
}
|
|
55
|
+
this.videoElement = videoElement;
|
|
56
|
+
await videoElement.setMediaKeys(this.mediaKeys);
|
|
57
|
+
console.log('[Widevine] MediaKeys attached to video element');
|
|
58
|
+
videoElement.addEventListener('encrypted', this.onEncrypted.bind(this));
|
|
59
|
+
}
|
|
60
|
+
async onEncrypted(event) {
|
|
61
|
+
console.log('[Widevine] Encrypted event received:', event.initDataType);
|
|
62
|
+
try {
|
|
63
|
+
if (!this.mediaKeys) {
|
|
64
|
+
throw new DRMError('MediaKeys not available', 'MEDIAKEYS_NOT_AVAILABLE');
|
|
65
|
+
}
|
|
66
|
+
const session = this.mediaKeys.createSession();
|
|
67
|
+
session.addEventListener('message', async (messageEvent) => {
|
|
68
|
+
await this.onMessage(session, messageEvent);
|
|
69
|
+
});
|
|
70
|
+
await session.generateRequest(event.initDataType, event.initData);
|
|
71
|
+
console.log('[Widevine] License request generated');
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('[Widevine] Failed to handle encrypted event:', error);
|
|
75
|
+
throw new DRMError('Failed to process encrypted media', 'ENCRYPTED_EVENT_ERROR', error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async onMessage(session, event) {
|
|
79
|
+
console.log('[Widevine] License request message:', event.messageType);
|
|
80
|
+
try {
|
|
81
|
+
const license = await this.requestLicense(event.message);
|
|
82
|
+
await session.update(license);
|
|
83
|
+
console.log('[Widevine] License applied successfully');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('[Widevine] Failed to process license:', error);
|
|
87
|
+
throw new DRMError('Failed to process DRM license', 'LICENSE_REQUEST_ERROR', error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async requestLicense(challenge) {
|
|
91
|
+
const licenseUrl = this.getLicenseUrl();
|
|
92
|
+
const headers = await this.getLicenseHeaders();
|
|
93
|
+
console.log('[Widevine] Requesting license from:', licenseUrl);
|
|
94
|
+
try {
|
|
95
|
+
const response = await fetch(licenseUrl, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers,
|
|
98
|
+
body: challenge
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`License request failed: ${response.status} ${response.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
const license = await response.arrayBuffer();
|
|
104
|
+
console.log('[Widevine] License received:', license.byteLength, 'bytes');
|
|
105
|
+
return license;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error('[Widevine] License request failed:', error);
|
|
109
|
+
throw new DRMError('Failed to retrieve DRM license', 'LICENSE_FETCH_ERROR', error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
getLicenseUrl() {
|
|
113
|
+
if (this.config.provider === 'bunny' && this.bunnyProvider) {
|
|
114
|
+
return this.bunnyProvider.getWidevineLicenseUrl();
|
|
115
|
+
}
|
|
116
|
+
else if (this.config.provider === 'generic' && this.config.generic) {
|
|
117
|
+
return this.config.generic.licenseUrl;
|
|
118
|
+
}
|
|
119
|
+
throw new DRMError('No license URL configured', 'NO_LICENSE_URL');
|
|
120
|
+
}
|
|
121
|
+
async getLicenseHeaders() {
|
|
122
|
+
if (this.config.provider === 'bunny' && this.bunnyProvider) {
|
|
123
|
+
return await this.bunnyProvider.getLicenseHeaders();
|
|
124
|
+
}
|
|
125
|
+
else if (this.config.provider === 'generic' && this.config.generic) {
|
|
126
|
+
return this.config.generic.headers || { 'Content-Type': 'application/octet-stream' };
|
|
127
|
+
}
|
|
128
|
+
return { 'Content-Type': 'application/octet-stream' };
|
|
129
|
+
}
|
|
130
|
+
async onLicenseRequest(licenseRequest) {
|
|
131
|
+
return await this.requestLicense(licenseRequest);
|
|
132
|
+
}
|
|
133
|
+
destroy() {
|
|
134
|
+
if (this.videoElement) {
|
|
135
|
+
this.videoElement.removeEventListener('encrypted', this.onEncrypted.bind(this));
|
|
136
|
+
this.videoElement = null;
|
|
137
|
+
}
|
|
138
|
+
this.mediaKeys = null;
|
|
139
|
+
this.bunnyProvider = null;
|
|
140
|
+
this.pendingLicenseRequests.clear();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=WidevineDRMHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidevineDRMHandler.js","sourceRoot":"","sources":["../../src/drm/WidevineDRMHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface DRMTokenProvider {
|
|
2
|
+
getManifestToken(): Promise<DRMToken | null>;
|
|
3
|
+
getSegmentToken(): Promise<DRMToken | null>;
|
|
4
|
+
getLicenseToken(): Promise<DRMToken | null>;
|
|
5
|
+
shouldRenewToken(token: DRMToken): boolean;
|
|
6
|
+
renewToken(token: DRMToken): Promise<DRMToken>;
|
|
7
|
+
}
|
|
8
|
+
export interface DRMToken {
|
|
9
|
+
token: string;
|
|
10
|
+
expires: number;
|
|
11
|
+
tokenVer?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface BunnyCDNDRMConfig {
|
|
14
|
+
libraryId: string;
|
|
15
|
+
videoId: string;
|
|
16
|
+
pullZoneUrl: string;
|
|
17
|
+
tokenProvider: DRMTokenProvider;
|
|
18
|
+
certificateUrl?: string;
|
|
19
|
+
licenseUrl?: string;
|
|
20
|
+
enableReferrerProtection?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface GenericDRMConfig {
|
|
23
|
+
type: 'widevine' | 'fairplay';
|
|
24
|
+
licenseUrl: string;
|
|
25
|
+
certificateUrl?: string;
|
|
26
|
+
headers?: Record<string, string>;
|
|
27
|
+
certificateHeaders?: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
export interface WebDRMConfig {
|
|
30
|
+
provider: 'bunny' | 'generic';
|
|
31
|
+
bunny?: BunnyCDNDRMConfig;
|
|
32
|
+
generic?: GenericDRMConfig;
|
|
33
|
+
}
|
|
34
|
+
export interface IDRMHandler {
|
|
35
|
+
initialize(): Promise<void>;
|
|
36
|
+
setupDRM(videoElement: HTMLVideoElement, manifestUrl: string): Promise<void>;
|
|
37
|
+
onLicenseRequest(licenseRequest: ArrayBuffer): Promise<ArrayBuffer>;
|
|
38
|
+
destroy(): void;
|
|
39
|
+
isSupported(): boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare const DRM_KEY_SYSTEMS: {
|
|
42
|
+
readonly WIDEVINE: "com.widevine.alpha";
|
|
43
|
+
readonly FAIRPLAY: "com.apple.fps.1_0";
|
|
44
|
+
readonly PLAYREADY: "com.microsoft.playready";
|
|
45
|
+
readonly CLEARKEY: "org.w3.clearkey";
|
|
46
|
+
};
|
|
47
|
+
export declare class DRMError extends Error {
|
|
48
|
+
code: string;
|
|
49
|
+
details?: any;
|
|
50
|
+
constructor(message: string, code: string, details?: any);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=DRMTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DRMTypes.d.ts","sourceRoot":"","sources":["../../../src/drm/types/DRMTypes.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAE/B,gBAAgB,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAG7C,eAAe,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAG5C,eAAe,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAG5C,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAG3C,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD;AAGD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,gBAAgB,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAGD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAGD,MAAM,WAAW,YAAY;IAE3B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAG9B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAGD,MAAM,WAAW,WAAW;IAE1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAG5B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7E,gBAAgB,CAAC,cAAc,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAGpE,OAAO,IAAI,IAAI,CAAC;IAGhB,WAAW,IAAI,OAAO,CAAC;CACxB;AAGD,eAAO,MAAM,eAAe;;;;;CAKlB,CAAC;AAGX,qBAAa,QAAS,SAAQ,KAAK;IAGxB,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC;gBAFf,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,KAAK;CAKvB"}
|