suada-components 1.8.0 → 1.9.0
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/dist/components/{DailyMotion-SZKPSpD1.js → DailyMotion-B7yDPBbg.js} +1 -1
- package/dist/components/{DailyMotion-jrl4eEA1.esm.js → DailyMotion-BmnymjR1.esm.js} +1 -1
- package/dist/components/{Facebook-DS0ye_bL.js → Facebook-42iqQU2G.js} +1 -1
- package/dist/components/{Facebook-Ha24RKIX.esm.js → Facebook-D9Ak6ZJU.esm.js} +1 -1
- package/dist/components/{FilePlayer-B4_DDZXQ.js → FilePlayer-CAnHK0Cd.js} +1 -1
- package/dist/components/{FilePlayer-D-n083nK.esm.js → FilePlayer-wg9lyafD.esm.js} +1 -1
- package/dist/components/{Kaltura-DAMolg_c.js → Kaltura-Ct6kwbgP.js} +1 -1
- package/dist/components/{Kaltura-BlDrsjbp.esm.js → Kaltura-DPaEN-dq.esm.js} +1 -1
- package/dist/components/{Mixcloud-B5AIgf8e.esm.js → Mixcloud-BobSN3YI.esm.js} +1 -1
- package/dist/components/{Mixcloud-C1z9BVJ8.js → Mixcloud-sBbcL5rG.js} +1 -1
- package/dist/components/{Mux-f77ctQXE.esm.js → Mux-B9YP-rFr.esm.js} +1 -1
- package/dist/components/{Mux-Bgsc5vvM.js → Mux-Cosy8sFO.js} +1 -1
- package/dist/components/{Preview-CKXk6Axz.js → Preview-DiVfo6aa.js} +1 -1
- package/dist/components/{Preview-DhMMn7e2.esm.js → Preview-XcTlhHT1.esm.js} +1 -1
- package/dist/components/{SoundCloud-DyYFhGe5.esm.js → SoundCloud-BTHoyFWT.esm.js} +1 -1
- package/dist/components/{SoundCloud-DHLHmaaB.js → SoundCloud-CIWqB-QW.js} +1 -1
- package/dist/components/{Streamable-BDhbB3m3.js → Streamable-9anYiQtU.js} +1 -1
- package/dist/components/{Streamable-BBygdIqb.esm.js → Streamable-DsfQCy3p.esm.js} +1 -1
- package/dist/components/{Twitch-CAbFCb5f.esm.js → Twitch-D1BOr8hj.esm.js} +1 -1
- package/dist/components/{Twitch-ZG7WuoXD.js → Twitch-Dud6e1Rv.js} +1 -1
- package/dist/components/VideoPlayer/pipManager.d.ts +60 -0
- package/dist/components/VideoPlayer/pipManager.js +272 -0
- package/dist/components/VideoPlayer/pipManager.js.map +1 -0
- package/dist/components/VideoPlayer/usePlayerControls.js +40 -12
- package/dist/components/VideoPlayer/usePlayerControls.js.map +1 -1
- package/dist/components/{Vidyard-CkSCnLg5.js → Vidyard-BuOu85uS.js} +1 -1
- package/dist/components/{Vidyard-BsU5Ayr6.esm.js → Vidyard-C1csjpQH.esm.js} +1 -1
- package/dist/components/{Vimeo-4uslT7bX.esm.js → Vimeo-CHlHIswX.esm.js} +1 -1
- package/dist/components/{Vimeo-DKpnTiZ8.js → Vimeo-DrDJ5O9H.js} +1 -1
- package/dist/components/{Wistia-BxvIPVO7.esm.js → Wistia-D-eYyONb.esm.js} +1 -1
- package/dist/components/{Wistia-DKdMEz2a.js → Wistia-fh9U2CA2.js} +1 -1
- package/dist/components/{YouTube-Cd4b1iuA.esm.js → YouTube-CmnnzZvk.esm.js} +1 -1
- package/dist/components/{YouTube-JSWV2_hs.js → YouTube-DC2uZ14c.js} +1 -1
- package/dist/components/components/VideoPlayer/pipManager.d.ts +60 -0
- package/dist/components/{index-BTR541gv.esm.js → index-DKAGRUEW.esm.js} +304 -26
- package/dist/components/{index-XiB9Yp2-.js → index-DetZ05pw.js} +304 -26
- package/dist/components/index.esm.js +1 -1
- package/dist/icons/components/VideoPlayer/pipManager.d.ts +60 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-
|
|
1
|
+
import { r as requireUtils, a as requirePatterns, g as getDefaultExportFromCjs } from './index-DKAGRUEW.esm.js';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
function _mergeNamespaces(n, m) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Picture-in-Picture Manager
|
|
3
|
+
* This module manages PiP state across component unmounts and route changes
|
|
4
|
+
*/
|
|
5
|
+
interface PiPVideoState {
|
|
6
|
+
url: string;
|
|
7
|
+
currentTime: number;
|
|
8
|
+
isPlaying: boolean;
|
|
9
|
+
volume: number;
|
|
10
|
+
playbackRate: number;
|
|
11
|
+
}
|
|
12
|
+
declare class PictureInPictureManager {
|
|
13
|
+
private videoElement;
|
|
14
|
+
private pipContainer;
|
|
15
|
+
private currentVideoState;
|
|
16
|
+
private onStateChange;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Register a video element for PiP management
|
|
20
|
+
*/
|
|
21
|
+
registerVideo(videoElement: HTMLVideoElement, url: string, onStateChange?: (state: PiPVideoState) => void): void;
|
|
22
|
+
/**
|
|
23
|
+
* Unregister the current video element
|
|
24
|
+
*/
|
|
25
|
+
unregisterVideo(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Create a persistent video element for PiP
|
|
28
|
+
*/
|
|
29
|
+
private createPersistentVideo;
|
|
30
|
+
/**
|
|
31
|
+
* Enter picture-in-picture mode with persistence
|
|
32
|
+
*/
|
|
33
|
+
enterPiP(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Exit picture-in-picture mode
|
|
36
|
+
*/
|
|
37
|
+
exitPiP(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Check if currently in PiP mode
|
|
40
|
+
*/
|
|
41
|
+
isPiPActive(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Get current video state
|
|
44
|
+
*/
|
|
45
|
+
getCurrentState(): PiPVideoState | null;
|
|
46
|
+
/**
|
|
47
|
+
* Restore video state to a new video element
|
|
48
|
+
*/
|
|
49
|
+
restoreStateToVideo(videoElement: HTMLVideoElement): void;
|
|
50
|
+
private handleTimeUpdate;
|
|
51
|
+
private handlePlayStateChange;
|
|
52
|
+
private handleVolumeChange;
|
|
53
|
+
private handleRateChange;
|
|
54
|
+
private handlePiPEnter;
|
|
55
|
+
private handlePiPExit;
|
|
56
|
+
private notifyStateChange;
|
|
57
|
+
private cleanup;
|
|
58
|
+
}
|
|
59
|
+
export declare const pipManager: PictureInPictureManager;
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Picture-in-Picture Manager
|
|
3
|
+
* This module manages PiP state across component unmounts and route changes
|
|
4
|
+
*/
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
15
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
16
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
17
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
18
|
+
function step(op) {
|
|
19
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
20
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
21
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
22
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
23
|
+
switch (op[0]) {
|
|
24
|
+
case 0: case 1: t = op; break;
|
|
25
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
26
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
27
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
28
|
+
default:
|
|
29
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
30
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
31
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
32
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
33
|
+
if (t[2]) _.ops.pop();
|
|
34
|
+
_.trys.pop(); continue;
|
|
35
|
+
}
|
|
36
|
+
op = body.call(thisArg, _);
|
|
37
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
38
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var PictureInPictureManager = /** @class */ (function () {
|
|
42
|
+
function PictureInPictureManager() {
|
|
43
|
+
this.videoElement = null;
|
|
44
|
+
this.pipContainer = null;
|
|
45
|
+
this.currentVideoState = null;
|
|
46
|
+
this.onStateChange = null;
|
|
47
|
+
// Listen for PiP events globally
|
|
48
|
+
document.addEventListener('leavepictureinpicture', this.handlePiPExit.bind(this));
|
|
49
|
+
document.addEventListener('enterpictureinpicture', this.handlePiPEnter.bind(this));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Register a video element for PiP management
|
|
53
|
+
*/
|
|
54
|
+
PictureInPictureManager.prototype.registerVideo = function (videoElement, url, onStateChange) {
|
|
55
|
+
this.videoElement = videoElement;
|
|
56
|
+
this.onStateChange = onStateChange || null;
|
|
57
|
+
// Store current video state
|
|
58
|
+
this.currentVideoState = {
|
|
59
|
+
url: url,
|
|
60
|
+
currentTime: videoElement.currentTime,
|
|
61
|
+
isPlaying: !videoElement.paused,
|
|
62
|
+
volume: videoElement.volume,
|
|
63
|
+
playbackRate: videoElement.playbackRate
|
|
64
|
+
};
|
|
65
|
+
// Add listeners to track state changes
|
|
66
|
+
videoElement.addEventListener('timeupdate', this.handleTimeUpdate.bind(this));
|
|
67
|
+
videoElement.addEventListener('play', this.handlePlayStateChange.bind(this));
|
|
68
|
+
videoElement.addEventListener('pause', this.handlePlayStateChange.bind(this));
|
|
69
|
+
videoElement.addEventListener('volumechange', this.handleVolumeChange.bind(this));
|
|
70
|
+
videoElement.addEventListener('ratechange', this.handleRateChange.bind(this));
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Unregister the current video element
|
|
74
|
+
*/
|
|
75
|
+
PictureInPictureManager.prototype.unregisterVideo = function () {
|
|
76
|
+
if (this.videoElement) {
|
|
77
|
+
this.videoElement.removeEventListener('timeupdate', this.handleTimeUpdate.bind(this));
|
|
78
|
+
this.videoElement.removeEventListener('play', this.handlePlayStateChange.bind(this));
|
|
79
|
+
this.videoElement.removeEventListener('pause', this.handlePlayStateChange.bind(this));
|
|
80
|
+
this.videoElement.removeEventListener('volumechange', this.handleVolumeChange.bind(this));
|
|
81
|
+
this.videoElement.removeEventListener('ratechange', this.handleRateChange.bind(this));
|
|
82
|
+
}
|
|
83
|
+
this.videoElement = null;
|
|
84
|
+
this.onStateChange = null;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Create a persistent video element for PiP
|
|
88
|
+
*/
|
|
89
|
+
PictureInPictureManager.prototype.createPersistentVideo = function (originalVideo) {
|
|
90
|
+
var persistentVideo = originalVideo.cloneNode(true);
|
|
91
|
+
// Copy all relevant properties
|
|
92
|
+
persistentVideo.src = originalVideo.src;
|
|
93
|
+
persistentVideo.currentTime = originalVideo.currentTime;
|
|
94
|
+
persistentVideo.volume = originalVideo.volume;
|
|
95
|
+
persistentVideo.playbackRate = originalVideo.playbackRate;
|
|
96
|
+
persistentVideo.muted = originalVideo.muted;
|
|
97
|
+
// Set properties for PiP
|
|
98
|
+
persistentVideo.style.position = 'fixed';
|
|
99
|
+
persistentVideo.style.top = '-9999px';
|
|
100
|
+
persistentVideo.style.left = '-9999px';
|
|
101
|
+
persistentVideo.style.width = '1px';
|
|
102
|
+
persistentVideo.style.height = '1px';
|
|
103
|
+
persistentVideo.style.opacity = '0';
|
|
104
|
+
persistentVideo.style.pointerEvents = 'none';
|
|
105
|
+
return persistentVideo;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Enter picture-in-picture mode with persistence
|
|
109
|
+
*/
|
|
110
|
+
PictureInPictureManager.prototype.enterPiP = function () {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
112
|
+
var persistentVideo_1, error_1;
|
|
113
|
+
return __generator(this, function (_a) {
|
|
114
|
+
switch (_a.label) {
|
|
115
|
+
case 0:
|
|
116
|
+
if (!this.videoElement || !document.pictureInPictureEnabled) {
|
|
117
|
+
return [2 /*return*/];
|
|
118
|
+
}
|
|
119
|
+
_a.label = 1;
|
|
120
|
+
case 1:
|
|
121
|
+
_a.trys.push([1, 6, , 7]);
|
|
122
|
+
if (!document.pictureInPictureElement) return [3 /*break*/, 3];
|
|
123
|
+
return [4 /*yield*/, document.exitPictureInPicture()];
|
|
124
|
+
case 2:
|
|
125
|
+
_a.sent();
|
|
126
|
+
_a.label = 3;
|
|
127
|
+
case 3:
|
|
128
|
+
// Create a container if it doesn't exist
|
|
129
|
+
if (!this.pipContainer) {
|
|
130
|
+
this.pipContainer = document.createElement('div');
|
|
131
|
+
this.pipContainer.id = 'suada-pip-container';
|
|
132
|
+
this.pipContainer.style.position = 'fixed';
|
|
133
|
+
this.pipContainer.style.top = '-9999px';
|
|
134
|
+
this.pipContainer.style.left = '-9999px';
|
|
135
|
+
this.pipContainer.style.width = '1px';
|
|
136
|
+
this.pipContainer.style.height = '1px';
|
|
137
|
+
this.pipContainer.style.zIndex = '-1';
|
|
138
|
+
document.body.appendChild(this.pipContainer);
|
|
139
|
+
}
|
|
140
|
+
persistentVideo_1 = this.createPersistentVideo(this.videoElement);
|
|
141
|
+
this.pipContainer.appendChild(persistentVideo_1);
|
|
142
|
+
// Wait for video to load
|
|
143
|
+
return [4 /*yield*/, new Promise(function (resolve) {
|
|
144
|
+
if (persistentVideo_1.readyState >= 2) {
|
|
145
|
+
resolve();
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
persistentVideo_1.addEventListener('loadedmetadata', function () { return resolve(); }, { once: true });
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
// Enter PiP mode
|
|
152
|
+
];
|
|
153
|
+
case 4:
|
|
154
|
+
// Wait for video to load
|
|
155
|
+
_a.sent();
|
|
156
|
+
// Enter PiP mode
|
|
157
|
+
return [4 /*yield*/, persistentVideo_1.requestPictureInPicture()
|
|
158
|
+
// Update the reference to the persistent video
|
|
159
|
+
];
|
|
160
|
+
case 5:
|
|
161
|
+
// Enter PiP mode
|
|
162
|
+
_a.sent();
|
|
163
|
+
// Update the reference to the persistent video
|
|
164
|
+
this.videoElement = persistentVideo_1;
|
|
165
|
+
return [3 /*break*/, 7];
|
|
166
|
+
case 6:
|
|
167
|
+
error_1 = _a.sent();
|
|
168
|
+
console.error('Failed to enter picture-in-picture:', error_1);
|
|
169
|
+
return [3 /*break*/, 7];
|
|
170
|
+
case 7: return [2 /*return*/];
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Exit picture-in-picture mode
|
|
177
|
+
*/
|
|
178
|
+
PictureInPictureManager.prototype.exitPiP = function () {
|
|
179
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
180
|
+
var error_2;
|
|
181
|
+
return __generator(this, function (_a) {
|
|
182
|
+
switch (_a.label) {
|
|
183
|
+
case 0:
|
|
184
|
+
_a.trys.push([0, 3, , 4]);
|
|
185
|
+
if (!document.pictureInPictureElement) return [3 /*break*/, 2];
|
|
186
|
+
return [4 /*yield*/, document.exitPictureInPicture()];
|
|
187
|
+
case 1:
|
|
188
|
+
_a.sent();
|
|
189
|
+
_a.label = 2;
|
|
190
|
+
case 2: return [3 /*break*/, 4];
|
|
191
|
+
case 3:
|
|
192
|
+
error_2 = _a.sent();
|
|
193
|
+
console.error('Failed to exit picture-in-picture:', error_2);
|
|
194
|
+
return [3 /*break*/, 4];
|
|
195
|
+
case 4: return [2 /*return*/];
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Check if currently in PiP mode
|
|
202
|
+
*/
|
|
203
|
+
PictureInPictureManager.prototype.isPiPActive = function () {
|
|
204
|
+
return !!document.pictureInPictureElement;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* Get current video state
|
|
208
|
+
*/
|
|
209
|
+
PictureInPictureManager.prototype.getCurrentState = function () {
|
|
210
|
+
return this.currentVideoState;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Restore video state to a new video element
|
|
214
|
+
*/
|
|
215
|
+
PictureInPictureManager.prototype.restoreStateToVideo = function (videoElement) {
|
|
216
|
+
if (!this.currentVideoState)
|
|
217
|
+
return;
|
|
218
|
+
videoElement.currentTime = this.currentVideoState.currentTime;
|
|
219
|
+
videoElement.volume = this.currentVideoState.volume;
|
|
220
|
+
videoElement.playbackRate = this.currentVideoState.playbackRate;
|
|
221
|
+
if (this.currentVideoState.isPlaying) {
|
|
222
|
+
videoElement.play().catch(console.error);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
PictureInPictureManager.prototype.handleTimeUpdate = function () {
|
|
226
|
+
if (this.videoElement && this.currentVideoState) {
|
|
227
|
+
this.currentVideoState.currentTime = this.videoElement.currentTime;
|
|
228
|
+
this.notifyStateChange();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
PictureInPictureManager.prototype.handlePlayStateChange = function () {
|
|
232
|
+
if (this.videoElement && this.currentVideoState) {
|
|
233
|
+
this.currentVideoState.isPlaying = !this.videoElement.paused;
|
|
234
|
+
this.notifyStateChange();
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
PictureInPictureManager.prototype.handleVolumeChange = function () {
|
|
238
|
+
if (this.videoElement && this.currentVideoState) {
|
|
239
|
+
this.currentVideoState.volume = this.videoElement.volume;
|
|
240
|
+
this.notifyStateChange();
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
PictureInPictureManager.prototype.handleRateChange = function () {
|
|
244
|
+
if (this.videoElement && this.currentVideoState) {
|
|
245
|
+
this.currentVideoState.playbackRate = this.videoElement.playbackRate;
|
|
246
|
+
this.notifyStateChange();
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
PictureInPictureManager.prototype.handlePiPEnter = function () {
|
|
250
|
+
console.log('Entered picture-in-picture mode');
|
|
251
|
+
};
|
|
252
|
+
PictureInPictureManager.prototype.handlePiPExit = function () {
|
|
253
|
+
console.log('Exited picture-in-picture mode');
|
|
254
|
+
this.cleanup();
|
|
255
|
+
};
|
|
256
|
+
PictureInPictureManager.prototype.notifyStateChange = function () {
|
|
257
|
+
if (this.onStateChange && this.currentVideoState) {
|
|
258
|
+
this.onStateChange(this.currentVideoState);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
PictureInPictureManager.prototype.cleanup = function () {
|
|
262
|
+
// Clean up the persistent container
|
|
263
|
+
if (this.pipContainer && this.pipContainer.parentNode) {
|
|
264
|
+
this.pipContainer.parentNode.removeChild(this.pipContainer);
|
|
265
|
+
this.pipContainer = null;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
return PictureInPictureManager;
|
|
269
|
+
}());
|
|
270
|
+
// Create a singleton instance
|
|
271
|
+
export var pipManager = new PictureInPictureManager();
|
|
272
|
+
//# sourceMappingURL=pipManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipManager.js","sourceRoot":"","sources":["../../../src/components/VideoPlayer/pipManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,6 +49,7 @@ import { useState, useRef, useCallback, useEffect } from 'react';
|
|
|
49
49
|
import { parseVTT } from './parseVtt';
|
|
50
50
|
import { FormatSecondsToTimeString } from './timeConversion';
|
|
51
51
|
import useEventListener from './useEventListener';
|
|
52
|
+
import { pipManager } from './pipManager';
|
|
52
53
|
var count = 0;
|
|
53
54
|
var defaultVideoState = {
|
|
54
55
|
muted: false,
|
|
@@ -105,6 +106,8 @@ function usePlayerControls(_a) {
|
|
|
105
106
|
};
|
|
106
107
|
var handlePiPLeave = function () {
|
|
107
108
|
setIsPiPActive(false);
|
|
109
|
+
// Also cleanup the PiP manager when PiP exits
|
|
110
|
+
pipManager.unregisterVideo();
|
|
108
111
|
};
|
|
109
112
|
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
|
110
113
|
document.addEventListener('enterpictureinpicture', handlePiPEnter);
|
|
@@ -128,19 +131,29 @@ function usePlayerControls(_a) {
|
|
|
128
131
|
}, [url]); // Re-run when URL changes to ensure proper cleanup and setup
|
|
129
132
|
useEffect(function () {
|
|
130
133
|
setStartPlayed(false);
|
|
131
|
-
|
|
134
|
+
// Check if there's an active PiP session and restore state
|
|
135
|
+
if (pipManager.isPiPActive()) {
|
|
136
|
+
var savedState_1 = pipManager.getCurrentState();
|
|
137
|
+
if (savedState_1 && savedState_1.url === url) {
|
|
138
|
+
setIsPiPActive(true);
|
|
139
|
+
// Restore video state from PiP manager
|
|
140
|
+
setVideoState(function (prev) {
|
|
141
|
+
var _a;
|
|
142
|
+
return (__assign(__assign({}, prev), { volume: savedState_1.volume, playbackRate: savedState_1.playbackRate, played: savedState_1.currentTime / (((_a = videoPlayerRef.current) === null || _a === void 0 ? void 0 : _a.getDuration()) || 1) }));
|
|
143
|
+
});
|
|
144
|
+
setIsPlaying(savedState_1.isPlaying);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}, [url, setIsPlaying]);
|
|
132
148
|
// Cleanup effect to handle component unmounting while in PiP mode
|
|
133
149
|
useEffect(function () {
|
|
134
|
-
var currentVideoPlayerRef = videoPlayerRef.current;
|
|
135
150
|
return function () {
|
|
151
|
+
// Unregister from PiP manager when component unmounts
|
|
152
|
+
pipManager.unregisterVideo();
|
|
136
153
|
// Check if we're in PiP mode when component unmounts
|
|
137
154
|
if (document.pictureInPictureElement) {
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
if (videoElement && videoElement instanceof HTMLVideoElement) {
|
|
141
|
-
// Create a warning for the user that PiP will exit
|
|
142
|
-
console.log('Component unmounting while in Picture-in-Picture mode');
|
|
143
|
-
}
|
|
155
|
+
// The PiP manager will handle keeping the video alive
|
|
156
|
+
console.log('Component unmounting while in Picture-in-Picture mode - PiP will persist');
|
|
144
157
|
}
|
|
145
158
|
};
|
|
146
159
|
}, []);
|
|
@@ -275,9 +288,18 @@ function usePlayerControls(_a) {
|
|
|
275
288
|
if (videoPlayerRef.current && !startPlayed) {
|
|
276
289
|
videoPlayerRef.current.seekTo(startTime);
|
|
277
290
|
setStartPlayed(true);
|
|
291
|
+
// Register video with PiP manager when it's ready
|
|
292
|
+
var videoElement = videoPlayerRef.current.getInternalPlayer();
|
|
293
|
+
if (videoElement && videoElement instanceof HTMLVideoElement) {
|
|
294
|
+
// Restore state if there was a previous PiP session
|
|
295
|
+
var savedState = pipManager.getCurrentState();
|
|
296
|
+
if (savedState && savedState.url === url && pipManager.isPiPActive()) {
|
|
297
|
+
pipManager.restoreStateToVideo(videoElement);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
278
300
|
}
|
|
279
301
|
setLoading(false);
|
|
280
|
-
}, [startTime, startPlayed, setLoading]);
|
|
302
|
+
}, [startTime, startPlayed, setLoading, url]);
|
|
281
303
|
var handleFullScreen = function () {
|
|
282
304
|
var playerContainer = playerContainerRef.current;
|
|
283
305
|
if (!playerContainer) {
|
|
@@ -301,15 +323,21 @@ function usePlayerControls(_a) {
|
|
|
301
323
|
return;
|
|
302
324
|
}
|
|
303
325
|
if (document.pictureInPictureElement) {
|
|
304
|
-
|
|
326
|
+
pipManager.exitPiP().catch(function (error) {
|
|
305
327
|
console.error('Failed to exit picture-in-picture:', error);
|
|
306
328
|
});
|
|
307
329
|
}
|
|
308
330
|
else {
|
|
331
|
+
// Register the video with the PiP manager
|
|
332
|
+
pipManager.registerVideo(videoElement, url, function (state) {
|
|
333
|
+
// Update local state when PiP video state changes
|
|
334
|
+
setVideoState(function (prev) { return (__assign(__assign({}, prev), { played: state.currentTime / duration, volume: state.volume, playbackRate: state.playbackRate })); });
|
|
335
|
+
setIsPlaying(state.isPlaying);
|
|
336
|
+
});
|
|
309
337
|
// Ensure the video is playing before entering PiP mode
|
|
310
338
|
if (videoElement.paused && isPlaying) {
|
|
311
339
|
videoElement.play().then(function () {
|
|
312
|
-
|
|
340
|
+
pipManager.enterPiP().catch(function (error) {
|
|
313
341
|
console.error('Failed to enter picture-in-picture:', error);
|
|
314
342
|
});
|
|
315
343
|
}).catch(function (error) {
|
|
@@ -317,7 +345,7 @@ function usePlayerControls(_a) {
|
|
|
317
345
|
});
|
|
318
346
|
}
|
|
319
347
|
else {
|
|
320
|
-
|
|
348
|
+
pipManager.enterPiP().catch(function (error) {
|
|
321
349
|
console.error('Failed to enter picture-in-picture:', error);
|
|
322
350
|
});
|
|
323
351
|
}
|