unified-video-framework 1.4.431 → 1.4.432
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/version.d.ts +1 -1
- package/packages/core/dist/version.js +1 -1
- package/packages/core/src/version.ts +1 -1
- 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 +95 -0
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/src/WebPlayer.ts +125 -0
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
} from './chapters/types/ChapterTypes';
|
|
23
23
|
import type { FlashNewsTickerConfig } from './react/types/FlashNewsTickerTypes';
|
|
24
24
|
import YouTubeExtractor from './utils/YouTubeExtractor';
|
|
25
|
+
import { DRMManager, DRMErrorHandler } from '../dist/drm';
|
|
26
|
+
import type { DRMInitResult, DRMError } from '../dist/drm';
|
|
25
27
|
|
|
26
28
|
// Dynamic imports for streaming libraries
|
|
27
29
|
declare global {
|
|
@@ -142,6 +144,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
142
144
|
// Chapter management
|
|
143
145
|
private chapterManager: ChapterManager | null = null;
|
|
144
146
|
|
|
147
|
+
// DRM management
|
|
148
|
+
private drmManager: DRMManager | null = null;
|
|
149
|
+
private isDRMProtected: boolean = false;
|
|
150
|
+
|
|
145
151
|
// Start time tracking
|
|
146
152
|
private hasAppliedStartTime: boolean = false;
|
|
147
153
|
private coreChapterManager: CoreChapterManager | null = null;
|
|
@@ -700,6 +706,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
700
706
|
this.source = source as any;
|
|
701
707
|
this.subtitles = (source.subtitles || []) as any;
|
|
702
708
|
|
|
709
|
+
// Check if this is DRM-protected content
|
|
710
|
+
this.isDRMProtected = !!(source.drm && source.drm.licenseUrl);
|
|
711
|
+
this.debugLog('DRM config provided:', source.drm);
|
|
712
|
+
|
|
703
713
|
this.debugLog('Loading video source:', source.url);
|
|
704
714
|
this.debugLog('Fallback sources provided:', source.fallbackSources);
|
|
705
715
|
this.debugLog('Fallback poster provided:', source.fallbackPoster);
|
|
@@ -750,6 +760,16 @@ export class WebPlayer extends BasePlayer {
|
|
|
750
760
|
* Load a video source (main or fallback)
|
|
751
761
|
*/
|
|
752
762
|
private async loadVideoSource(url: string, sourceType: string, source: any): Promise<void> {
|
|
763
|
+
// Initialize DRM BEFORE loading the video if DRM config exists
|
|
764
|
+
if (this.isDRMProtected && source.drm) {
|
|
765
|
+
try {
|
|
766
|
+
await this.initializeDRM(source.drm);
|
|
767
|
+
} catch (drmError) {
|
|
768
|
+
this.handleDRMError(drmError);
|
|
769
|
+
throw drmError; // Prevent video loading
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
753
773
|
switch (sourceType) {
|
|
754
774
|
case 'hls':
|
|
755
775
|
await this.loadHLS(url);
|
|
@@ -782,6 +802,75 @@ export class WebPlayer extends BasePlayer {
|
|
|
782
802
|
}
|
|
783
803
|
}
|
|
784
804
|
|
|
805
|
+
/**
|
|
806
|
+
* Initialize DRM system for protected content
|
|
807
|
+
*/
|
|
808
|
+
private async initializeDRM(drmConfig: any): Promise<void> {
|
|
809
|
+
if (!this.video) {
|
|
810
|
+
throw new Error('Video element not initialized');
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
this.debugLog('Initializing DRM protection...');
|
|
814
|
+
this.debugLog('DRM Config:', {
|
|
815
|
+
type: drmConfig.type,
|
|
816
|
+
licenseUrl: drmConfig.licenseUrl,
|
|
817
|
+
certificateUrl: drmConfig.certificateUrl
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
// Create DRMManager instance
|
|
822
|
+
this.drmManager = new DRMManager(
|
|
823
|
+
this.video,
|
|
824
|
+
drmConfig,
|
|
825
|
+
this.config.debug
|
|
826
|
+
);
|
|
827
|
+
|
|
828
|
+
// Initialize DRM system
|
|
829
|
+
const initResult: DRMInitResult = await this.drmManager.initialize();
|
|
830
|
+
|
|
831
|
+
if (!initResult.success) {
|
|
832
|
+
const error = initResult.error!;
|
|
833
|
+
this.debugError('DRM initialization failed:', error);
|
|
834
|
+
throw error;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
this.debugLog('DRM initialized successfully:', {
|
|
838
|
+
drmType: initResult.drmType,
|
|
839
|
+
keySystem: initResult.keySystem
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
} catch (error) {
|
|
843
|
+
this.debugError('DRM initialization error:', error);
|
|
844
|
+
if (this.drmManager) {
|
|
845
|
+
await this.drmManager.destroy();
|
|
846
|
+
this.drmManager = null;
|
|
847
|
+
}
|
|
848
|
+
throw error;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**
|
|
853
|
+
* Handle DRM-specific errors with user-friendly messages
|
|
854
|
+
*/
|
|
855
|
+
private handleDRMError(error: any): void {
|
|
856
|
+
const userMessage = DRMErrorHandler.getUserFriendlyMessage(error);
|
|
857
|
+
const technicalMessage = DRMErrorHandler.getTechnicalMessage(error);
|
|
858
|
+
|
|
859
|
+
this.showNotification(userMessage);
|
|
860
|
+
this.debugError('DRM Error:', technicalMessage);
|
|
861
|
+
|
|
862
|
+
this.handleError({
|
|
863
|
+
code: error.code || 'DRM_ERROR',
|
|
864
|
+
message: userMessage,
|
|
865
|
+
type: 'drm',
|
|
866
|
+
fatal: true,
|
|
867
|
+
details: {
|
|
868
|
+
technical: technicalMessage,
|
|
869
|
+
original: error
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
|
|
785
874
|
/**
|
|
786
875
|
* Try loading the next fallback source
|
|
787
876
|
*/
|
|
@@ -1015,6 +1104,18 @@ export class WebPlayer extends BasePlayer {
|
|
|
1015
1104
|
this.debugLog(`⏩ HLS startPosition set to: ${this.config.startTime}s (continue watching)`);
|
|
1016
1105
|
}
|
|
1017
1106
|
|
|
1107
|
+
// Apply DRM configuration if available
|
|
1108
|
+
if (this.isDRMProtected && this.drmManager) {
|
|
1109
|
+
try {
|
|
1110
|
+
const drmHlsConfig = this.drmManager.getHLSConfig();
|
|
1111
|
+
Object.assign(hlsConfig, drmHlsConfig);
|
|
1112
|
+
this.debugLog('Applied DRM config to HLS.js');
|
|
1113
|
+
} catch (error) {
|
|
1114
|
+
this.debugError('Failed to get HLS DRM config:', error);
|
|
1115
|
+
throw error;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1018
1119
|
this.hls = new window.Hls(hlsConfig);
|
|
1019
1120
|
|
|
1020
1121
|
this.hls.loadSource(url);
|
|
@@ -1106,6 +1207,18 @@ export class WebPlayer extends BasePlayer {
|
|
|
1106
1207
|
|
|
1107
1208
|
this.dash.initialize(this.video, url, this.config.autoPlay);
|
|
1108
1209
|
|
|
1210
|
+
// Apply DRM protection data if available
|
|
1211
|
+
if (this.isDRMProtected && this.drmManager) {
|
|
1212
|
+
try {
|
|
1213
|
+
const protectionData = this.drmManager.getDashProtectionData();
|
|
1214
|
+
this.dash.setProtectionData(protectionData);
|
|
1215
|
+
this.debugLog('Applied DRM protection data to dash.js');
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
this.debugError('Failed to apply DASH DRM protection:', error);
|
|
1218
|
+
throw error;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1109
1222
|
// Configure DASH settings
|
|
1110
1223
|
this.dash.updateSettings({
|
|
1111
1224
|
streaming: {
|
|
@@ -11321,6 +11434,18 @@ export class WebPlayer extends BasePlayer {
|
|
|
11321
11434
|
}
|
|
11322
11435
|
|
|
11323
11436
|
private async cleanup(): Promise<void> {
|
|
11437
|
+
// Clean up DRM resources first
|
|
11438
|
+
if (this.drmManager) {
|
|
11439
|
+
try {
|
|
11440
|
+
await this.drmManager.destroy();
|
|
11441
|
+
this.debugLog('DRM manager destroyed');
|
|
11442
|
+
} catch (error) {
|
|
11443
|
+
this.debugError('Error destroying DRM manager:', error);
|
|
11444
|
+
}
|
|
11445
|
+
this.drmManager = null;
|
|
11446
|
+
}
|
|
11447
|
+
this.isDRMProtected = false;
|
|
11448
|
+
|
|
11324
11449
|
if (this.hls) {
|
|
11325
11450
|
this.hls.destroy();
|
|
11326
11451
|
this.hls = null;
|