unified-video-framework 1.4.118 → 1.4.119
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unified-video-framework",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.119",
|
|
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",
|
|
@@ -82,6 +82,8 @@ export declare class WebPlayer extends BasePlayer {
|
|
|
82
82
|
setAutoQuality(enabled: boolean): void;
|
|
83
83
|
enterFullscreen(): Promise<void>;
|
|
84
84
|
exitFullscreen(): Promise<void>;
|
|
85
|
+
isPictureInPictureSupported(): boolean;
|
|
86
|
+
private isMobileDevice;
|
|
85
87
|
enterPictureInPicture(): Promise<void>;
|
|
86
88
|
exitPictureInPicture(): Promise<void>;
|
|
87
89
|
focusPlayer(): void;
|
|
@@ -137,6 +139,7 @@ export declare class WebPlayer extends BasePlayer {
|
|
|
137
139
|
private changeVolume;
|
|
138
140
|
private setSpeed;
|
|
139
141
|
private setQualityByLabel;
|
|
142
|
+
isPictureInPictureActive(): boolean;
|
|
140
143
|
private togglePiP;
|
|
141
144
|
private setupCastContextSafe;
|
|
142
145
|
private setupCastContext;
|
|
@@ -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":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAUjD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,GAAG,EAAE,GAAG,CAAC;QACT,MAAM,EAAE,GAAG,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC;QACX,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;KACxD;CACF;AAED,qBAAa,SAAU,SAAQ,UAAU;IACvC,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAChD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,mBAAmB,CAAc;IACzC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,iBAAiB,CAAkB;IAG3C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,yBAAyB,CAAa;IAC9C,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,mBAAmB,CAAiB;IAC5C,OAAO,CAAC,KAAK,CAAa;IAG1B,OAAO,CAAC,iBAAiB,CAAa;IAGtC,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,mBAAmB,CAAO;IAGlC,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,mBAAmB,CAAa;IAGxC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,SAAS;cAOD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA+I5C,OAAO,CAAC,wBAAwB;IAsHhC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,oBAAoB;IAYtB,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAwDtC,OAAO,CAAC,gBAAgB;YAcV,OAAO;IAyDrB,OAAO,CAAC,cAAc;YAyBR,QAAQ;IA4DtB,OAAO,CAAC,iBAAiB;YAQX,UAAU;IAMxB,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,gBAAgB;IAOlB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+C3B,KAAK,IAAI,IAAI;IAkBN,YAAY,IAAI,IAAI;IAO3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBxB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B,IAAI,IAAI,IAAI;IAMZ,MAAM,IAAI,IAAI;IAOd,cAAc,IAAI,MAAM;IAOxB,YAAY,IAAI,GAAG,EAAE;IAIrB,iBAAiB,IAAI,GAAG;IAIxB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW/B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOnC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAkBhC,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAwDhC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CrC,2BAA2B,IAAI,OAAO;IAiDtC,OAAO,CAAC,cAAc;IAMhB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BtC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC3C,WAAW,IAAI,IAAI;IAUnB,iBAAiB,IAAI,IAAI;IAUzB,OAAO,CAAC,cAAc;YAmBR,0BAA0B;IAwCxC,OAAO,CAAC,eAAe;IAwCvB,uBAAuB,IAAI,IAAI;IA4D/B,OAAO,CAAC,4BAA4B;YAoEtB,gCAAgC;IAgBxC,+BAA+B,IAAI,OAAO,CAAC,IAAI,CAAC;IAkGtD,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAmC3C,4BAA4B,IAAI,IAAI;IA4D9B,gCAAgC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IA8DtE,0BAA0B,IAAI,IAAI;IAqK5B,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IA4C3C,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAc9C,SAAS,CAAC,eAAe,IAAI,IAAI;IASjC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAu/EvB,OAAO,CAAC,oBAAoB;IAwO5B,OAAO,CAAC,2BAA2B;IA2VnC,SAAS,CAAC,sBAAsB,IAAI,IAAI;IAoLxC,SAAS,CAAC,cAAc,IAAI,IAAI;IAiDzB,gBAAgB,CAAC,MAAM,EAAE,GAAG;IA2CnC,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,sBAAsB;IAsDvB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAetC,oBAAoB,IAAI,IAAI;IAO5B,kBAAkB,IAAI,IAAI;IAOjC,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,wBAAwB;IAyEhC,OAAO,CAAC,qBAAqB;IA8FtB,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI;IAiBxE,0BAA0B,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAwB1F,OAAO,CAAC,oCAAoC;IAqBrC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IA2DjC,OAAO,CAAC,SAAS;IA8BjB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,iBAAiB;IAmCzB,wBAAwB,IAAI,OAAO;YAYrB,SAAS;IA+BvB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,gBAAgB;IA6BxB,OAAO,CAAC,uBAAuB;IAoB/B,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,uBAAuB;IA6D/B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,kBAAkB;IA4D1B,OAAO,CAAC,wBAAwB;IA+ChC,OAAO,CAAC,wBAAwB;IA6BhC,OAAO,CAAC,2BAA2B;IAmCnC,OAAO,CAAC,0BAA0B;IAgBlC,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,WAAW;YAoBL,QAAQ;YAqGR,UAAU;IAqBxB,OAAO,CAAC,gBAAgB;IA2CxB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,YAAY;IA6BpB,OAAO,CAAC,sBAAsB;IA6B9B,OAAO,CAAC,sBAAsB;IAiF9B,OAAO,CAAC,uBAAuB;IAuB/B,OAAO,CAAC,4BAA4B;IAoDpC,OAAO,CAAC,oBAAoB;IA+BrB,aAAa,IAAI,IAAI;IAarB,aAAa,IAAI,IAAI;IAYrB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAe9B,kBAAkB,IAAI,OAAO;YAKtB,OAAO;IAgBf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA2C/B"}
|
|
@@ -739,26 +739,87 @@ export class WebPlayer extends BasePlayer {
|
|
|
739
739
|
this.debugWarn('Failed to exit fullscreen:', error.message);
|
|
740
740
|
}
|
|
741
741
|
}
|
|
742
|
-
|
|
742
|
+
isPictureInPictureSupported() {
|
|
743
743
|
if (!this.video)
|
|
744
|
-
return;
|
|
744
|
+
return false;
|
|
745
|
+
const hasStandardPiP = 'requestPictureInPicture' in this.video &&
|
|
746
|
+
'pictureInPictureEnabled' in document;
|
|
747
|
+
const hasSafariPiP = 'webkitSupportsPresentationMode' in this.video &&
|
|
748
|
+
typeof this.video.webkitSupportsPresentationMode === 'function' &&
|
|
749
|
+
this.video.webkitSupportsPresentationMode('picture-in-picture');
|
|
750
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
751
|
+
const isIOS = /iphone|ipad|ipod/.test(userAgent);
|
|
752
|
+
const isAndroid = /android/.test(userAgent);
|
|
753
|
+
const isChrome = /chrome/.test(userAgent) && !/edge/.test(userAgent);
|
|
754
|
+
const isSafari = /safari/.test(userAgent) && !/chrome/.test(userAgent);
|
|
755
|
+
const isFirefox = /firefox/.test(userAgent);
|
|
756
|
+
const iosSupport = isIOS && isSafari && hasSafariPiP;
|
|
757
|
+
const androidChromeSupport = isAndroid && isChrome && hasStandardPiP;
|
|
758
|
+
const firefoxSupport = isFirefox && hasStandardPiP && !this.isMobileDevice();
|
|
759
|
+
this.debugLog('PiP Support Detection:', {
|
|
760
|
+
hasStandardPiP,
|
|
761
|
+
hasSafariPiP,
|
|
762
|
+
isIOS,
|
|
763
|
+
isAndroid,
|
|
764
|
+
isChrome,
|
|
765
|
+
isSafari,
|
|
766
|
+
isFirefox,
|
|
767
|
+
iosSupport,
|
|
768
|
+
androidChromeSupport,
|
|
769
|
+
firefoxSupport,
|
|
770
|
+
overall: hasStandardPiP || iosSupport || androidChromeSupport || firefoxSupport
|
|
771
|
+
});
|
|
772
|
+
return hasStandardPiP || iosSupport || androidChromeSupport || firefoxSupport;
|
|
773
|
+
}
|
|
774
|
+
isMobileDevice() {
|
|
775
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
776
|
+
return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/.test(userAgent) ||
|
|
777
|
+
(!!(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) && /macintosh/.test(userAgent));
|
|
778
|
+
}
|
|
779
|
+
async enterPictureInPicture() {
|
|
780
|
+
if (!this.video) {
|
|
781
|
+
throw new Error('Video element not available');
|
|
782
|
+
}
|
|
783
|
+
if (!this.isPictureInPictureSupported()) {
|
|
784
|
+
throw new Error('Picture-in-Picture not supported on this device/browser');
|
|
785
|
+
}
|
|
745
786
|
try {
|
|
746
|
-
if (this.video
|
|
787
|
+
if ('requestPictureInPicture' in this.video) {
|
|
747
788
|
await this.video.requestPictureInPicture();
|
|
789
|
+
this.debugLog('PiP entered using standard API');
|
|
790
|
+
return;
|
|
748
791
|
}
|
|
749
|
-
|
|
750
|
-
|
|
792
|
+
if ('webkitSetPresentationMode' in this.video) {
|
|
793
|
+
this.video.webkitSetPresentationMode('picture-in-picture');
|
|
794
|
+
this.debugLog('PiP entered using WebKit API');
|
|
795
|
+
return;
|
|
751
796
|
}
|
|
797
|
+
throw new Error('No supported PiP API available');
|
|
752
798
|
}
|
|
753
799
|
catch (error) {
|
|
754
|
-
|
|
800
|
+
this.debugError('Failed to enter PiP:', error.message);
|
|
755
801
|
throw error;
|
|
756
802
|
}
|
|
757
803
|
}
|
|
758
804
|
async exitPictureInPicture() {
|
|
759
805
|
try {
|
|
760
|
-
|
|
806
|
+
const inStandardPiP = document.pictureInPictureElement;
|
|
807
|
+
const inWebkitPiP = this.video &&
|
|
808
|
+
'webkitPresentationMode' in this.video &&
|
|
809
|
+
this.video.webkitPresentationMode === 'picture-in-picture';
|
|
810
|
+
if (!inStandardPiP && !inWebkitPiP) {
|
|
811
|
+
this.debugLog('Not currently in PiP mode');
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
if (inStandardPiP && 'exitPictureInPicture' in document) {
|
|
761
815
|
await document.exitPictureInPicture();
|
|
816
|
+
this.debugLog('PiP exited using standard API');
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
if (inWebkitPiP && this.video && 'webkitSetPresentationMode' in this.video) {
|
|
820
|
+
this.video.webkitSetPresentationMode('inline');
|
|
821
|
+
this.debugLog('PiP exited using WebKit API');
|
|
822
|
+
return;
|
|
762
823
|
}
|
|
763
824
|
}
|
|
764
825
|
catch (error) {
|
|
@@ -1462,16 +1523,48 @@ export class WebPlayer extends BasePlayer {
|
|
|
1462
1523
|
aspect-ratio: 16 / 9;
|
|
1463
1524
|
background: radial-gradient(ellipse at center, #1a1a2e 0%, #000 100%);
|
|
1464
1525
|
overflow: hidden;
|
|
1526
|
+
display: flex;
|
|
1527
|
+
align-items: center;
|
|
1528
|
+
justify-content: center;
|
|
1465
1529
|
}
|
|
1466
1530
|
|
|
1467
1531
|
.uvf-video {
|
|
1468
1532
|
position: absolute;
|
|
1469
|
-
top:
|
|
1470
|
-
left:
|
|
1471
|
-
|
|
1472
|
-
|
|
1533
|
+
top: 50%;
|
|
1534
|
+
left: 50%;
|
|
1535
|
+
transform: translate(-50%, -50%);
|
|
1536
|
+
max-width: 100%;
|
|
1537
|
+
max-height: 100%;
|
|
1538
|
+
width: auto;
|
|
1539
|
+
height: auto;
|
|
1473
1540
|
background: #000;
|
|
1474
1541
|
object-fit: contain;
|
|
1542
|
+
/* Ensure proper centering and scaling */
|
|
1543
|
+
object-position: center;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/* Mobile-specific video centering improvements */
|
|
1547
|
+
@media screen and (max-width: 767px) {
|
|
1548
|
+
.uvf-video {
|
|
1549
|
+
/* Force full width/height on mobile for better centering */
|
|
1550
|
+
width: 100%;
|
|
1551
|
+
height: 100%;
|
|
1552
|
+
top: 0;
|
|
1553
|
+
left: 0;
|
|
1554
|
+
transform: none;
|
|
1555
|
+
object-fit: contain;
|
|
1556
|
+
object-position: center;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
.uvf-video-container {
|
|
1560
|
+
/* Remove aspect ratio constraint on mobile for full height usage */
|
|
1561
|
+
aspect-ratio: unset;
|
|
1562
|
+
min-height: 100%;
|
|
1563
|
+
height: 100%;
|
|
1564
|
+
display: flex;
|
|
1565
|
+
align-items: center;
|
|
1566
|
+
justify-content: center;
|
|
1567
|
+
}
|
|
1475
1568
|
}
|
|
1476
1569
|
|
|
1477
1570
|
.uvf-watermark-layer {
|
|
@@ -2594,6 +2687,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
2594
2687
|
@media screen and (max-width: 767px) {
|
|
2595
2688
|
html, body {
|
|
2596
2689
|
overflow-x: hidden;
|
|
2690
|
+
/* Prevent iOS Safari address bar bounce */
|
|
2691
|
+
position: fixed;
|
|
2692
|
+
height: 100%;
|
|
2693
|
+
width: 100%;
|
|
2597
2694
|
}
|
|
2598
2695
|
|
|
2599
2696
|
.uvf-player-wrapper {
|
|
@@ -2603,6 +2700,23 @@ export class WebPlayer extends BasePlayer {
|
|
|
2603
2700
|
|
|
2604
2701
|
/* Prevent zoom on double tap */
|
|
2605
2702
|
touch-action: manipulation;
|
|
2703
|
+
|
|
2704
|
+
/* Ensure full viewport usage */
|
|
2705
|
+
position: relative;
|
|
2706
|
+
width: 100vw;
|
|
2707
|
+
height: 100vh;
|
|
2708
|
+
|
|
2709
|
+
/* iOS Safari fix for viewport height */
|
|
2710
|
+
min-height: -webkit-fill-available;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
.uvf-video-container {
|
|
2714
|
+
/* Full viewport container */
|
|
2715
|
+
width: 100vw;
|
|
2716
|
+
height: 100vh;
|
|
2717
|
+
min-height: -webkit-fill-available;
|
|
2718
|
+
position: relative;
|
|
2719
|
+
overflow: hidden;
|
|
2606
2720
|
}
|
|
2607
2721
|
|
|
2608
2722
|
.uvf-video {
|
|
@@ -2615,12 +2729,38 @@ export class WebPlayer extends BasePlayer {
|
|
|
2615
2729
|
/* Ensure hardware acceleration */
|
|
2616
2730
|
-webkit-transform: translateZ(0);
|
|
2617
2731
|
transform: translateZ(0);
|
|
2732
|
+
|
|
2733
|
+
/* Full viewport video with proper centering */
|
|
2734
|
+
width: 100%;
|
|
2735
|
+
height: 100%;
|
|
2736
|
+
object-fit: contain;
|
|
2737
|
+
object-position: center center;
|
|
2618
2738
|
}
|
|
2619
2739
|
|
|
2620
2740
|
/* Fix for controls being cut off by virtual keyboard */
|
|
2621
2741
|
.uvf-controls-bar {
|
|
2622
2742
|
position: fixed !important;
|
|
2623
2743
|
bottom: var(--uvf-safe-area-bottom, 0) !important;
|
|
2744
|
+
left: var(--uvf-safe-area-left, 0) !important;
|
|
2745
|
+
right: var(--uvf-safe-area-right, 0) !important;
|
|
2746
|
+
width: auto !important;
|
|
2747
|
+
z-index: 9999;
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2750
|
+
/* Top controls safe area positioning */
|
|
2751
|
+
.uvf-top-controls {
|
|
2752
|
+
position: fixed !important;
|
|
2753
|
+
top: var(--uvf-safe-area-top, 10px) !important;
|
|
2754
|
+
right: var(--uvf-safe-area-right, 10px) !important;
|
|
2755
|
+
z-index: 9999;
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
.uvf-title-bar {
|
|
2759
|
+
position: fixed !important;
|
|
2760
|
+
top: var(--uvf-safe-area-top, 10px) !important;
|
|
2761
|
+
left: var(--uvf-safe-area-left, 10px) !important;
|
|
2762
|
+
right: calc(120px + var(--uvf-safe-area-right, 10px)) !important; /* Leave space for top controls */
|
|
2763
|
+
z-index: 9999;
|
|
2624
2764
|
}
|
|
2625
2765
|
|
|
2626
2766
|
/* Ensure controls stay above virtual keyboards */
|
|
@@ -2629,6 +2769,61 @@ export class WebPlayer extends BasePlayer {
|
|
|
2629
2769
|
bottom: max(var(--uvf-safe-area-bottom, 0), env(keyboard-inset-height, 0)) !important;
|
|
2630
2770
|
}
|
|
2631
2771
|
}
|
|
2772
|
+
|
|
2773
|
+
/* Enhanced safe area support for newer devices */
|
|
2774
|
+
@supports (padding: max(0px)) {
|
|
2775
|
+
.uvf-controls-bar {
|
|
2776
|
+
padding-bottom: max(16px, calc(16px + var(--uvf-safe-area-bottom, 0)));
|
|
2777
|
+
padding-left: max(12px, calc(12px + var(--uvf-safe-area-left, 0)));
|
|
2778
|
+
padding-right: max(12px, calc(12px + var(--uvf-safe-area-right, 0)));
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
.uvf-top-controls {
|
|
2782
|
+
top: max(10px, calc(10px + var(--uvf-safe-area-top, 0))) !important;
|
|
2783
|
+
right: max(10px, calc(10px + var(--uvf-safe-area-right, 0))) !important;
|
|
2784
|
+
}
|
|
2785
|
+
|
|
2786
|
+
.uvf-title-bar {
|
|
2787
|
+
top: max(10px, calc(10px + var(--uvf-safe-area-top, 0))) !important;
|
|
2788
|
+
left: max(10px, calc(10px + var(--uvf-safe-area-left, 0))) !important;
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
/* Specific fixes for iPhone X series and newer with notches */
|
|
2794
|
+
@media screen and (max-width: 767px) and (orientation: portrait) {
|
|
2795
|
+
@supports (top: env(safe-area-inset-top)) {
|
|
2796
|
+
.uvf-responsive-container,
|
|
2797
|
+
.uvf-player-wrapper,
|
|
2798
|
+
.uvf-video-container {
|
|
2799
|
+
height: 100vh;
|
|
2800
|
+
height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
/* Landscape orientation fixes for mobile */
|
|
2806
|
+
@media screen and (max-width: 767px) and (orientation: landscape) {
|
|
2807
|
+
html, body {
|
|
2808
|
+
height: 100vh;
|
|
2809
|
+
overflow: hidden;
|
|
2810
|
+
}
|
|
2811
|
+
|
|
2812
|
+
.uvf-responsive-container,
|
|
2813
|
+
.uvf-player-wrapper,
|
|
2814
|
+
.uvf-video-container {
|
|
2815
|
+
height: 100vh;
|
|
2816
|
+
width: 100vw;
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
@supports (height: 100dvh) {
|
|
2820
|
+
.uvf-responsive-container,
|
|
2821
|
+
.uvf-player-wrapper,
|
|
2822
|
+
.uvf-video-container {
|
|
2823
|
+
height: 100dvh;
|
|
2824
|
+
width: 100dvw;
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2632
2827
|
}
|
|
2633
2828
|
|
|
2634
2829
|
/* Enhanced Responsive Media Queries with UX Best Practices */
|
|
@@ -3941,7 +4136,13 @@ export class WebPlayer extends BasePlayer {
|
|
|
3941
4136
|
pipBtn.id = 'uvf-pip-btn';
|
|
3942
4137
|
pipBtn.title = 'Picture-in-Picture';
|
|
3943
4138
|
pipBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z"/></svg>';
|
|
3944
|
-
|
|
4139
|
+
if (this.isPictureInPictureSupported()) {
|
|
4140
|
+
rightControls.appendChild(pipBtn);
|
|
4141
|
+
this.debugLog('PiP button added - support detected');
|
|
4142
|
+
}
|
|
4143
|
+
else {
|
|
4144
|
+
this.debugLog('PiP button not added - no support detected');
|
|
4145
|
+
}
|
|
3945
4146
|
const fullscreenBtn = document.createElement('button');
|
|
3946
4147
|
fullscreenBtn.className = 'uvf-control-btn';
|
|
3947
4148
|
fullscreenBtn.id = 'uvf-fullscreen-btn';
|
|
@@ -5054,17 +5255,41 @@ export class WebPlayer extends BasePlayer {
|
|
|
5054
5255
|
this.setAutoQuality(true);
|
|
5055
5256
|
}
|
|
5056
5257
|
}
|
|
5258
|
+
isPictureInPictureActive() {
|
|
5259
|
+
const inStandardPiP = !!document.pictureInPictureElement;
|
|
5260
|
+
const inWebkitPiP = !!(this.video &&
|
|
5261
|
+
'webkitPresentationMode' in this.video &&
|
|
5262
|
+
this.video.webkitPresentationMode === 'picture-in-picture');
|
|
5263
|
+
return inStandardPiP || inWebkitPiP;
|
|
5264
|
+
}
|
|
5057
5265
|
async togglePiP() {
|
|
5266
|
+
if (!this.isPictureInPictureSupported()) {
|
|
5267
|
+
this.showShortcutIndicator('PiP not supported');
|
|
5268
|
+
this.debugWarn('PiP not supported on this device/browser');
|
|
5269
|
+
return;
|
|
5270
|
+
}
|
|
5058
5271
|
try {
|
|
5059
|
-
if (
|
|
5272
|
+
if (this.isPictureInPictureActive()) {
|
|
5060
5273
|
await this.exitPictureInPicture();
|
|
5274
|
+
this.showShortcutIndicator('Exit PiP');
|
|
5275
|
+
this.debugLog('PiP deactivated');
|
|
5061
5276
|
}
|
|
5062
5277
|
else {
|
|
5063
5278
|
await this.enterPictureInPicture();
|
|
5279
|
+
this.showShortcutIndicator('Enter PiP');
|
|
5280
|
+
this.debugLog('PiP activated');
|
|
5064
5281
|
}
|
|
5065
5282
|
}
|
|
5066
5283
|
catch (error) {
|
|
5067
|
-
|
|
5284
|
+
const errorMessage = error.message;
|
|
5285
|
+
this.showShortcutIndicator(`PiP Error: ${errorMessage}`);
|
|
5286
|
+
this.debugError('PiP toggle failed:', errorMessage);
|
|
5287
|
+
if (errorMessage.includes('not supported')) {
|
|
5288
|
+
this.showShortcutIndicator('PiP not supported');
|
|
5289
|
+
}
|
|
5290
|
+
else if (errorMessage.includes('user gesture')) {
|
|
5291
|
+
this.showShortcutIndicator('PiP requires user interaction');
|
|
5292
|
+
}
|
|
5068
5293
|
}
|
|
5069
5294
|
}
|
|
5070
5295
|
setupCastContextSafe() {
|