unified-video-framework 1.4.84 → 1.4.85
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/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.85] - 2024-12-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **🦁 Brave Browser Fullscreen Support**: Comprehensive Brave browser detection and enhanced fullscreen handling
|
|
12
|
+
- Accurate Brave browser detection using multiple detection methods
|
|
13
|
+
- Private/Incognito mode detection for different handling approaches
|
|
14
|
+
- Enhanced permissions checking and fullscreen capability analysis
|
|
15
|
+
- `enterFullscreenWithBraveSupport()` method with targeted error handling for Brave-specific issues
|
|
16
|
+
- Brave-specific user gesture validation and permission requests
|
|
17
|
+
- **🧪 Comprehensive Debug Testing**: Advanced debugging tools for Brave fullscreen issues
|
|
18
|
+
- `brave-fullscreen-debug-test.html` - Comprehensive test page for diagnosing fullscreen problems
|
|
19
|
+
- Browser environment detection with detailed capability analysis
|
|
20
|
+
- Multiple fullscreen test methods (button click, keyboard shortcuts, double-click, direct API)
|
|
21
|
+
- Debug logging system with export functionality for issue analysis
|
|
22
|
+
- Permission state monitoring and site settings validation
|
|
23
|
+
|
|
24
|
+
### Enhanced
|
|
25
|
+
- **Fullscreen Button Handler**: Enhanced with Brave-specific logic and debugging
|
|
26
|
+
- Special handling for Brave normal tabs vs private tabs
|
|
27
|
+
- Enhanced error messages with browser-specific guidance
|
|
28
|
+
- Multiple event dispatch methods for maximum compatibility
|
|
29
|
+
- Fresh user gesture validation for reliable fullscreen activation
|
|
30
|
+
- **Cross-browser Compatibility**: Improved fullscreen API support
|
|
31
|
+
- Multiple fullscreen API fallbacks (standard, webkit, moz, ms)
|
|
32
|
+
- Enhanced error handling with specific guidance for common browser issues
|
|
33
|
+
- Improved user gesture context preservation
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- **Brave Browser Issues**: Resolved common fullscreen problems in Brave browser
|
|
37
|
+
- Fixed "API can only be initiated by a user gesture" errors in normal tabs
|
|
38
|
+
- Improved permission handling for Brave's stricter security policies
|
|
39
|
+
- Better handling of Brave Shields and site settings interference
|
|
40
|
+
- Enhanced fallback mechanisms when fullscreen APIs are restricted
|
|
41
|
+
|
|
42
|
+
### Improved
|
|
43
|
+
- **Developer Experience**: Better debugging and issue identification tools
|
|
44
|
+
- Detailed browser capability detection and logging
|
|
45
|
+
- Comprehensive test suite for diagnosing fullscreen issues across different browser modes
|
|
46
|
+
- Enhanced error messages with actionable guidance for users
|
|
47
|
+
- Export functionality for debug logs to assist with issue resolution
|
|
48
|
+
|
|
8
49
|
## [1.4.47] - 2024-01-24
|
|
9
50
|
|
|
10
51
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unified-video-framework",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.85",
|
|
4
4
|
"description": "Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more",
|
|
5
5
|
"main": "packages/core/dist/index.js",
|
|
6
6
|
"types": "packages/core/dist/index.d.ts",
|
|
@@ -81,7 +81,13 @@ export declare class WebPlayer extends BasePlayer {
|
|
|
81
81
|
exitPictureInPicture(): Promise<void>;
|
|
82
82
|
focusPlayer(): void;
|
|
83
83
|
showFullscreenTip(): void;
|
|
84
|
+
private isBraveBrowser;
|
|
85
|
+
private checkFullscreenPermissions;
|
|
86
|
+
private isPrivateWindow;
|
|
84
87
|
triggerFullscreenButton(): void;
|
|
88
|
+
private performFullscreenButtonClick;
|
|
89
|
+
private requestFullscreenPermissionBrave;
|
|
90
|
+
enterFullscreenWithBraveSupport(): Promise<void>;
|
|
85
91
|
showTemporaryMessage(message: string): void;
|
|
86
92
|
enterFullscreenSynchronously(): void;
|
|
87
93
|
requestFullscreenWithUserGesture(event: Event): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebPlayer.d.ts","sourceRoot":"","sources":["../src/WebPlayer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"WebPlayer.d.ts","sourceRoot":"","sources":["../src/WebPlayer.ts"],"names":[],"mappings":"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"}
|
|
@@ -768,51 +768,258 @@ export class WebPlayer extends BasePlayer {
|
|
|
768
768
|
this.showShortcutIndicator('💡 Double-click or use ⌨️ F key for fullscreen');
|
|
769
769
|
this.debugLog('Tip: Double-click the video area or press F key for fullscreen, or use the fullscreen button in controls');
|
|
770
770
|
}
|
|
771
|
+
isBraveBrowser() {
|
|
772
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
773
|
+
const isBrave = (userAgent.includes('brave') ||
|
|
774
|
+
!!navigator.brave ||
|
|
775
|
+
window.chrome && window.chrome.app && window.chrome.app.isInstalled === false);
|
|
776
|
+
this.debugLog('Browser detection - Is Brave:', isBrave, 'User Agent:', userAgent);
|
|
777
|
+
return isBrave;
|
|
778
|
+
}
|
|
779
|
+
async checkFullscreenPermissions() {
|
|
780
|
+
try {
|
|
781
|
+
const fullscreenEnabled = document.fullscreenEnabled ||
|
|
782
|
+
document.webkitFullscreenEnabled ||
|
|
783
|
+
document.mozFullScreenEnabled ||
|
|
784
|
+
document.msFullscreenEnabled;
|
|
785
|
+
this.debugLog('Fullscreen permissions check:', {
|
|
786
|
+
fullscreenEnabled,
|
|
787
|
+
documentFullscreenEnabled: document.fullscreenEnabled,
|
|
788
|
+
webkitEnabled: document.webkitFullscreenEnabled,
|
|
789
|
+
mozEnabled: document.mozFullScreenEnabled,
|
|
790
|
+
msEnabled: document.msFullscreenEnabled,
|
|
791
|
+
currentOrigin: window.location.origin,
|
|
792
|
+
currentHref: window.location.href,
|
|
793
|
+
isSecureContext: window.isSecureContext,
|
|
794
|
+
protocol: window.location.protocol,
|
|
795
|
+
isBrave: this.isBraveBrowser(),
|
|
796
|
+
isPrivate: this.isPrivateWindow()
|
|
797
|
+
});
|
|
798
|
+
if ('permissions' in navigator) {
|
|
799
|
+
try {
|
|
800
|
+
const permission = await navigator.permissions.query({ name: 'fullscreen' });
|
|
801
|
+
this.debugLog('Fullscreen permission state:', permission.state);
|
|
802
|
+
}
|
|
803
|
+
catch (err) {
|
|
804
|
+
this.debugLog('Permissions API check failed:', err.message);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
catch (error) {
|
|
809
|
+
this.debugWarn('Permission check failed:', error.message);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
isPrivateWindow() {
|
|
813
|
+
try {
|
|
814
|
+
if ('webkitRequestFileSystem' in window) {
|
|
815
|
+
return new Promise((resolve) => {
|
|
816
|
+
window.webkitRequestFileSystem(window.TEMPORARY, 1, () => resolve(false), () => resolve(true));
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
if ('MozAppearance' in document.documentElement.style) {
|
|
820
|
+
if (window.indexedDB === null)
|
|
821
|
+
return true;
|
|
822
|
+
if (window.indexedDB === undefined)
|
|
823
|
+
return true;
|
|
824
|
+
}
|
|
825
|
+
try {
|
|
826
|
+
window.localStorage.setItem('test', '1');
|
|
827
|
+
window.localStorage.removeItem('test');
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
catch {
|
|
831
|
+
return true;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
catch {
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
771
839
|
triggerFullscreenButton() {
|
|
772
840
|
const fullscreenBtn = document.getElementById('uvf-fullscreen-btn');
|
|
841
|
+
const isBrave = this.isBraveBrowser();
|
|
842
|
+
const isPrivate = this.isPrivateWindow();
|
|
843
|
+
this.debugLog('Fullscreen trigger attempt:', {
|
|
844
|
+
buttonExists: !!fullscreenBtn,
|
|
845
|
+
isBrave,
|
|
846
|
+
isPrivate,
|
|
847
|
+
currentFullscreenElement: document.fullscreenElement,
|
|
848
|
+
timestamp: Date.now(),
|
|
849
|
+
lastUserInteraction: this.lastUserInteraction,
|
|
850
|
+
timeSinceInteraction: Date.now() - this.lastUserInteraction
|
|
851
|
+
});
|
|
852
|
+
this.checkFullscreenPermissions();
|
|
773
853
|
if (fullscreenBtn) {
|
|
774
854
|
this.debugLog('Triggering fullscreen button click');
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
view: window,
|
|
788
|
-
detail: 1,
|
|
789
|
-
button: 0,
|
|
790
|
-
buttons: 0
|
|
791
|
-
}),
|
|
792
|
-
new MouseEvent('click', {
|
|
793
|
-
bubbles: true,
|
|
794
|
-
cancelable: true,
|
|
795
|
-
view: window,
|
|
796
|
-
detail: 1,
|
|
797
|
-
button: 0,
|
|
798
|
-
buttons: 0
|
|
799
|
-
})
|
|
800
|
-
];
|
|
801
|
-
events.forEach(event => {
|
|
802
|
-
fullscreenBtn.dispatchEvent(event);
|
|
803
|
-
});
|
|
804
|
-
try {
|
|
805
|
-
fullscreenBtn.click();
|
|
855
|
+
if (isBrave) {
|
|
856
|
+
this.debugLog('Applying Brave browser specific fullscreen handling');
|
|
857
|
+
if (Date.now() - this.lastUserInteraction > 1000) {
|
|
858
|
+
this.debugWarn('User gesture may be stale for Brave browser');
|
|
859
|
+
this.showTemporaryMessage('Click the fullscreen button directly in Brave browser');
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
this.requestFullscreenPermissionBrave().then(() => {
|
|
863
|
+
this.performFullscreenButtonClick(fullscreenBtn);
|
|
864
|
+
}).catch(() => {
|
|
865
|
+
this.performFullscreenButtonClick(fullscreenBtn);
|
|
866
|
+
});
|
|
806
867
|
}
|
|
807
|
-
|
|
808
|
-
this.
|
|
868
|
+
else {
|
|
869
|
+
this.performFullscreenButtonClick(fullscreenBtn);
|
|
809
870
|
}
|
|
810
|
-
this.showShortcutIndicator('Fullscreen');
|
|
811
871
|
}
|
|
812
872
|
else {
|
|
813
873
|
this.debugWarn('Fullscreen button not found');
|
|
814
874
|
this.showShortcutIndicator('Fullscreen Button Missing');
|
|
815
|
-
|
|
875
|
+
if (isBrave) {
|
|
876
|
+
this.showTemporaryMessage('Brave: Please use fullscreen button in controls');
|
|
877
|
+
}
|
|
878
|
+
else {
|
|
879
|
+
this.showTemporaryMessage('Press F key when player controls are visible');
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
performFullscreenButtonClick(fullscreenBtn) {
|
|
884
|
+
const events = [
|
|
885
|
+
new MouseEvent('mousedown', {
|
|
886
|
+
bubbles: true,
|
|
887
|
+
cancelable: true,
|
|
888
|
+
view: window,
|
|
889
|
+
detail: 1,
|
|
890
|
+
button: 0,
|
|
891
|
+
buttons: 1,
|
|
892
|
+
isTrusted: true
|
|
893
|
+
}),
|
|
894
|
+
new MouseEvent('mouseup', {
|
|
895
|
+
bubbles: true,
|
|
896
|
+
cancelable: true,
|
|
897
|
+
view: window,
|
|
898
|
+
detail: 1,
|
|
899
|
+
button: 0,
|
|
900
|
+
buttons: 0,
|
|
901
|
+
isTrusted: true
|
|
902
|
+
}),
|
|
903
|
+
new MouseEvent('click', {
|
|
904
|
+
bubbles: true,
|
|
905
|
+
cancelable: true,
|
|
906
|
+
view: window,
|
|
907
|
+
detail: 1,
|
|
908
|
+
button: 0,
|
|
909
|
+
buttons: 0,
|
|
910
|
+
isTrusted: true
|
|
911
|
+
})
|
|
912
|
+
];
|
|
913
|
+
this.debugLog('Dispatching mouse events:', events.length);
|
|
914
|
+
events.forEach((event, index) => {
|
|
915
|
+
try {
|
|
916
|
+
fullscreenBtn.dispatchEvent(event);
|
|
917
|
+
this.debugLog(`Event ${index + 1} dispatched:`, event.type);
|
|
918
|
+
}
|
|
919
|
+
catch (error) {
|
|
920
|
+
this.debugWarn(`Event ${index + 1} dispatch failed:`, error.message);
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
try {
|
|
924
|
+
fullscreenBtn.click();
|
|
925
|
+
this.debugLog('Direct button click executed');
|
|
926
|
+
}
|
|
927
|
+
catch (error) {
|
|
928
|
+
this.debugWarn('Direct button click failed:', error.message);
|
|
929
|
+
}
|
|
930
|
+
try {
|
|
931
|
+
fullscreenBtn.focus();
|
|
932
|
+
setTimeout(() => fullscreenBtn.blur(), 100);
|
|
933
|
+
}
|
|
934
|
+
catch (error) {
|
|
935
|
+
this.debugLog('Button focus failed:', error.message);
|
|
936
|
+
}
|
|
937
|
+
this.showShortcutIndicator('Fullscreen');
|
|
938
|
+
}
|
|
939
|
+
async requestFullscreenPermissionBrave() {
|
|
940
|
+
try {
|
|
941
|
+
if ('permissions' in navigator && 'request' in navigator.permissions) {
|
|
942
|
+
await navigator.permissions.request({ name: 'fullscreen' });
|
|
943
|
+
this.debugLog('Brave fullscreen permission requested');
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
catch (error) {
|
|
947
|
+
this.debugLog('Brave permission request failed:', error.message);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async enterFullscreenWithBraveSupport() {
|
|
951
|
+
if (!this.playerWrapper) {
|
|
952
|
+
throw new Error('Player wrapper not available');
|
|
953
|
+
}
|
|
954
|
+
this.debugLog('Attempting Brave-specific fullscreen entry');
|
|
955
|
+
await this.requestFullscreenPermissionBrave();
|
|
956
|
+
if (document.fullscreenElement ||
|
|
957
|
+
document.webkitFullscreenElement ||
|
|
958
|
+
document.mozFullScreenElement ||
|
|
959
|
+
document.msFullscreenElement) {
|
|
960
|
+
this.debugLog('Already in fullscreen mode');
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
const fullscreenEnabled = document.fullscreenEnabled ||
|
|
964
|
+
document.webkitFullscreenEnabled ||
|
|
965
|
+
document.mozFullScreenEnabled ||
|
|
966
|
+
document.msFullscreenEnabled;
|
|
967
|
+
if (!fullscreenEnabled) {
|
|
968
|
+
throw new Error('Fullscreen not supported or disabled in Brave settings');
|
|
969
|
+
}
|
|
970
|
+
if ('permissions' in navigator) {
|
|
971
|
+
try {
|
|
972
|
+
const permission = await navigator.permissions.query({ name: 'fullscreen' });
|
|
973
|
+
this.debugLog('Brave fullscreen permission state:', permission.state);
|
|
974
|
+
if (permission.state === 'denied') {
|
|
975
|
+
throw new Error('Fullscreen permission denied in Brave site settings');
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
catch (permError) {
|
|
979
|
+
this.debugLog('Permission check failed:', permError.message);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
let fullscreenError = null;
|
|
983
|
+
try {
|
|
984
|
+
if (this.playerWrapper.requestFullscreen) {
|
|
985
|
+
this.debugLog('Attempting standard requestFullscreen()');
|
|
986
|
+
await this.playerWrapper.requestFullscreen({
|
|
987
|
+
navigationUI: 'hide'
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
else if (this.playerWrapper.webkitRequestFullscreen) {
|
|
991
|
+
this.debugLog('Attempting webkitRequestFullscreen()');
|
|
992
|
+
await this.playerWrapper.webkitRequestFullscreen();
|
|
993
|
+
}
|
|
994
|
+
else if (this.playerWrapper.mozRequestFullScreen) {
|
|
995
|
+
this.debugLog('Attempting mozRequestFullScreen()');
|
|
996
|
+
await this.playerWrapper.mozRequestFullScreen();
|
|
997
|
+
}
|
|
998
|
+
else if (this.playerWrapper.msRequestFullscreen) {
|
|
999
|
+
this.debugLog('Attempting msRequestFullscreen()');
|
|
1000
|
+
await this.playerWrapper.msRequestFullscreen();
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
throw new Error('No fullscreen API available');
|
|
1004
|
+
}
|
|
1005
|
+
this.playerWrapper.classList.add('uvf-fullscreen');
|
|
1006
|
+
this.emit('onFullscreenChanged', true);
|
|
1007
|
+
this.debugLog('Brave fullscreen entry successful');
|
|
1008
|
+
}
|
|
1009
|
+
catch (error) {
|
|
1010
|
+
fullscreenError = error;
|
|
1011
|
+
this.debugWarn('Brave fullscreen attempt failed:', fullscreenError.message);
|
|
1012
|
+
if (fullscreenError.message.includes('denied') ||
|
|
1013
|
+
fullscreenError.message.includes('not allowed')) {
|
|
1014
|
+
throw new Error('Brave Browser: Fullscreen blocked. Check site permissions in Settings > Site and Shields Settings');
|
|
1015
|
+
}
|
|
1016
|
+
else if (fullscreenError.message.includes('gesture') ||
|
|
1017
|
+
fullscreenError.message.includes('user activation')) {
|
|
1018
|
+
throw new Error('Brave Browser: User interaction required. Click the fullscreen button directly');
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
throw new Error(`Brave Browser: ${fullscreenError.message}`);
|
|
1022
|
+
}
|
|
816
1023
|
}
|
|
817
1024
|
}
|
|
818
1025
|
showTemporaryMessage(message) {
|
|
@@ -2944,16 +3151,41 @@ export class WebPlayer extends BasePlayer {
|
|
|
2944
3151
|
}
|
|
2945
3152
|
}
|
|
2946
3153
|
});
|
|
2947
|
-
fullscreenBtn?.addEventListener('click', () => {
|
|
3154
|
+
fullscreenBtn?.addEventListener('click', (event) => {
|
|
3155
|
+
const isBrave = this.isBraveBrowser();
|
|
3156
|
+
const isPrivate = this.isPrivateWindow();
|
|
3157
|
+
this.debugLog('Fullscreen button clicked:', {
|
|
3158
|
+
isBrave,
|
|
3159
|
+
isPrivate,
|
|
3160
|
+
isFullscreen: this.isFullscreen(),
|
|
3161
|
+
eventTrusted: event.isTrusted,
|
|
3162
|
+
eventType: event.type,
|
|
3163
|
+
timestamp: Date.now()
|
|
3164
|
+
});
|
|
3165
|
+
this.lastUserInteraction = Date.now();
|
|
3166
|
+
this.checkFullscreenPermissions();
|
|
2948
3167
|
if (this.isFullscreen()) {
|
|
3168
|
+
this.debugLog('Exiting fullscreen via button');
|
|
2949
3169
|
this.exitFullscreen().catch(err => {
|
|
2950
3170
|
this.debugWarn('Exit fullscreen button failed:', err.message);
|
|
2951
3171
|
});
|
|
2952
3172
|
}
|
|
2953
3173
|
else {
|
|
2954
|
-
this.
|
|
2955
|
-
|
|
2956
|
-
|
|
3174
|
+
this.debugLog('Entering fullscreen via button');
|
|
3175
|
+
if (isBrave && !isPrivate) {
|
|
3176
|
+
this.enterFullscreenWithBraveSupport().catch(err => {
|
|
3177
|
+
this.debugWarn('Brave fullscreen button failed:', err.message);
|
|
3178
|
+
this.showTemporaryMessage('Brave Browser: Please allow fullscreen in site settings');
|
|
3179
|
+
});
|
|
3180
|
+
}
|
|
3181
|
+
else {
|
|
3182
|
+
this.enterFullscreen().catch(err => {
|
|
3183
|
+
this.debugWarn('Fullscreen button failed:', err.message);
|
|
3184
|
+
if (isBrave) {
|
|
3185
|
+
this.showTemporaryMessage('Try refreshing the page or check Brave shields settings');
|
|
3186
|
+
}
|
|
3187
|
+
});
|
|
3188
|
+
}
|
|
2957
3189
|
}
|
|
2958
3190
|
});
|
|
2959
3191
|
const updateFullscreenIcon = () => {
|