unified-video-framework 1.4.411 → 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.
- package/package.json +1 -1
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +62 -6
- 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 +20 -0
- package/packages/web/dist/drm/DRMManager.d.ts.map +1 -0
- package/packages/web/dist/drm/DRMManager.js +126 -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/index.d.ts +15 -0
- package/packages/web/dist/drm/index.d.ts.map +1 -0
- package/packages/web/dist/drm/index.js +13 -0
- package/packages/web/dist/drm/index.js.map +1 -0
- package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts +19 -0
- package/packages/web/dist/drm/providers/BunnyNetProvider.d.ts.map +1 -0
- package/packages/web/dist/drm/providers/BunnyNetProvider.js +112 -0
- package/packages/web/dist/drm/providers/BunnyNetProvider.js.map +1 -0
- package/packages/web/dist/drm/providers/GenericProvider.d.ts +30 -0
- package/packages/web/dist/drm/providers/GenericProvider.d.ts.map +1 -0
- package/packages/web/dist/drm/providers/GenericProvider.js +102 -0
- package/packages/web/dist/drm/providers/GenericProvider.js.map +1 -0
- package/packages/web/dist/drm/systems/BaseDRM.d.ts +18 -0
- package/packages/web/dist/drm/systems/BaseDRM.d.ts.map +1 -0
- package/packages/web/dist/drm/systems/BaseDRM.js +29 -0
- package/packages/web/dist/drm/systems/BaseDRM.js.map +1 -0
- package/packages/web/dist/drm/systems/FairPlayDRM.d.ts +32 -0
- package/packages/web/dist/drm/systems/FairPlayDRM.d.ts.map +1 -0
- package/packages/web/dist/drm/systems/FairPlayDRM.js +198 -0
- package/packages/web/dist/drm/systems/FairPlayDRM.js.map +1 -0
- package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts +9 -0
- package/packages/web/dist/drm/systems/PlayReadyDRM.d.ts.map +1 -0
- package/packages/web/dist/drm/systems/PlayReadyDRM.js +92 -0
- package/packages/web/dist/drm/systems/PlayReadyDRM.js.map +1 -0
- package/packages/web/dist/drm/systems/WidevineDRM.d.ts +9 -0
- package/packages/web/dist/drm/systems/WidevineDRM.d.ts.map +1 -0
- package/packages/web/dist/drm/systems/WidevineDRM.js +73 -0
- package/packages/web/dist/drm/systems/WidevineDRM.js.map +1 -0
- package/packages/web/dist/drm/types/BunnyNetTypes.d.ts +20 -0
- package/packages/web/dist/drm/types/BunnyNetTypes.d.ts.map +1 -0
- package/packages/web/dist/drm/types/BunnyNetTypes.js +8 -0
- package/packages/web/dist/drm/types/BunnyNetTypes.js.map +1 -0
- package/packages/web/dist/drm/types/DRMTypes.d.ts +59 -0
- package/packages/web/dist/drm/types/DRMTypes.d.ts.map +1 -0
- package/packages/web/dist/drm/types/DRMTypes.js +21 -0
- package/packages/web/dist/drm/types/DRMTypes.js.map +1 -0
- package/packages/web/dist/drm/utils/BrowserDetector.d.ts +20 -0
- package/packages/web/dist/drm/utils/BrowserDetector.d.ts.map +1 -0
- package/packages/web/dist/drm/utils/BrowserDetector.js +168 -0
- package/packages/web/dist/drm/utils/BrowserDetector.js.map +1 -0
- package/packages/web/dist/drm/utils/CertificateManager.d.ts +15 -0
- package/packages/web/dist/drm/utils/CertificateManager.d.ts.map +1 -0
- package/packages/web/dist/drm/utils/CertificateManager.js +46 -0
- package/packages/web/dist/drm/utils/CertificateManager.js.map +1 -0
- package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts +7 -0
- package/packages/web/dist/drm/utils/DRMErrorHandler.d.ts.map +1 -0
- package/packages/web/dist/drm/utils/DRMErrorHandler.js +49 -0
- package/packages/web/dist/drm/utils/DRMErrorHandler.js.map +1 -0
- package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts +15 -0
- package/packages/web/dist/drm/utils/LicenseRequestHandler.d.ts.map +1 -0
- package/packages/web/dist/drm/utils/LicenseRequestHandler.js +110 -0
- package/packages/web/dist/drm/utils/LicenseRequestHandler.js.map +1 -0
- package/packages/web/src/WebPlayer.ts +80 -12
- package/packages/web/src/drm/DRMManager.ts +213 -0
- package/packages/web/src/drm/index.ts +37 -0
- package/packages/web/src/drm/providers/BunnyNetProvider.ts +170 -0
- package/packages/web/src/drm/providers/GenericProvider.ts +148 -0
- package/packages/web/src/drm/systems/BaseDRM.ts +68 -0
- package/packages/web/src/drm/systems/FairPlayDRM.ts +305 -0
- package/packages/web/src/drm/systems/PlayReadyDRM.ts +131 -0
- package/packages/web/src/drm/systems/WidevineDRM.ts +105 -0
- package/packages/web/src/drm/types/BunnyNetTypes.ts +35 -0
- package/packages/web/src/drm/types/DRMTypes.ts +91 -0
- package/packages/web/src/drm/utils/BrowserDetector.ts +232 -0
- package/packages/web/src/drm/utils/CertificateManager.ts +86 -0
- package/packages/web/src/drm/utils/DRMErrorHandler.ts +84 -0
- package/packages/web/src/drm/utils/LicenseRequestHandler.ts +180 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DRMErrorHandler.d.ts","sourceRoot":"","sources":["../../../src/drm/utils/DRMErrorHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3D,qBAAa,eAAe;IAI1B,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAwCtD,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;IAiBnD,MAAM,CAAC,WAAW,CAChB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,OAAc,EACrB,OAAO,CAAC,EAAE,GAAG,EACb,WAAW,CAAC,EAAE,GAAG,GAChB,QAAQ;CASZ"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { DRMErrorCode } from "../types/DRMTypes.js";
|
|
2
|
+
export class DRMErrorHandler {
|
|
3
|
+
static getUserFriendlyMessage(error) {
|
|
4
|
+
switch (error.code) {
|
|
5
|
+
case DRMErrorCode.UNSUPPORTED_BROWSER:
|
|
6
|
+
return 'DRM is not supported in this browser. Please use Chrome, Safari, Firefox, or Edge.';
|
|
7
|
+
case DRMErrorCode.CERTIFICATE_LOAD_FAILED:
|
|
8
|
+
return 'Failed to load DRM certificate. Please check your internet connection.';
|
|
9
|
+
case DRMErrorCode.LICENSE_REQUEST_FAILED:
|
|
10
|
+
return 'Failed to obtain content license. Please check your internet connection and try again.';
|
|
11
|
+
case DRMErrorCode.KEY_SYSTEM_ACCESS_DENIED:
|
|
12
|
+
return 'Access to DRM system was denied. Please ensure DRM is enabled in your browser settings.';
|
|
13
|
+
case DRMErrorCode.MEDIA_KEYS_CREATION_FAILED:
|
|
14
|
+
return 'Failed to initialize DRM protection. Please try refreshing the page.';
|
|
15
|
+
case DRMErrorCode.SESSION_CREATION_FAILED:
|
|
16
|
+
return 'Failed to create secure playback session. Please try again.';
|
|
17
|
+
case DRMErrorCode.LICENSE_INVALID:
|
|
18
|
+
return 'Invalid or expired content license. You may not have permission to view this content.';
|
|
19
|
+
case DRMErrorCode.CONFIGURATION_ERROR:
|
|
20
|
+
return 'DRM configuration error. Please contact support.';
|
|
21
|
+
case DRMErrorCode.NETWORK_ERROR:
|
|
22
|
+
return 'Network error while loading protected content. Please check your internet connection.';
|
|
23
|
+
case DRMErrorCode.TIMEOUT:
|
|
24
|
+
return 'DRM initialization timed out. Please try again.';
|
|
25
|
+
default:
|
|
26
|
+
return 'An error occurred while loading protected content. Please try again.';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
static getTechnicalMessage(error) {
|
|
30
|
+
let message = `[${error.code}] ${error.message}`;
|
|
31
|
+
if (error.details) {
|
|
32
|
+
message += `\nDetails: ${JSON.stringify(error.details, null, 2)}`;
|
|
33
|
+
}
|
|
34
|
+
if (error.systemError) {
|
|
35
|
+
message += `\nSystem Error: ${error.systemError}`;
|
|
36
|
+
}
|
|
37
|
+
return message;
|
|
38
|
+
}
|
|
39
|
+
static createError(code, message, fatal = true, details, systemError) {
|
|
40
|
+
return {
|
|
41
|
+
code,
|
|
42
|
+
message,
|
|
43
|
+
fatal,
|
|
44
|
+
details,
|
|
45
|
+
systemError,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=DRMErrorHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DRMErrorHandler.js","sourceRoot":"","sources":["../../../src/drm/utils/DRMErrorHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAY,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3D,MAAM,OAAO,eAAe;IAI1B,MAAM,CAAC,sBAAsB,CAAC,KAAe;QAC3C,QAAQ,KAAK,CAAC,IAAI,EAAE;YAClB,KAAK,YAAY,CAAC,mBAAmB;gBACnC,OAAO,oFAAoF,CAAC;YAE9F,KAAK,YAAY,CAAC,uBAAuB;gBACvC,OAAO,wEAAwE,CAAC;YAElF,KAAK,YAAY,CAAC,sBAAsB;gBACtC,OAAO,wFAAwF,CAAC;YAElG,KAAK,YAAY,CAAC,wBAAwB;gBACxC,OAAO,yFAAyF,CAAC;YAEnG,KAAK,YAAY,CAAC,0BAA0B;gBAC1C,OAAO,sEAAsE,CAAC;YAEhF,KAAK,YAAY,CAAC,uBAAuB;gBACvC,OAAO,6DAA6D,CAAC;YAEvE,KAAK,YAAY,CAAC,eAAe;gBAC/B,OAAO,uFAAuF,CAAC;YAEjG,KAAK,YAAY,CAAC,mBAAmB;gBACnC,OAAO,kDAAkD,CAAC;YAE5D,KAAK,YAAY,CAAC,aAAa;gBAC7B,OAAO,uFAAuF,CAAC;YAEjG,KAAK,YAAY,CAAC,OAAO;gBACvB,OAAO,iDAAiD,CAAC;YAE3D;gBACE,OAAO,sEAAsE,CAAC;SACjF;IACH,CAAC;IAKD,MAAM,CAAC,mBAAmB,CAAC,KAAe;QACxC,IAAI,OAAO,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QAEjD,IAAI,KAAK,CAAC,OAAO,EAAE;YACjB,OAAO,IAAI,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE;QAED,IAAI,KAAK,CAAC,WAAW,EAAE;YACrB,OAAO,IAAI,mBAAmB,KAAK,CAAC,WAAW,EAAE,CAAC;SACnD;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAKD,MAAM,CAAC,WAAW,CAChB,IAAkB,EAClB,OAAe,EACf,QAAiB,IAAI,EACrB,OAAa,EACb,WAAiB;QAEjB,OAAO;YACL,IAAI;YACJ,OAAO;YACP,KAAK;YACL,OAAO;YACP,WAAW;SACZ,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ExtendedDRMConfig, LicenseRequest, LicenseResponse } from '../types/DRMTypes';
|
|
2
|
+
export declare class LicenseRequestHandler {
|
|
3
|
+
private config;
|
|
4
|
+
private debug;
|
|
5
|
+
constructor(config: ExtendedDRMConfig, debug?: boolean);
|
|
6
|
+
requestLicense(request: LicenseRequest): Promise<LicenseResponse>;
|
|
7
|
+
private makeRequest;
|
|
8
|
+
private isFatalError;
|
|
9
|
+
private textToArrayBuffer;
|
|
10
|
+
private base64ToArrayBuffer;
|
|
11
|
+
private delay;
|
|
12
|
+
private createError;
|
|
13
|
+
private log;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=LicenseRequestHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LicenseRequestHandler.d.ts","sourceRoot":"","sources":["../../../src/drm/utils/LicenseRequestHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAErG,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,KAAK,CAAU;gBAEX,MAAM,EAAE,iBAAiB,EAAE,KAAK,GAAE,OAAe;IAQvD,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;YAqCzD,WAAW;IAgEzB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,GAAG;CAKZ"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { DRMErrorCode } from "../types/DRMTypes.js";
|
|
2
|
+
export class LicenseRequestHandler {
|
|
3
|
+
constructor(config, debug = false) {
|
|
4
|
+
this.config = config;
|
|
5
|
+
this.debug = debug;
|
|
6
|
+
}
|
|
7
|
+
async requestLicense(request) {
|
|
8
|
+
const maxRetries = this.config.retryConfig?.maxRetries || 3;
|
|
9
|
+
const retryDelay = this.config.retryConfig?.retryDelay || 1000;
|
|
10
|
+
let lastError;
|
|
11
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
12
|
+
try {
|
|
13
|
+
if (attempt > 0) {
|
|
14
|
+
this.log(`Retry attempt ${attempt}/${maxRetries}`);
|
|
15
|
+
await this.delay(retryDelay * attempt);
|
|
16
|
+
}
|
|
17
|
+
const response = await this.makeRequest(request);
|
|
18
|
+
return response;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
lastError = error;
|
|
22
|
+
this.log(`License request failed (attempt ${attempt + 1}/${maxRetries + 1}):`, error);
|
|
23
|
+
if (this.isFatalError(error)) {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
throw this.createError(DRMErrorCode.LICENSE_REQUEST_FAILED, `Failed to request license after ${maxRetries + 1} attempts`, lastError);
|
|
29
|
+
}
|
|
30
|
+
async makeRequest(request) {
|
|
31
|
+
this.log('Requesting license from:', request.url);
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(request.url, {
|
|
34
|
+
method: request.method,
|
|
35
|
+
headers: request.headers,
|
|
36
|
+
body: request.body,
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
throw this.createError(DRMErrorCode.LICENSE_REQUEST_FAILED, `License server returned ${response.status}: ${response.statusText}`, { status: response.status, statusText: response.statusText });
|
|
40
|
+
}
|
|
41
|
+
let license;
|
|
42
|
+
if (request.responseType === 'arraybuffer') {
|
|
43
|
+
license = await response.arrayBuffer();
|
|
44
|
+
}
|
|
45
|
+
else if (request.responseType === 'text') {
|
|
46
|
+
const text = await response.text();
|
|
47
|
+
license = this.textToArrayBuffer(text);
|
|
48
|
+
}
|
|
49
|
+
else if (request.responseType === 'json') {
|
|
50
|
+
const json = await response.json();
|
|
51
|
+
if (json.license) {
|
|
52
|
+
license = this.base64ToArrayBuffer(json.license);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
throw this.createError(DRMErrorCode.LICENSE_INVALID, 'License response does not contain license field', json);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
license = await response.arrayBuffer();
|
|
60
|
+
}
|
|
61
|
+
this.log('License received, size:', license.byteLength, 'bytes');
|
|
62
|
+
return {
|
|
63
|
+
license,
|
|
64
|
+
metadata: response.headers,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error.code && error.code.startsWith('DRM_')) {
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
throw this.createError(DRMErrorCode.NETWORK_ERROR, `Network error requesting license: ${error.message}`, error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
isFatalError(error) {
|
|
75
|
+
if (error.details?.status === 401 || error.details?.status === 403) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
if (error.code === DRMErrorCode.LICENSE_INVALID) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
textToArrayBuffer(text) {
|
|
84
|
+
const encoder = new TextEncoder();
|
|
85
|
+
return encoder.encode(text).buffer;
|
|
86
|
+
}
|
|
87
|
+
base64ToArrayBuffer(base64) {
|
|
88
|
+
const binaryString = atob(base64);
|
|
89
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
90
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
91
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
92
|
+
}
|
|
93
|
+
return bytes.buffer;
|
|
94
|
+
}
|
|
95
|
+
delay(ms) {
|
|
96
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
97
|
+
}
|
|
98
|
+
createError(code, message, details) {
|
|
99
|
+
const error = new Error(message);
|
|
100
|
+
error.code = code;
|
|
101
|
+
error.details = details;
|
|
102
|
+
return error;
|
|
103
|
+
}
|
|
104
|
+
log(...args) {
|
|
105
|
+
if (this.debug) {
|
|
106
|
+
console.log('[LicenseRequestHandler]', ...args);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=LicenseRequestHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LicenseRequestHandler.js","sourceRoot":"","sources":["../../../src/drm/utils/LicenseRequestHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1015,6 +1015,39 @@ export class WebPlayer extends BasePlayer {
|
|
|
1015
1015
|
this.debugLog(`⏩ HLS startPosition set to: ${this.config.startTime}s (continue watching)`);
|
|
1016
1016
|
}
|
|
1017
1017
|
|
|
1018
|
+
// Add DRM configuration if present
|
|
1019
|
+
if (this.source?.drm) {
|
|
1020
|
+
try {
|
|
1021
|
+
const { DRMManager } = await import('./drm/DRMManager');
|
|
1022
|
+
const drmManager = new DRMManager(this.video!, this.source.drm as any, this.config.debug);
|
|
1023
|
+
|
|
1024
|
+
this.debugLog('Initializing DRM for HLS...');
|
|
1025
|
+
const initResult = await drmManager.initialize();
|
|
1026
|
+
|
|
1027
|
+
if (!initResult.success) {
|
|
1028
|
+
throw initResult.error || new Error('DRM initialization failed');
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Merge DRM config into HLS config
|
|
1032
|
+
const drmConfig = drmManager.getHLSConfig();
|
|
1033
|
+
Object.assign(hlsConfig, drmConfig);
|
|
1034
|
+
|
|
1035
|
+
this.debugLog(`✅ HLS DRM configured: ${initResult.drmType} (${initResult.keySystem})`);
|
|
1036
|
+
|
|
1037
|
+
// Store for cleanup
|
|
1038
|
+
(this as any)._drmManager = drmManager;
|
|
1039
|
+
} catch (error: any) {
|
|
1040
|
+
this.handleError({
|
|
1041
|
+
code: 'DRM_ERROR',
|
|
1042
|
+
message: `Failed to initialize DRM: ${error.message || error}`,
|
|
1043
|
+
type: 'drm',
|
|
1044
|
+
fatal: true,
|
|
1045
|
+
details: error
|
|
1046
|
+
});
|
|
1047
|
+
throw error;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1018
1051
|
this.hls = new window.Hls(hlsConfig);
|
|
1019
1052
|
|
|
1020
1053
|
this.hls.loadSource(url);
|
|
@@ -1104,6 +1137,39 @@ export class WebPlayer extends BasePlayer {
|
|
|
1104
1137
|
// The seek will be applied at canplay event when stream is ready
|
|
1105
1138
|
}
|
|
1106
1139
|
|
|
1140
|
+
// Add DRM configuration if present
|
|
1141
|
+
if (this.source?.drm) {
|
|
1142
|
+
try {
|
|
1143
|
+
const { DRMManager } = await import('./drm/DRMManager');
|
|
1144
|
+
const drmManager = new DRMManager(this.video!, this.source.drm as any, this.config.debug);
|
|
1145
|
+
|
|
1146
|
+
this.debugLog('Initializing DRM for DASH...');
|
|
1147
|
+
const initResult = await drmManager.initialize();
|
|
1148
|
+
|
|
1149
|
+
if (!initResult.success) {
|
|
1150
|
+
throw initResult.error || new Error('DRM initialization failed');
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// Set protection data for dash.js
|
|
1154
|
+
const protectionData = drmManager.getDashProtectionData();
|
|
1155
|
+
this.dash.setProtectionData(protectionData);
|
|
1156
|
+
|
|
1157
|
+
this.debugLog(`✅ DASH DRM configured: ${initResult.drmType} (${initResult.keySystem})`);
|
|
1158
|
+
|
|
1159
|
+
// Store for cleanup
|
|
1160
|
+
(this as any)._drmManager = drmManager;
|
|
1161
|
+
} catch (error: any) {
|
|
1162
|
+
this.handleError({
|
|
1163
|
+
code: 'DRM_ERROR',
|
|
1164
|
+
message: `Failed to initialize DRM: ${error.message || error}`,
|
|
1165
|
+
type: 'drm',
|
|
1166
|
+
fatal: true,
|
|
1167
|
+
details: error
|
|
1168
|
+
});
|
|
1169
|
+
throw error;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1107
1173
|
this.dash.initialize(this.video, url, this.config.autoPlay);
|
|
1108
1174
|
|
|
1109
1175
|
// Configure DASH settings
|
|
@@ -8590,21 +8656,12 @@ export class WebPlayer extends BasePlayer {
|
|
|
8590
8656
|
|
|
8591
8657
|
this.lastDuration = duration;
|
|
8592
8658
|
|
|
8593
|
-
// Check if this is a live stream
|
|
8594
|
-
|
|
8595
|
-
// 2. Duration = Infinity (pure live)
|
|
8596
|
-
// 3. Previously detected as live (duration increased at some point)
|
|
8597
|
-
// 4. Near live edge: duration - currentTime < 15 seconds (live with DVR)
|
|
8598
|
-
const isLiveStream = this.config.isLive === true ||
|
|
8599
|
-
!isFinite(duration) ||
|
|
8600
|
-
this.isDetectedAsLive ||
|
|
8601
|
-
(duration > 0 && (duration - current) < 15);
|
|
8602
|
-
|
|
8603
|
-
if (isLiveStream) {
|
|
8659
|
+
// Check if this is a live stream - only use isLive prop
|
|
8660
|
+
if (this.config.isLive === true) {
|
|
8604
8661
|
// Show LIVE indicator for live streams
|
|
8605
8662
|
timeDisplay.innerHTML = '<span class="uvf-live-dot"></span><span class="uvf-live-text">LIVE</span>';
|
|
8606
8663
|
timeDisplay.classList.add('uvf-is-live');
|
|
8607
|
-
this.debugLog('Time display: LIVE stream
|
|
8664
|
+
this.debugLog('Time display: LIVE stream (isLive=true)');
|
|
8608
8665
|
} else {
|
|
8609
8666
|
// Show normal time display for VOD
|
|
8610
8667
|
const currentFormatted = this.formatTime(current);
|
|
@@ -11330,6 +11387,17 @@ export class WebPlayer extends BasePlayer {
|
|
|
11330
11387
|
}
|
|
11331
11388
|
|
|
11332
11389
|
private async cleanup(): Promise<void> {
|
|
11390
|
+
// Cleanup DRM resources
|
|
11391
|
+
if ((this as any)._drmManager) {
|
|
11392
|
+
try {
|
|
11393
|
+
this.debugLog('Cleaning up DRM resources');
|
|
11394
|
+
await (this as any)._drmManager.destroy();
|
|
11395
|
+
(this as any)._drmManager = null;
|
|
11396
|
+
} catch (error) {
|
|
11397
|
+
this.debugLog('Error cleaning up DRM:', error);
|
|
11398
|
+
}
|
|
11399
|
+
}
|
|
11400
|
+
|
|
11333
11401
|
if (this.hls) {
|
|
11334
11402
|
this.hls.destroy();
|
|
11335
11403
|
this.hls = null;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DRM Manager
|
|
3
|
+
* Main orchestrator for all DRM systems
|
|
4
|
+
* Provides a unified interface for HLS.js, dash.js, and native playback
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { DRMType, DRMConfig } from '@unified-video/core';
|
|
8
|
+
import { ExtendedDRMConfig, DRMInitResult, DRMError, DRMErrorCode, DRMCapabilities } from './types/DRMTypes';
|
|
9
|
+
import { BrowserDetector } from './utils/BrowserDetector';
|
|
10
|
+
import { BunnyNetProvider } from './providers/BunnyNetProvider';
|
|
11
|
+
import { WidevineDRM } from './systems/WidevineDRM';
|
|
12
|
+
import { FairPlayDRM } from './systems/FairPlayDRM';
|
|
13
|
+
import { PlayReadyDRM } from './systems/PlayReadyDRM';
|
|
14
|
+
import { BaseDRM } from './systems/BaseDRM';
|
|
15
|
+
import { DRMErrorHandler } from './utils/DRMErrorHandler';
|
|
16
|
+
|
|
17
|
+
export class DRMManager {
|
|
18
|
+
private videoElement: HTMLVideoElement;
|
|
19
|
+
private config: ExtendedDRMConfig;
|
|
20
|
+
private drmSystem: BaseDRM | null = null;
|
|
21
|
+
private browserDetector: BrowserDetector;
|
|
22
|
+
private debug: boolean = false;
|
|
23
|
+
|
|
24
|
+
constructor(videoElement: HTMLVideoElement, config: DRMConfig, debug: boolean = false) {
|
|
25
|
+
this.videoElement = videoElement;
|
|
26
|
+
this.config = this.normalizeConfig(config);
|
|
27
|
+
this.debug = debug || this.config.debug || false;
|
|
28
|
+
this.browserDetector = BrowserDetector.getInstance();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Initialize DRM system based on browser capabilities
|
|
33
|
+
*/
|
|
34
|
+
async initialize(): Promise<DRMInitResult> {
|
|
35
|
+
try {
|
|
36
|
+
this.log('Initializing DRM system...');
|
|
37
|
+
|
|
38
|
+
// Detect browser capabilities
|
|
39
|
+
const capabilities = await this.browserDetector.detectCapabilities();
|
|
40
|
+
this.log('Browser DRM capabilities:', capabilities);
|
|
41
|
+
|
|
42
|
+
// Determine which DRM system to use
|
|
43
|
+
const drmType = this.selectDRMType(capabilities);
|
|
44
|
+
if (!drmType) {
|
|
45
|
+
const browserName = this.browserDetector.getBrowserName();
|
|
46
|
+
throw DRMErrorHandler.createError(
|
|
47
|
+
DRMErrorCode.UNSUPPORTED_BROWSER,
|
|
48
|
+
`No supported DRM system found in ${browserName}. Please use Chrome, Safari, Firefox, or Edge.`,
|
|
49
|
+
true,
|
|
50
|
+
{ browser: browserName, capabilities }
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.log(`Selected DRM type: ${drmType}`);
|
|
55
|
+
|
|
56
|
+
// Create appropriate DRM system
|
|
57
|
+
this.drmSystem = this.createDRMSystem(drmType);
|
|
58
|
+
|
|
59
|
+
// Initialize the DRM system
|
|
60
|
+
await this.drmSystem.initialize();
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
success: true,
|
|
64
|
+
drmType,
|
|
65
|
+
keySystem: this.drmSystem.getKeySystem(),
|
|
66
|
+
};
|
|
67
|
+
} catch (error: any) {
|
|
68
|
+
this.log('DRM initialization failed:', error);
|
|
69
|
+
|
|
70
|
+
const drmError = error.code && error.code.startsWith('DRM_')
|
|
71
|
+
? error
|
|
72
|
+
: DRMErrorHandler.createError(
|
|
73
|
+
DRMErrorCode.CONFIGURATION_ERROR,
|
|
74
|
+
error.message || 'DRM initialization failed',
|
|
75
|
+
true,
|
|
76
|
+
error
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
drmType: this.config.type,
|
|
82
|
+
keySystem: '',
|
|
83
|
+
error: drmError,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get HLS.js configuration for DRM
|
|
90
|
+
*/
|
|
91
|
+
getHLSConfig(): any {
|
|
92
|
+
if (!this.drmSystem) {
|
|
93
|
+
throw new Error('DRM system not initialized. Call initialize() first.');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return this.drmSystem.getHLSConfig();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get dash.js protection data for DRM
|
|
101
|
+
*/
|
|
102
|
+
getDashProtectionData(): any {
|
|
103
|
+
if (!this.drmSystem) {
|
|
104
|
+
throw new Error('DRM system not initialized. Call initialize() first.');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return this.drmSystem.getDashProtectionData();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Cleanup DRM resources
|
|
112
|
+
*/
|
|
113
|
+
async destroy(): Promise<void> {
|
|
114
|
+
if (this.drmSystem) {
|
|
115
|
+
this.log('Destroying DRM system');
|
|
116
|
+
await this.drmSystem.destroy();
|
|
117
|
+
this.drmSystem = null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Select appropriate DRM type based on config and capabilities
|
|
123
|
+
*/
|
|
124
|
+
private selectDRMType(capabilities: DRMCapabilities): DRMType | null {
|
|
125
|
+
// If config specifies a type and it's supported, use it
|
|
126
|
+
if (this.config.type) {
|
|
127
|
+
const typeSupported = this.isDRMTypeSupported(this.config.type, capabilities);
|
|
128
|
+
if (typeSupported) {
|
|
129
|
+
return this.config.type;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
this.log(`Requested DRM type ${this.config.type} not supported, falling back to browser default`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Otherwise, use browser's preferred DRM system
|
|
136
|
+
return capabilities.supportedType;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Check if specific DRM type is supported
|
|
141
|
+
*/
|
|
142
|
+
private isDRMTypeSupported(drmType: DRMType, capabilities: DRMCapabilities): boolean {
|
|
143
|
+
switch (drmType) {
|
|
144
|
+
case DRMType.WIDEVINE:
|
|
145
|
+
return capabilities.widevine;
|
|
146
|
+
case DRMType.FAIRPLAY:
|
|
147
|
+
return capabilities.fairplay;
|
|
148
|
+
case DRMType.PLAYREADY:
|
|
149
|
+
return capabilities.playready;
|
|
150
|
+
default:
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create DRM system instance
|
|
157
|
+
*/
|
|
158
|
+
private createDRMSystem(drmType: DRMType): BaseDRM {
|
|
159
|
+
switch (drmType) {
|
|
160
|
+
case DRMType.FAIRPLAY:
|
|
161
|
+
return new FairPlayDRM(this.videoElement, this.config, this.debug);
|
|
162
|
+
|
|
163
|
+
case DRMType.WIDEVINE:
|
|
164
|
+
return new WidevineDRM(this.videoElement, this.config, this.debug);
|
|
165
|
+
|
|
166
|
+
case DRMType.PLAYREADY:
|
|
167
|
+
return new PlayReadyDRM(this.videoElement, this.config, this.debug);
|
|
168
|
+
|
|
169
|
+
default:
|
|
170
|
+
throw DRMErrorHandler.createError(
|
|
171
|
+
DRMErrorCode.CONFIGURATION_ERROR,
|
|
172
|
+
`Unsupported DRM type: ${drmType}`,
|
|
173
|
+
true
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Normalize and enrich DRM config
|
|
180
|
+
*/
|
|
181
|
+
private normalizeConfig(config: DRMConfig): ExtendedDRMConfig {
|
|
182
|
+
const extended = { ...config } as ExtendedDRMConfig;
|
|
183
|
+
|
|
184
|
+
// Auto-detect Bunny.net and enhance config
|
|
185
|
+
if (BunnyNetProvider.isBunnyNetConfig(config)) {
|
|
186
|
+
extended.provider = 'bunny';
|
|
187
|
+
|
|
188
|
+
// Extract IDs if available
|
|
189
|
+
const ids = BunnyNetProvider.extractIdsFromUrl(config.licenseUrl);
|
|
190
|
+
if (ids.libraryId) extended.libraryId = ids.libraryId;
|
|
191
|
+
if (ids.videoId) extended.videoId = ids.videoId;
|
|
192
|
+
|
|
193
|
+
this.log('Detected Bunny.net DRM configuration');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Set defaults
|
|
197
|
+
extended.retryConfig = extended.retryConfig || {
|
|
198
|
+
maxRetries: 3,
|
|
199
|
+
retryDelay: 1000,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return extended;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Debug logging
|
|
207
|
+
*/
|
|
208
|
+
private log(...args: any[]): void {
|
|
209
|
+
if (this.debug) {
|
|
210
|
+
console.log('[DRMManager]', ...args);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DRM System - Public API
|
|
3
|
+
* Exports for the DRM system
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Main DRM Manager
|
|
7
|
+
export { DRMManager } from './DRMManager';
|
|
8
|
+
|
|
9
|
+
// Providers
|
|
10
|
+
export { BunnyNetProvider } from './providers/BunnyNetProvider';
|
|
11
|
+
export { GenericProvider } from './providers/GenericProvider';
|
|
12
|
+
|
|
13
|
+
// Types
|
|
14
|
+
export type {
|
|
15
|
+
ExtendedDRMConfig,
|
|
16
|
+
DRMCapabilities,
|
|
17
|
+
LicenseRequest,
|
|
18
|
+
LicenseResponse,
|
|
19
|
+
DRMInitResult,
|
|
20
|
+
DRMError,
|
|
21
|
+
} from './types/DRMTypes';
|
|
22
|
+
|
|
23
|
+
export { DRMErrorCode, KEY_SYSTEMS } from './types/DRMTypes';
|
|
24
|
+
|
|
25
|
+
export type { BunnyNetConfig, BunnyNetEndpoints } from './types/BunnyNetTypes';
|
|
26
|
+
export { BUNNY_NET_BASE_URL, BUNNY_NET_ENDPOINTS } from './types/BunnyNetTypes';
|
|
27
|
+
|
|
28
|
+
// Utilities
|
|
29
|
+
export { BrowserDetector } from './utils/BrowserDetector';
|
|
30
|
+
export { DRMErrorHandler } from './utils/DRMErrorHandler';
|
|
31
|
+
export { CertificateManager } from './utils/CertificateManager';
|
|
32
|
+
|
|
33
|
+
// DRM Systems (for advanced usage)
|
|
34
|
+
export { BaseDRM } from './systems/BaseDRM';
|
|
35
|
+
export { WidevineDRM } from './systems/WidevineDRM';
|
|
36
|
+
export { FairPlayDRM } from './systems/FairPlayDRM';
|
|
37
|
+
export { PlayReadyDRM } from './systems/PlayReadyDRM';
|