ts-video-player 0.1.1 → 0.1.3
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/cdn.min.js +76 -76
- package/dist/{chunk-z1ehbz9f.js → chunk-ds1nj487.js} +35 -35
- package/dist/{chunk-36x4yhjn.js → chunk-rhykj0qy.js} +58 -58
- package/dist/{chunk-eajts2jv.js → chunk-yfrrczn9.js} +221 -194
- package/dist/elements/index.js +49 -50
- package/dist/features/index.js +25 -26
- package/dist/index.js +368 -368
- package/dist/plugins/index.js +2143 -15
- package/dist/providers/html5.d.ts +4 -0
- package/dist/providers/youtube.d.ts +4 -0
- package/dist/stx/index.js +4 -4
- package/dist/ui/index.js +730 -11
- package/package.json +3 -5
- package/src/providers/html5.ts +1 -1
- package/src/providers/index.ts +36 -2
- package/src/providers/youtube.ts +18 -5
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} from "./chunk-
|
|
2
|
+
StateStore2,
|
|
3
|
+
selectBufferedAmount2,
|
|
4
|
+
createStorageSync2,
|
|
5
|
+
EventEmitter2,
|
|
6
|
+
MediaEventsNormalizer2,
|
|
7
|
+
onFullscreenChange2,
|
|
8
|
+
onPiPChange2,
|
|
9
|
+
createKeyboardHandler2,
|
|
10
|
+
createActivityDetector2,
|
|
11
|
+
detectVolumeAvailability2,
|
|
12
|
+
probeVolumeAvailability2,
|
|
13
|
+
detectFullscreenAvailability2,
|
|
14
|
+
enterFullscreen2,
|
|
15
|
+
exitFullscreen2,
|
|
16
|
+
detectPipAvailability2,
|
|
17
|
+
enterPiP2,
|
|
18
|
+
exitPiP2
|
|
19
|
+
} from "./chunk-rhykj0qy.js";
|
|
20
20
|
|
|
21
21
|
// src/core/media-session.ts
|
|
22
|
-
function
|
|
22
|
+
function isMediaSessionSupported2() {
|
|
23
23
|
return typeof navigator !== "undefined" && "mediaSession" in navigator;
|
|
24
24
|
}
|
|
25
|
-
function
|
|
26
|
-
if (!
|
|
25
|
+
function createMediaSession2(store, actions, options) {
|
|
26
|
+
if (!isMediaSessionSupported2())
|
|
27
27
|
return () => {};
|
|
28
28
|
const session = navigator.mediaSession;
|
|
29
29
|
if (options) {
|
|
30
|
-
|
|
30
|
+
updateMetadata2(options);
|
|
31
31
|
}
|
|
32
32
|
const handlers = [
|
|
33
33
|
["play", () => actions.play()],
|
|
@@ -94,8 +94,8 @@ function createMediaSession(store, actions, options) {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
function
|
|
98
|
-
if (!
|
|
97
|
+
function updateMetadata2(options) {
|
|
98
|
+
if (!isMediaSessionSupported2())
|
|
99
99
|
return;
|
|
100
100
|
navigator.mediaSession.metadata = new MediaMetadata({
|
|
101
101
|
title: options.title || "",
|
|
@@ -106,11 +106,11 @@ function updateMetadata(options) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// src/core/orientation.ts
|
|
109
|
-
function
|
|
109
|
+
function isOrientationLockSupported2() {
|
|
110
110
|
return typeof screen !== "undefined" && "orientation" in screen && typeof screen.orientation.lock === "function";
|
|
111
111
|
}
|
|
112
|
-
function
|
|
113
|
-
if (!
|
|
112
|
+
function lockOrientation2(type) {
|
|
113
|
+
if (!isOrientationLockSupported2())
|
|
114
114
|
return;
|
|
115
115
|
const orientationMap = {
|
|
116
116
|
landscape: "landscape",
|
|
@@ -119,8 +119,8 @@ function lockOrientation(type) {
|
|
|
119
119
|
};
|
|
120
120
|
screen.orientation.lock(orientationMap[type]).catch(() => {});
|
|
121
121
|
}
|
|
122
|
-
function
|
|
123
|
-
if (!
|
|
122
|
+
function unlockOrientation2() {
|
|
123
|
+
if (!isOrientationLockSupported2())
|
|
124
124
|
return;
|
|
125
125
|
try {
|
|
126
126
|
screen.orientation.unlock();
|
|
@@ -128,10 +128,10 @@ function unlockOrientation() {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
// src/providers/base.ts
|
|
131
|
-
class
|
|
131
|
+
class BaseProvider2 {
|
|
132
132
|
container = null;
|
|
133
133
|
options = {};
|
|
134
|
-
events = new
|
|
134
|
+
events = new EventEmitter2;
|
|
135
135
|
_ready = false;
|
|
136
136
|
get mediaElement() {
|
|
137
137
|
return null;
|
|
@@ -173,20 +173,20 @@ class BaseProvider {
|
|
|
173
173
|
const video = el instanceof HTMLVideoElement ? el : null;
|
|
174
174
|
switch (feature) {
|
|
175
175
|
case "volume":
|
|
176
|
-
return el && !(el instanceof HTMLMediaElement) ? "available" :
|
|
176
|
+
return el && !(el instanceof HTMLMediaElement) ? "available" : detectVolumeAvailability2(media);
|
|
177
177
|
case "fullscreen":
|
|
178
|
-
return
|
|
178
|
+
return detectFullscreenAvailability2(this.container, video);
|
|
179
179
|
case "pip":
|
|
180
|
-
return el && !(el instanceof HTMLMediaElement) ? "unsupported" :
|
|
180
|
+
return el && !(el instanceof HTMLMediaElement) ? "unsupported" : detectPipAvailability2(video);
|
|
181
181
|
default:
|
|
182
182
|
return "unsupported";
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
async enterFullscreen() {
|
|
186
|
-
await
|
|
186
|
+
await enterFullscreen2(this.container, this.mediaElement);
|
|
187
187
|
}
|
|
188
188
|
async exitFullscreen() {
|
|
189
|
-
await
|
|
189
|
+
await exitFullscreen2(this.mediaElement);
|
|
190
190
|
}
|
|
191
191
|
getFullscreenElement() {
|
|
192
192
|
return this.container;
|
|
@@ -195,10 +195,10 @@ class BaseProvider {
|
|
|
195
195
|
const media = this.mediaElement;
|
|
196
196
|
if (!media)
|
|
197
197
|
return;
|
|
198
|
-
await
|
|
198
|
+
await enterPiP2(media);
|
|
199
199
|
}
|
|
200
200
|
async exitPiP() {
|
|
201
|
-
await
|
|
201
|
+
await exitPiP2(this.mediaElement);
|
|
202
202
|
}
|
|
203
203
|
on(event, handler) {
|
|
204
204
|
this.events.on(event, handler);
|
|
@@ -212,7 +212,7 @@ class BaseProvider {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
// src/providers/html5.ts
|
|
215
|
-
function
|
|
215
|
+
function isHTML5Source2(src) {
|
|
216
216
|
if (typeof src === "string") {
|
|
217
217
|
const extension = getExtension(src);
|
|
218
218
|
if (extension === "mp4" || extension === "webm" || extension === "ogg" || extension === "ogv" || extension === "mov" || extension === "mp3" || extension === "wav" || extension === "flac" || extension === "m4a" || extension === "aac" || extension === "oga" || extension === "opus") {
|
|
@@ -249,7 +249,7 @@ function getMimeType(src) {
|
|
|
249
249
|
return mimeTypes[ext || ""] || "video/mp4";
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
class
|
|
252
|
+
class HTML5Provider2 extends BaseProvider2 {
|
|
253
253
|
name = "html5";
|
|
254
254
|
type = "video";
|
|
255
255
|
media = null;
|
|
@@ -294,12 +294,12 @@ class HTML5Provider extends BaseProvider {
|
|
|
294
294
|
this.container.appendChild(this.media);
|
|
295
295
|
for (const track of this.options.tracks ?? [])
|
|
296
296
|
this.addTextTrack(track);
|
|
297
|
-
this.eventsNormalizer = new
|
|
298
|
-
this.cleanupFullscreen =
|
|
297
|
+
this.eventsNormalizer = new MediaEventsNormalizer2(this.media, this.events);
|
|
298
|
+
this.cleanupFullscreen = onFullscreenChange2((fullscreen) => {
|
|
299
299
|
this.events.emit("fullscreenchange", fullscreen);
|
|
300
300
|
});
|
|
301
301
|
if (!this.isAudio && this.media instanceof HTMLVideoElement) {
|
|
302
|
-
this.cleanupPiP =
|
|
302
|
+
this.cleanupPiP = onPiPChange2(this.media, (pip) => {
|
|
303
303
|
this.events.emit("pipchange", pip);
|
|
304
304
|
});
|
|
305
305
|
}
|
|
@@ -327,7 +327,7 @@ class HTML5Provider extends BaseProvider {
|
|
|
327
327
|
this.media.addEventListener("loadeddata", () => {
|
|
328
328
|
if (!this.media)
|
|
329
329
|
return;
|
|
330
|
-
|
|
330
|
+
probeVolumeAvailability2(this.media).then((availability) => {
|
|
331
331
|
this.events.emit("statechange", {
|
|
332
332
|
volumeAvailability: availability
|
|
333
333
|
});
|
|
@@ -357,7 +357,7 @@ class HTML5Provider extends BaseProvider {
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
canPlay(src) {
|
|
360
|
-
return
|
|
360
|
+
return isHTML5Source2(src);
|
|
361
361
|
}
|
|
362
362
|
async load(src) {
|
|
363
363
|
if (!this.media)
|
|
@@ -522,11 +522,11 @@ class HTML5Provider extends BaseProvider {
|
|
|
522
522
|
this.media.appendChild(track);
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
|
-
var
|
|
525
|
+
var html5Loader2 = {
|
|
526
526
|
name: "html5",
|
|
527
527
|
type: "video",
|
|
528
528
|
canPlay(src) {
|
|
529
|
-
return
|
|
529
|
+
return isHTML5Source2(src);
|
|
530
530
|
},
|
|
531
531
|
mediaType(src) {
|
|
532
532
|
if (typeof src === "string") {
|
|
@@ -544,7 +544,7 @@ var html5Loader = {
|
|
|
544
544
|
return "video";
|
|
545
545
|
},
|
|
546
546
|
async load(container, options) {
|
|
547
|
-
const provider = new
|
|
547
|
+
const provider = new HTML5Provider2;
|
|
548
548
|
await provider.setup(container, options);
|
|
549
549
|
return provider;
|
|
550
550
|
}
|
|
@@ -555,7 +555,7 @@ var YOUTUBE_PATTERNS = [
|
|
|
555
555
|
/youtube\.com\/v\/([a-zA-Z0-9_-]{11})/,
|
|
556
556
|
/youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/
|
|
557
557
|
];
|
|
558
|
-
function
|
|
558
|
+
function extractYouTubeId2(url) {
|
|
559
559
|
for (const pattern of YOUTUBE_PATTERNS) {
|
|
560
560
|
const match = url.match(pattern);
|
|
561
561
|
if (match)
|
|
@@ -563,9 +563,9 @@ function extractYouTubeId(url) {
|
|
|
563
563
|
}
|
|
564
564
|
return null;
|
|
565
565
|
}
|
|
566
|
-
function
|
|
566
|
+
function isYouTubeSource2(src) {
|
|
567
567
|
if (typeof src === "string") {
|
|
568
|
-
return
|
|
568
|
+
return extractYouTubeId2(src) !== null;
|
|
569
569
|
}
|
|
570
570
|
if (typeof src === "object" && "type" in src) {
|
|
571
571
|
return src.type === "youtube";
|
|
@@ -574,7 +574,7 @@ function isYouTubeSource(src) {
|
|
|
574
574
|
}
|
|
575
575
|
function parseYouTubeSource(src) {
|
|
576
576
|
if (typeof src === "string") {
|
|
577
|
-
const videoId =
|
|
577
|
+
const videoId = extractYouTubeId2(src);
|
|
578
578
|
if (!videoId)
|
|
579
579
|
return null;
|
|
580
580
|
const url = new URL(src, "https://youtube.com");
|
|
@@ -589,7 +589,7 @@ function parseYouTubeSource(src) {
|
|
|
589
589
|
if (typeof src === "object" && "type" in src && src.type === "youtube") {
|
|
590
590
|
const ytSrc = src;
|
|
591
591
|
return {
|
|
592
|
-
videoId: ytSrc.videoId ||
|
|
592
|
+
videoId: ytSrc.videoId || extractYouTubeId2(ytSrc.src) || "",
|
|
593
593
|
startTime: ytSrc.startTime,
|
|
594
594
|
endTime: ytSrc.endTime
|
|
595
595
|
};
|
|
@@ -614,12 +614,13 @@ function parseTime(time) {
|
|
|
614
614
|
return 0;
|
|
615
615
|
}
|
|
616
616
|
|
|
617
|
-
class
|
|
617
|
+
class YouTubeProvider2 extends BaseProvider2 {
|
|
618
618
|
name = "youtube";
|
|
619
619
|
type = "youtube";
|
|
620
620
|
player = null;
|
|
621
621
|
iframe = null;
|
|
622
622
|
pendingVideoId = null;
|
|
623
|
+
playerReady = false;
|
|
623
624
|
startTime;
|
|
624
625
|
endTime;
|
|
625
626
|
timeUpdateInterval = null;
|
|
@@ -650,8 +651,8 @@ class YouTubeProvider extends BaseProvider {
|
|
|
650
651
|
if (this.options.youtubeParams) {
|
|
651
652
|
Object.assign(playerVars, this.options.youtubeParams);
|
|
652
653
|
}
|
|
653
|
-
|
|
654
|
-
|
|
654
|
+
this.player = new window.YT.Player(playerDiv, {
|
|
655
|
+
host: "https://www.youtube-nocookie.com",
|
|
655
656
|
width: "100%",
|
|
656
657
|
height: "100%",
|
|
657
658
|
playerVars,
|
|
@@ -697,9 +698,11 @@ class YouTubeProvider extends BaseProvider {
|
|
|
697
698
|
}
|
|
698
699
|
this.player?.destroy();
|
|
699
700
|
this.player = null;
|
|
701
|
+
this.playerReady = false;
|
|
700
702
|
this.iframe = null;
|
|
701
703
|
}
|
|
702
704
|
onReady() {
|
|
705
|
+
this.playerReady = true;
|
|
703
706
|
this.timeUpdateInterval = setInterval(() => {
|
|
704
707
|
if (this.player && this.lastState === 1) {
|
|
705
708
|
this.events.emit("timeupdate", this.getCurrentTime());
|
|
@@ -762,7 +765,7 @@ class YouTubeProvider extends BaseProvider {
|
|
|
762
765
|
this.events.emit("ratechange", this.getPlaybackRate());
|
|
763
766
|
}
|
|
764
767
|
canPlay(src) {
|
|
765
|
-
return
|
|
768
|
+
return isYouTubeSource2(src);
|
|
766
769
|
}
|
|
767
770
|
async load(src) {
|
|
768
771
|
const parsed = parseYouTubeSource(src);
|
|
@@ -772,7 +775,7 @@ class YouTubeProvider extends BaseProvider {
|
|
|
772
775
|
}
|
|
773
776
|
this.startTime = parsed.startTime;
|
|
774
777
|
this.endTime = parsed.endTime;
|
|
775
|
-
if (!this.player || !this._ready) {
|
|
778
|
+
if (!this.player || !this._ready || !this.playerReady) {
|
|
776
779
|
this.pendingVideoId = parsed.videoId;
|
|
777
780
|
return;
|
|
778
781
|
}
|
|
@@ -869,11 +872,11 @@ class YouTubeProvider extends BaseProvider {
|
|
|
869
872
|
}
|
|
870
873
|
}
|
|
871
874
|
}
|
|
872
|
-
var
|
|
875
|
+
var youtubeLoader2 = {
|
|
873
876
|
name: "youtube",
|
|
874
877
|
type: "youtube",
|
|
875
878
|
canPlay(src) {
|
|
876
|
-
return
|
|
879
|
+
return isYouTubeSource2(src);
|
|
877
880
|
},
|
|
878
881
|
mediaType() {
|
|
879
882
|
return "video";
|
|
@@ -887,7 +890,7 @@ var youtubeLoader = {
|
|
|
887
890
|
];
|
|
888
891
|
},
|
|
889
892
|
async load(container, options) {
|
|
890
|
-
const provider = new
|
|
893
|
+
const provider = new YouTubeProvider2;
|
|
891
894
|
await provider.setup(container, options);
|
|
892
895
|
return provider;
|
|
893
896
|
}
|
|
@@ -900,7 +903,7 @@ var VIMEO_PATTERNS = [
|
|
|
900
903
|
/vimeo\.com\/channels\/[\w]+\/(\d+)/,
|
|
901
904
|
/vimeo\.com\/groups\/[\w]+\/videos\/(\d+)/
|
|
902
905
|
];
|
|
903
|
-
function
|
|
906
|
+
function extractVimeoId2(url) {
|
|
904
907
|
for (const pattern of VIMEO_PATTERNS) {
|
|
905
908
|
const match = url.match(pattern);
|
|
906
909
|
if (match)
|
|
@@ -908,13 +911,13 @@ function extractVimeoId(url) {
|
|
|
908
911
|
}
|
|
909
912
|
return null;
|
|
910
913
|
}
|
|
911
|
-
function
|
|
914
|
+
function extractVimeoHash2(url) {
|
|
912
915
|
const match = url.match(/vimeo\.com\/\d+\/([a-f0-9]+)/);
|
|
913
916
|
return match ? match[1] : null;
|
|
914
917
|
}
|
|
915
|
-
function
|
|
918
|
+
function isVimeoSource2(src) {
|
|
916
919
|
if (typeof src === "string") {
|
|
917
|
-
return
|
|
920
|
+
return extractVimeoId2(src) !== null;
|
|
918
921
|
}
|
|
919
922
|
if (typeof src === "object" && "type" in src) {
|
|
920
923
|
return src.type === "vimeo";
|
|
@@ -923,15 +926,15 @@ function isVimeoSource(src) {
|
|
|
923
926
|
}
|
|
924
927
|
function parseVimeoSource(src) {
|
|
925
928
|
if (typeof src === "string") {
|
|
926
|
-
const videoId =
|
|
929
|
+
const videoId = extractVimeoId2(src);
|
|
927
930
|
if (!videoId)
|
|
928
931
|
return null;
|
|
929
|
-
return { videoId, hash:
|
|
932
|
+
return { videoId, hash: extractVimeoHash2(src) || undefined };
|
|
930
933
|
}
|
|
931
934
|
if (typeof src === "object" && "type" in src && src.type === "vimeo") {
|
|
932
935
|
const vSrc = src;
|
|
933
936
|
return {
|
|
934
|
-
videoId: vSrc.videoId ||
|
|
937
|
+
videoId: vSrc.videoId || extractVimeoId2(vSrc.src) || "",
|
|
935
938
|
hash: vSrc.hash
|
|
936
939
|
};
|
|
937
940
|
}
|
|
@@ -939,7 +942,7 @@ function parseVimeoSource(src) {
|
|
|
939
942
|
}
|
|
940
943
|
var VIMEO_SDK_URL = "https://player.vimeo.com/api/player.js";
|
|
941
944
|
|
|
942
|
-
class
|
|
945
|
+
class VimeoProvider2 extends BaseProvider2 {
|
|
943
946
|
name = "vimeo";
|
|
944
947
|
type = "vimeo";
|
|
945
948
|
container_el = null;
|
|
@@ -994,7 +997,7 @@ class VimeoProvider extends BaseProvider {
|
|
|
994
997
|
this.container_el = null;
|
|
995
998
|
}
|
|
996
999
|
canPlay(src) {
|
|
997
|
-
return
|
|
1000
|
+
return isVimeoSource2(src);
|
|
998
1001
|
}
|
|
999
1002
|
async load(src) {
|
|
1000
1003
|
const parsed = parseVimeoSource(src);
|
|
@@ -1185,11 +1188,11 @@ class VimeoProvider extends BaseProvider {
|
|
|
1185
1188
|
}
|
|
1186
1189
|
}
|
|
1187
1190
|
}
|
|
1188
|
-
var
|
|
1191
|
+
var vimeoLoader2 = {
|
|
1189
1192
|
name: "vimeo",
|
|
1190
1193
|
type: "vimeo",
|
|
1191
1194
|
canPlay(src) {
|
|
1192
|
-
return
|
|
1195
|
+
return isVimeoSource2(src);
|
|
1193
1196
|
},
|
|
1194
1197
|
mediaType() {
|
|
1195
1198
|
return "video";
|
|
@@ -1198,13 +1201,13 @@ var vimeoLoader = {
|
|
|
1198
1201
|
return ["https://player.vimeo.com", "https://i.vimeocdn.com", "https://f.vimeocdn.com"];
|
|
1199
1202
|
},
|
|
1200
1203
|
async load(container, options) {
|
|
1201
|
-
const provider = new
|
|
1204
|
+
const provider = new VimeoProvider2;
|
|
1202
1205
|
await provider.setup(container, options);
|
|
1203
1206
|
return provider;
|
|
1204
1207
|
}
|
|
1205
1208
|
};
|
|
1206
1209
|
// src/providers/hls.ts
|
|
1207
|
-
function
|
|
1210
|
+
function isHLSSource2(src) {
|
|
1208
1211
|
if (typeof src === "string") {
|
|
1209
1212
|
const url = src.toLowerCase();
|
|
1210
1213
|
return url.endsWith(".m3u8") || url.includes("application/x-mpegurl") || url.includes("application/vnd.apple.mpegurl");
|
|
@@ -1215,13 +1218,13 @@ function isHLSSource(src) {
|
|
|
1215
1218
|
}
|
|
1216
1219
|
return false;
|
|
1217
1220
|
}
|
|
1218
|
-
function
|
|
1221
|
+
function isNativeHLSSupported2() {
|
|
1219
1222
|
const video = document.createElement("video");
|
|
1220
1223
|
return video.canPlayType("application/vnd.apple.mpegurl") !== "";
|
|
1221
1224
|
}
|
|
1222
1225
|
var HLS_CDN_DEFAULT = "https://cdn.jsdelivr.net/npm/hls.js@latest/dist/hls.min.js";
|
|
1223
1226
|
|
|
1224
|
-
class
|
|
1227
|
+
class HLSProvider2 extends BaseProvider2 {
|
|
1225
1228
|
name = "hls";
|
|
1226
1229
|
type = "hls";
|
|
1227
1230
|
video = null;
|
|
@@ -1266,14 +1269,14 @@ class HLSProvider extends BaseProvider {
|
|
|
1266
1269
|
if (this.options.volume !== undefined)
|
|
1267
1270
|
this.video.volume = this.options.volume;
|
|
1268
1271
|
this.container.appendChild(this.video);
|
|
1269
|
-
this.eventsNormalizer = new
|
|
1270
|
-
this.cleanupFullscreen =
|
|
1272
|
+
this.eventsNormalizer = new MediaEventsNormalizer2(this.video, this.events);
|
|
1273
|
+
this.cleanupFullscreen = onFullscreenChange2((fullscreen) => {
|
|
1271
1274
|
this.events.emit("fullscreenchange", fullscreen);
|
|
1272
1275
|
});
|
|
1273
|
-
this.cleanupPiP =
|
|
1276
|
+
this.cleanupPiP = onPiPChange2(this.video, (pip) => {
|
|
1274
1277
|
this.events.emit("pipchange", pip);
|
|
1275
1278
|
});
|
|
1276
|
-
this.useNativeHLS =
|
|
1279
|
+
this.useNativeHLS = isNativeHLSSupported2();
|
|
1277
1280
|
if (!this.useNativeHLS) {
|
|
1278
1281
|
await this.loadHLSLibrary();
|
|
1279
1282
|
}
|
|
@@ -1328,7 +1331,7 @@ class HLSProvider extends BaseProvider {
|
|
|
1328
1331
|
this._textTracks = [];
|
|
1329
1332
|
}
|
|
1330
1333
|
canPlay(src) {
|
|
1331
|
-
return
|
|
1334
|
+
return isHLSSource2(src);
|
|
1332
1335
|
}
|
|
1333
1336
|
async load(src) {
|
|
1334
1337
|
if (!this.video)
|
|
@@ -1549,11 +1552,11 @@ class HLSProvider extends BaseProvider {
|
|
|
1549
1552
|
this.events.emit("texttrackchange", current || null);
|
|
1550
1553
|
}
|
|
1551
1554
|
}
|
|
1552
|
-
var
|
|
1555
|
+
var hlsLoader2 = {
|
|
1553
1556
|
name: "hls",
|
|
1554
1557
|
type: "hls",
|
|
1555
1558
|
canPlay(src) {
|
|
1556
|
-
return
|
|
1559
|
+
return isHLSSource2(src);
|
|
1557
1560
|
},
|
|
1558
1561
|
mediaType() {
|
|
1559
1562
|
return "video";
|
|
@@ -1562,7 +1565,7 @@ var hlsLoader = {
|
|
|
1562
1565
|
return ["https://cdn.jsdelivr.net"];
|
|
1563
1566
|
},
|
|
1564
1567
|
async load(container, options) {
|
|
1565
|
-
const provider = new
|
|
1568
|
+
const provider = new HLSProvider2;
|
|
1566
1569
|
await provider.setup(container, options);
|
|
1567
1570
|
return provider;
|
|
1568
1571
|
}
|
|
@@ -1596,7 +1599,7 @@ async function loadDashJS(cdnUrl) {
|
|
|
1596
1599
|
});
|
|
1597
1600
|
return dashLoading;
|
|
1598
1601
|
}
|
|
1599
|
-
function
|
|
1602
|
+
function isDASHSource2(src) {
|
|
1600
1603
|
if (typeof src === "object" && "type" in src && src.type === "dash") {
|
|
1601
1604
|
return true;
|
|
1602
1605
|
}
|
|
@@ -1606,7 +1609,7 @@ function isDASHSource(src) {
|
|
|
1606
1609
|
return false;
|
|
1607
1610
|
}
|
|
1608
1611
|
|
|
1609
|
-
class
|
|
1612
|
+
class DASHProvider2 extends BaseProvider2 {
|
|
1610
1613
|
name = "dash";
|
|
1611
1614
|
type = "dash";
|
|
1612
1615
|
dash = null;
|
|
@@ -1739,7 +1742,7 @@ class DASHProvider extends BaseProvider {
|
|
|
1739
1742
|
return;
|
|
1740
1743
|
if (typeof src === "string") {
|
|
1741
1744
|
this.source = { src, type: "dash" };
|
|
1742
|
-
} else if (
|
|
1745
|
+
} else if (isDASHSource2(src)) {
|
|
1743
1746
|
this.source = src;
|
|
1744
1747
|
} else {
|
|
1745
1748
|
this.emitError(4, "Invalid DASH source");
|
|
@@ -1751,7 +1754,7 @@ class DASHProvider extends BaseProvider {
|
|
|
1751
1754
|
this.dash.initialize(this.video, this.source.src, false);
|
|
1752
1755
|
}
|
|
1753
1756
|
canPlay(src) {
|
|
1754
|
-
return
|
|
1757
|
+
return isDASHSource2(src);
|
|
1755
1758
|
}
|
|
1756
1759
|
cleanup() {
|
|
1757
1760
|
if (this.dash) {
|
|
@@ -1928,17 +1931,17 @@ class DASHProvider extends BaseProvider {
|
|
|
1928
1931
|
}
|
|
1929
1932
|
}
|
|
1930
1933
|
}
|
|
1931
|
-
var
|
|
1934
|
+
var dashLoader2 = {
|
|
1932
1935
|
name: "dash",
|
|
1933
1936
|
type: "dash",
|
|
1934
1937
|
canPlay(src) {
|
|
1935
|
-
return
|
|
1938
|
+
return isDASHSource2(src);
|
|
1936
1939
|
},
|
|
1937
1940
|
mediaType() {
|
|
1938
1941
|
return "video";
|
|
1939
1942
|
},
|
|
1940
1943
|
async load(container, options) {
|
|
1941
|
-
const provider = new
|
|
1944
|
+
const provider = new DASHProvider2;
|
|
1942
1945
|
await provider.setup(container, options);
|
|
1943
1946
|
return provider;
|
|
1944
1947
|
},
|
|
@@ -1947,45 +1950,69 @@ var dashLoader = {
|
|
|
1947
1950
|
}
|
|
1948
1951
|
};
|
|
1949
1952
|
// src/providers/index.ts
|
|
1950
|
-
var
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1953
|
+
var defaultLoaders2 = [
|
|
1954
|
+
hlsLoader2,
|
|
1955
|
+
dashLoader2,
|
|
1956
|
+
youtubeLoader2,
|
|
1957
|
+
vimeoLoader2,
|
|
1958
|
+
html5Loader2
|
|
1956
1959
|
];
|
|
1957
|
-
function
|
|
1960
|
+
function untypedUrl(src) {
|
|
1961
|
+
if (!src || typeof src !== "object" || typeof src.src !== "string")
|
|
1962
|
+
return null;
|
|
1963
|
+
return "type" in src && src.type ? null : src.src;
|
|
1964
|
+
}
|
|
1965
|
+
var TYPE_FOR_LOADER = {
|
|
1966
|
+
youtube: () => "youtube",
|
|
1967
|
+
vimeo: () => "vimeo",
|
|
1968
|
+
hls: () => "application/x-mpegurl",
|
|
1969
|
+
dash: () => "dash",
|
|
1970
|
+
video: (url) => getMimeType(url)
|
|
1971
|
+
};
|
|
1972
|
+
function withType(src, loader) {
|
|
1973
|
+
const url = untypedUrl(src);
|
|
1974
|
+
const type = url && TYPE_FOR_LOADER[loader.type];
|
|
1975
|
+
return url && type ? { ...src, type: type(url) } : src;
|
|
1976
|
+
}
|
|
1977
|
+
function findLoader2(src, loaders = defaultLoaders2) {
|
|
1958
1978
|
for (const loader of loaders) {
|
|
1959
1979
|
if (loader.canPlay(src)) {
|
|
1960
1980
|
return loader;
|
|
1961
1981
|
}
|
|
1962
1982
|
}
|
|
1983
|
+
const url = untypedUrl(src);
|
|
1984
|
+
if (url) {
|
|
1985
|
+
for (const loader of loaders) {
|
|
1986
|
+
if (loader.canPlay(url))
|
|
1987
|
+
return loader;
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1963
1990
|
return null;
|
|
1964
1991
|
}
|
|
1965
|
-
function findSourceCandidates(sources, loaders =
|
|
1992
|
+
function findSourceCandidates(sources, loaders = defaultLoaders2) {
|
|
1966
1993
|
const candidates = [];
|
|
1967
1994
|
sources.forEach((src, index) => {
|
|
1968
|
-
const loader =
|
|
1995
|
+
const loader = findLoader2(src, loaders);
|
|
1969
1996
|
if (loader)
|
|
1970
|
-
candidates.push({ src, index, loader });
|
|
1997
|
+
candidates.push({ src: withType(src, loader), index, loader });
|
|
1971
1998
|
});
|
|
1972
1999
|
return candidates;
|
|
1973
2000
|
}
|
|
1974
|
-
function
|
|
1975
|
-
const loader =
|
|
2001
|
+
function detectMediaType2(src, loaders = defaultLoaders2) {
|
|
2002
|
+
const loader = findLoader2(src, loaders);
|
|
1976
2003
|
return loader?.mediaType(src) || "unknown";
|
|
1977
2004
|
}
|
|
1978
|
-
function
|
|
1979
|
-
const loader =
|
|
2005
|
+
function getPreconnectHints2(src, loaders = defaultLoaders2) {
|
|
2006
|
+
const loader = findLoader2(src, loaders);
|
|
1980
2007
|
return loader?.preconnect?.() || [];
|
|
1981
2008
|
}
|
|
1982
2009
|
|
|
1983
2010
|
// src/player.ts
|
|
1984
|
-
class
|
|
2011
|
+
class Player2 {
|
|
1985
2012
|
_el;
|
|
1986
2013
|
_options;
|
|
1987
2014
|
_store;
|
|
1988
|
-
_events = new
|
|
2015
|
+
_events = new EventEmitter2;
|
|
1989
2016
|
_provider = null;
|
|
1990
2017
|
_loaders;
|
|
1991
2018
|
_cleanupFns = [];
|
|
@@ -2002,8 +2029,8 @@ class Player {
|
|
|
2002
2029
|
this._el = container;
|
|
2003
2030
|
}
|
|
2004
2031
|
this._options = { ...defaultOptions, ...options };
|
|
2005
|
-
this._loaders =
|
|
2006
|
-
this._store = new
|
|
2032
|
+
this._loaders = defaultLoaders2;
|
|
2033
|
+
this._store = new StateStore2;
|
|
2007
2034
|
this.setupElement();
|
|
2008
2035
|
this.setupState();
|
|
2009
2036
|
this.setupKeyboard();
|
|
@@ -2088,7 +2115,7 @@ class Player {
|
|
|
2088
2115
|
seekPercent: (percent) => this.seekTo(percent / 100 * this.state.duration)
|
|
2089
2116
|
};
|
|
2090
2117
|
const config = typeof this._options.keyboard === "object" ? this._options.keyboard : {};
|
|
2091
|
-
const handler =
|
|
2118
|
+
const handler = createKeyboardHandler2(actions, {
|
|
2092
2119
|
seekStep: config.seekStep,
|
|
2093
2120
|
volumeStep: config.volumeStep
|
|
2094
2121
|
});
|
|
@@ -2097,7 +2124,7 @@ class Player {
|
|
|
2097
2124
|
this._cleanupFns.push(() => target.removeEventListener("keydown", handler));
|
|
2098
2125
|
}
|
|
2099
2126
|
setupActivity() {
|
|
2100
|
-
const cleanup =
|
|
2127
|
+
const cleanup = createActivityDetector2(this._el, {
|
|
2101
2128
|
timeout: this._options.controlsTimeout || 3000,
|
|
2102
2129
|
onActive: () => {
|
|
2103
2130
|
this._store.batch({ userActive: true, controlsVisible: true });
|
|
@@ -2124,14 +2151,14 @@ class Player {
|
|
|
2124
2151
|
return;
|
|
2125
2152
|
const config = typeof this._options.storage === "object" ? this._options.storage : {};
|
|
2126
2153
|
const storage = config.type === "session" ? sessionStorage : localStorage;
|
|
2127
|
-
const cleanup =
|
|
2154
|
+
const cleanup = createStorageSync2(this._store, config.persist || ["volume", "muted", "playbackRate"], storage);
|
|
2128
2155
|
this._cleanupFns.push(cleanup);
|
|
2129
2156
|
}
|
|
2130
2157
|
setupMediaSession() {
|
|
2131
2158
|
if (this._options.mediaSession === false)
|
|
2132
2159
|
return;
|
|
2133
2160
|
const sessionOpts = typeof this._options.mediaSession === "object" ? this._options.mediaSession : this._options.title ? { title: this._options.title } : undefined;
|
|
2134
|
-
const cleanup =
|
|
2161
|
+
const cleanup = createMediaSession2(this._store, {
|
|
2135
2162
|
play: () => this.play(),
|
|
2136
2163
|
pause: () => this.pause(),
|
|
2137
2164
|
seekTo: (time) => this.seekTo(time),
|
|
@@ -2353,7 +2380,7 @@ class Player {
|
|
|
2353
2380
|
provider.on("progress", (buffered) => {
|
|
2354
2381
|
this._store.batch({
|
|
2355
2382
|
buffered,
|
|
2356
|
-
bufferedAmount:
|
|
2383
|
+
bufferedAmount: selectBufferedAmount2({ ...this.state, buffered })
|
|
2357
2384
|
});
|
|
2358
2385
|
this._events.emit("progress", buffered);
|
|
2359
2386
|
});
|
|
@@ -2451,13 +2478,13 @@ class Player {
|
|
|
2451
2478
|
}
|
|
2452
2479
|
await this._provider?.enterFullscreen();
|
|
2453
2480
|
if (this._options.fullscreenOrientationLock !== false) {
|
|
2454
|
-
|
|
2481
|
+
lockOrientation2("landscape");
|
|
2455
2482
|
}
|
|
2456
2483
|
}
|
|
2457
2484
|
async exitFullscreen() {
|
|
2458
2485
|
await this._provider?.exitFullscreen();
|
|
2459
2486
|
if (this._options.fullscreenOrientationLock !== false) {
|
|
2460
|
-
|
|
2487
|
+
unlockOrientation2();
|
|
2461
2488
|
}
|
|
2462
2489
|
}
|
|
2463
2490
|
async toggleFullscreen() {
|
|
@@ -2539,10 +2566,10 @@ var defaultOptions = {
|
|
|
2539
2566
|
controlsTimeout: 3000,
|
|
2540
2567
|
storage: true
|
|
2541
2568
|
};
|
|
2542
|
-
function
|
|
2543
|
-
return new
|
|
2569
|
+
function createPlayer2(container, options) {
|
|
2570
|
+
return new Player2(container, options);
|
|
2544
2571
|
}
|
|
2545
|
-
function
|
|
2572
|
+
function getPlayer2(element) {
|
|
2546
2573
|
return element.__videoPlayer || null;
|
|
2547
2574
|
}
|
|
2548
2575
|
|
|
@@ -2553,7 +2580,7 @@ var HTMLElementBase = globalThis.HTMLElement ?? class {
|
|
|
2553
2580
|
// src/elements/video-player.ts
|
|
2554
2581
|
var OBSERVED_ATTRS = ["src", "poster", "autoplay", "loop", "muted", "controls", "volume", "playback-rate", "preload", "playsinline", "crossorigin", "controlslist", "disable-picture-in-picture"];
|
|
2555
2582
|
|
|
2556
|
-
class
|
|
2583
|
+
class VideoPlayerElement2 extends HTMLElementBase {
|
|
2557
2584
|
_player = null;
|
|
2558
2585
|
_container = null;
|
|
2559
2586
|
_disconnectId = 0;
|
|
@@ -2575,7 +2602,7 @@ class VideoPlayerElement extends HTMLElementBase {
|
|
|
2575
2602
|
this._container.appendChild(slot);
|
|
2576
2603
|
shadow.appendChild(this._container);
|
|
2577
2604
|
const options = this.buildOptions();
|
|
2578
|
-
this._player = new
|
|
2605
|
+
this._player = new Player2(this._container, options);
|
|
2579
2606
|
this.forwardEvents();
|
|
2580
2607
|
}
|
|
2581
2608
|
disconnectedCallback() {
|
|
@@ -2717,7 +2744,7 @@ class VideoPlayerElement extends HTMLElementBase {
|
|
|
2717
2744
|
}
|
|
2718
2745
|
}
|
|
2719
2746
|
// src/elements/utils.ts
|
|
2720
|
-
function
|
|
2747
|
+
function formatTime2(seconds, guide = 0) {
|
|
2721
2748
|
if (!isFinite(seconds) || isNaN(seconds))
|
|
2722
2749
|
return "0:00";
|
|
2723
2750
|
const s = Math.floor(seconds);
|
|
@@ -2730,7 +2757,7 @@ function formatTime(seconds, guide = 0) {
|
|
|
2730
2757
|
}
|
|
2731
2758
|
return `${m}:${sec.toString().padStart(2, "0")}`;
|
|
2732
2759
|
}
|
|
2733
|
-
function
|
|
2760
|
+
function formatTimePhrase2(seconds) {
|
|
2734
2761
|
if (!isFinite(seconds) || isNaN(seconds))
|
|
2735
2762
|
return "0 seconds";
|
|
2736
2763
|
const s = Math.floor(seconds);
|
|
@@ -2746,7 +2773,7 @@ function formatTimePhrase(seconds) {
|
|
|
2746
2773
|
parts.push(`${sec} ${sec === 1 ? "second" : "seconds"}`);
|
|
2747
2774
|
return parts.join(", ");
|
|
2748
2775
|
}
|
|
2749
|
-
function
|
|
2776
|
+
function toISODuration2(seconds) {
|
|
2750
2777
|
if (!isFinite(seconds) || isNaN(seconds))
|
|
2751
2778
|
return "PT0S";
|
|
2752
2779
|
const s = Math.floor(seconds);
|
|
@@ -2762,7 +2789,7 @@ function toISODuration(seconds) {
|
|
|
2762
2789
|
result += `${sec}S`;
|
|
2763
2790
|
return result;
|
|
2764
2791
|
}
|
|
2765
|
-
function
|
|
2792
|
+
function resolvePlayer2(el) {
|
|
2766
2793
|
const forId = el.getAttribute("for");
|
|
2767
2794
|
if (forId) {
|
|
2768
2795
|
const target = document.getElementById(forId);
|
|
@@ -2773,7 +2800,7 @@ function resolvePlayer(el) {
|
|
|
2773
2800
|
}
|
|
2774
2801
|
|
|
2775
2802
|
// src/elements/video-skin.ts
|
|
2776
|
-
class
|
|
2803
|
+
class VideoSkin2 extends HTMLElementBase {
|
|
2777
2804
|
_cleanups = [];
|
|
2778
2805
|
connectedCallback() {
|
|
2779
2806
|
if (!this.shadowRoot) {
|
|
@@ -2846,7 +2873,7 @@ class VideoSkin extends HTMLElementBase {
|
|
|
2846
2873
|
this._cleanups = [];
|
|
2847
2874
|
}
|
|
2848
2875
|
attach() {
|
|
2849
|
-
const player =
|
|
2876
|
+
const player = resolvePlayer2(this);
|
|
2850
2877
|
if (!player)
|
|
2851
2878
|
return;
|
|
2852
2879
|
const unsub = player.subscribe((state) => {
|
|
@@ -2871,7 +2898,7 @@ class VideoSkin extends HTMLElementBase {
|
|
|
2871
2898
|
var PLAY_ICON = "M8 5v14l11-7z";
|
|
2872
2899
|
var PAUSE_ICON = "M6 19h4V5H6v14zm8-14v14h4V5h-4z";
|
|
2873
2900
|
|
|
2874
|
-
class
|
|
2901
|
+
class MediaPlayButton2 extends HTMLElementBase {
|
|
2875
2902
|
_cleanup = null;
|
|
2876
2903
|
_onClick = null;
|
|
2877
2904
|
connectedCallback() {
|
|
@@ -2905,7 +2932,7 @@ class MediaPlayButton extends HTMLElementBase {
|
|
|
2905
2932
|
this._onClick = null;
|
|
2906
2933
|
}
|
|
2907
2934
|
attach() {
|
|
2908
|
-
const player =
|
|
2935
|
+
const player = resolvePlayer2(this);
|
|
2909
2936
|
if (!player)
|
|
2910
2937
|
return;
|
|
2911
2938
|
const btn = this.shadowRoot.querySelector("button");
|
|
@@ -2933,7 +2960,7 @@ function getVolumeIcon(muted, volume) {
|
|
|
2933
2960
|
return ICON_HIGH;
|
|
2934
2961
|
}
|
|
2935
2962
|
|
|
2936
|
-
class
|
|
2963
|
+
class MediaMuteButton2 extends HTMLElementBase {
|
|
2937
2964
|
_cleanup = null;
|
|
2938
2965
|
connectedCallback() {
|
|
2939
2966
|
if (!this.shadowRoot) {
|
|
@@ -2962,7 +2989,7 @@ class MediaMuteButton extends HTMLElementBase {
|
|
|
2962
2989
|
this._cleanup = null;
|
|
2963
2990
|
}
|
|
2964
2991
|
attach() {
|
|
2965
|
-
const player =
|
|
2992
|
+
const player = resolvePlayer2(this);
|
|
2966
2993
|
if (!player)
|
|
2967
2994
|
return;
|
|
2968
2995
|
const btn = this.shadowRoot.querySelector("button");
|
|
@@ -2980,7 +3007,7 @@ class MediaMuteButton extends HTMLElementBase {
|
|
|
2980
3007
|
var ENTER_FS = "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z";
|
|
2981
3008
|
var EXIT_FS = "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z";
|
|
2982
3009
|
|
|
2983
|
-
class
|
|
3010
|
+
class MediaFullscreenButton2 extends HTMLElementBase {
|
|
2984
3011
|
_cleanup = null;
|
|
2985
3012
|
connectedCallback() {
|
|
2986
3013
|
if (!this.shadowRoot) {
|
|
@@ -3011,7 +3038,7 @@ class MediaFullscreenButton extends HTMLElementBase {
|
|
|
3011
3038
|
this._cleanup = null;
|
|
3012
3039
|
}
|
|
3013
3040
|
attach() {
|
|
3014
|
-
const player =
|
|
3041
|
+
const player = resolvePlayer2(this);
|
|
3015
3042
|
if (!player)
|
|
3016
3043
|
return;
|
|
3017
3044
|
const btn = this.shadowRoot.querySelector("button");
|
|
@@ -3035,7 +3062,7 @@ class MediaFullscreenButton extends HTMLElementBase {
|
|
|
3035
3062
|
// src/elements/media-pip-button.ts
|
|
3036
3063
|
var PIP_ICON = "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";
|
|
3037
3064
|
|
|
3038
|
-
class
|
|
3065
|
+
class MediaPipButton2 extends HTMLElementBase {
|
|
3039
3066
|
_cleanup = null;
|
|
3040
3067
|
connectedCallback() {
|
|
3041
3068
|
if (!this.shadowRoot) {
|
|
@@ -3066,7 +3093,7 @@ class MediaPipButton extends HTMLElementBase {
|
|
|
3066
3093
|
this._cleanup = null;
|
|
3067
3094
|
}
|
|
3068
3095
|
attach() {
|
|
3069
|
-
const player =
|
|
3096
|
+
const player = resolvePlayer2(this);
|
|
3070
3097
|
if (!player)
|
|
3071
3098
|
return;
|
|
3072
3099
|
const btn = this.shadowRoot.querySelector("button");
|
|
@@ -3084,7 +3111,7 @@ class MediaPipButton extends HTMLElementBase {
|
|
|
3084
3111
|
}
|
|
3085
3112
|
}
|
|
3086
3113
|
// src/elements/media-time-display.ts
|
|
3087
|
-
class
|
|
3114
|
+
class MediaTimeDisplay2 extends HTMLElementBase {
|
|
3088
3115
|
_cleanup = null;
|
|
3089
3116
|
_showRemaining = false;
|
|
3090
3117
|
static get observedAttributes() {
|
|
@@ -3123,13 +3150,13 @@ class MediaTimeDisplay extends HTMLElementBase {
|
|
|
3123
3150
|
handleClick = () => {
|
|
3124
3151
|
if (this.type === "duration") {
|
|
3125
3152
|
this._showRemaining = !this._showRemaining;
|
|
3126
|
-
const player =
|
|
3153
|
+
const player = resolvePlayer2(this);
|
|
3127
3154
|
if (player)
|
|
3128
3155
|
this.render(player.state);
|
|
3129
3156
|
}
|
|
3130
3157
|
};
|
|
3131
3158
|
attach() {
|
|
3132
|
-
const player =
|
|
3159
|
+
const player = resolvePlayer2(this);
|
|
3133
3160
|
if (!player)
|
|
3134
3161
|
return;
|
|
3135
3162
|
const unsub = player.subscribe((state) => {
|
|
@@ -3145,21 +3172,21 @@ class MediaTimeDisplay extends HTMLElementBase {
|
|
|
3145
3172
|
let seconds;
|
|
3146
3173
|
if (type === "remaining" || type === "duration" && this._showRemaining) {
|
|
3147
3174
|
seconds = Math.max(state.duration - state.currentTime, 0);
|
|
3148
|
-
const formatted = `-${
|
|
3175
|
+
const formatted = `-${formatTime2(seconds, state.duration)}`;
|
|
3149
3176
|
timeEl.textContent = formatted;
|
|
3150
3177
|
} else if (type === "duration") {
|
|
3151
3178
|
seconds = state.duration;
|
|
3152
|
-
timeEl.textContent =
|
|
3179
|
+
timeEl.textContent = formatTime2(seconds);
|
|
3153
3180
|
} else {
|
|
3154
3181
|
seconds = state.currentTime;
|
|
3155
|
-
timeEl.textContent =
|
|
3182
|
+
timeEl.textContent = formatTime2(seconds, state.duration);
|
|
3156
3183
|
}
|
|
3157
|
-
timeEl.setAttribute("datetime",
|
|
3158
|
-
timeEl.setAttribute("aria-valuetext",
|
|
3184
|
+
timeEl.setAttribute("datetime", toISODuration2(seconds));
|
|
3185
|
+
timeEl.setAttribute("aria-valuetext", formatTimePhrase2(seconds));
|
|
3159
3186
|
}
|
|
3160
3187
|
}
|
|
3161
3188
|
// src/elements/media-time-group.ts
|
|
3162
|
-
class
|
|
3189
|
+
class MediaTimeGroup2 extends HTMLElementBase {
|
|
3163
3190
|
connectedCallback() {
|
|
3164
3191
|
if (!this.shadowRoot) {
|
|
3165
3192
|
const shadow = this.attachShadow({ mode: "open" });
|
|
@@ -3181,7 +3208,7 @@ class MediaTimeGroup extends HTMLElementBase {
|
|
|
3181
3208
|
}
|
|
3182
3209
|
}
|
|
3183
3210
|
// src/elements/media-time-separator.ts
|
|
3184
|
-
class
|
|
3211
|
+
class MediaTimeSeparator2 extends HTMLElementBase {
|
|
3185
3212
|
connectedCallback() {
|
|
3186
3213
|
if (!this.shadowRoot) {
|
|
3187
3214
|
const shadow = this.attachShadow({ mode: "open" });
|
|
@@ -3205,7 +3232,7 @@ class MediaTimeSeparator extends HTMLElementBase {
|
|
|
3205
3232
|
}
|
|
3206
3233
|
}
|
|
3207
3234
|
// src/elements/media-preview-time.ts
|
|
3208
|
-
class
|
|
3235
|
+
class MediaPreviewTime2 extends HTMLElementBase {
|
|
3209
3236
|
_cleanups = [];
|
|
3210
3237
|
connectedCallback() {
|
|
3211
3238
|
if (!this.shadowRoot) {
|
|
@@ -3231,7 +3258,7 @@ class MediaPreviewTime extends HTMLElementBase {
|
|
|
3231
3258
|
this._cleanups = [];
|
|
3232
3259
|
}
|
|
3233
3260
|
attach() {
|
|
3234
|
-
const player =
|
|
3261
|
+
const player = resolvePlayer2(this);
|
|
3235
3262
|
if (!player)
|
|
3236
3263
|
return;
|
|
3237
3264
|
const progressBar = this.closest("media-progress-bar") || this.parentElement?.querySelector("media-progress-bar");
|
|
@@ -3251,12 +3278,12 @@ class MediaPreviewTime extends HTMLElementBase {
|
|
|
3251
3278
|
updateTime(time, duration) {
|
|
3252
3279
|
const span = this.shadowRoot?.querySelector("span");
|
|
3253
3280
|
if (span) {
|
|
3254
|
-
span.textContent =
|
|
3281
|
+
span.textContent = formatTime2(time, duration);
|
|
3255
3282
|
}
|
|
3256
3283
|
}
|
|
3257
3284
|
}
|
|
3258
3285
|
// src/elements/media-progress-bar.ts
|
|
3259
|
-
class
|
|
3286
|
+
class MediaProgressBar2 extends HTMLElementBase {
|
|
3260
3287
|
_cleanups = [];
|
|
3261
3288
|
_isDragging = false;
|
|
3262
3289
|
connectedCallback() {
|
|
@@ -3331,7 +3358,7 @@ class MediaProgressBar extends HTMLElementBase {
|
|
|
3331
3358
|
this._cleanups = [];
|
|
3332
3359
|
}
|
|
3333
3360
|
attach() {
|
|
3334
|
-
const player =
|
|
3361
|
+
const player = resolvePlayer2(this);
|
|
3335
3362
|
if (!player)
|
|
3336
3363
|
return;
|
|
3337
3364
|
const container = this.shadowRoot.querySelector(".container");
|
|
@@ -3352,7 +3379,7 @@ class MediaProgressBar extends HTMLElementBase {
|
|
|
3352
3379
|
const rect = track.getBoundingClientRect();
|
|
3353
3380
|
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
3354
3381
|
const time = percent * (player.state.duration || 0);
|
|
3355
|
-
tooltip.textContent =
|
|
3382
|
+
tooltip.textContent = formatTime2(time, player.state.duration);
|
|
3356
3383
|
const containerRect = container.getBoundingClientRect();
|
|
3357
3384
|
const tooltipWidth = tooltip.offsetWidth;
|
|
3358
3385
|
const rawLeft = e.clientX - containerRect.left;
|
|
@@ -3419,7 +3446,7 @@ class MediaProgressBar extends HTMLElementBase {
|
|
|
3419
3446
|
fill.style.width = `${percent}%`;
|
|
3420
3447
|
thumb.style.left = `${percent}%`;
|
|
3421
3448
|
container.setAttribute("aria-valuenow", String(Math.round(percent)));
|
|
3422
|
-
container.setAttribute("aria-valuetext", `${
|
|
3449
|
+
container.setAttribute("aria-valuetext", `${formatTimePhrase2(state.currentTime)} of ${formatTimePhrase2(duration)}`);
|
|
3423
3450
|
const bufferedPct = (state.bufferedAmount || 0) * 100;
|
|
3424
3451
|
buffered.style.width = `${bufferedPct}%`;
|
|
3425
3452
|
});
|
|
@@ -3427,7 +3454,7 @@ class MediaProgressBar extends HTMLElementBase {
|
|
|
3427
3454
|
}
|
|
3428
3455
|
}
|
|
3429
3456
|
// src/elements/media-volume-slider.ts
|
|
3430
|
-
class
|
|
3457
|
+
class MediaVolumeSlider2 extends HTMLElementBase {
|
|
3431
3458
|
_cleanups = [];
|
|
3432
3459
|
_isDragging = false;
|
|
3433
3460
|
connectedCallback() {
|
|
@@ -3476,7 +3503,7 @@ class MediaVolumeSlider extends HTMLElementBase {
|
|
|
3476
3503
|
this._cleanups = [];
|
|
3477
3504
|
}
|
|
3478
3505
|
attach() {
|
|
3479
|
-
const player =
|
|
3506
|
+
const player = resolvePlayer2(this);
|
|
3480
3507
|
if (!player)
|
|
3481
3508
|
return;
|
|
3482
3509
|
const container = this.shadowRoot.querySelector(".container");
|
|
@@ -3545,7 +3572,7 @@ class MediaVolumeSlider extends HTMLElementBase {
|
|
|
3545
3572
|
}
|
|
3546
3573
|
}
|
|
3547
3574
|
// src/core/popover.ts
|
|
3548
|
-
function
|
|
3575
|
+
function computePosition2(anchor, popover, options = {}) {
|
|
3549
3576
|
const {
|
|
3550
3577
|
placement = "top",
|
|
3551
3578
|
offset = 4,
|
|
@@ -3595,11 +3622,11 @@ function computePosition(anchor, popover, options = {}) {
|
|
|
3595
3622
|
const finalPlacement = `${vertical}${align}`;
|
|
3596
3623
|
return { top, left, placement: finalPlacement };
|
|
3597
3624
|
}
|
|
3598
|
-
function
|
|
3625
|
+
function applyPosition2(anchor, popover, options = {}) {
|
|
3599
3626
|
const prevVisibility = popover.style.visibility;
|
|
3600
3627
|
popover.style.visibility = "hidden";
|
|
3601
3628
|
popover.style.display = "block";
|
|
3602
|
-
const result =
|
|
3629
|
+
const result = computePosition2(anchor, popover, options);
|
|
3603
3630
|
const offsetParent = popover.offsetParent;
|
|
3604
3631
|
if (offsetParent) {
|
|
3605
3632
|
const parentRect = offsetParent.getBoundingClientRect();
|
|
@@ -3617,7 +3644,7 @@ function applyPosition(anchor, popover, options = {}) {
|
|
|
3617
3644
|
var GEAR_ICON = "M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z";
|
|
3618
3645
|
var SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
3619
3646
|
|
|
3620
|
-
class
|
|
3647
|
+
class MediaSettingsMenu2 extends HTMLElementBase {
|
|
3621
3648
|
_cleanup = null;
|
|
3622
3649
|
_isOpen = false;
|
|
3623
3650
|
_currentPanel = "main";
|
|
@@ -3720,7 +3747,7 @@ class MediaSettingsMenu extends HTMLElementBase {
|
|
|
3720
3747
|
if (!trigger || !menu)
|
|
3721
3748
|
return;
|
|
3722
3749
|
const playerEl = this.closest("video-player, .ts-video-player");
|
|
3723
|
-
const result =
|
|
3750
|
+
const result = computePosition2(trigger, menu, {
|
|
3724
3751
|
placement: "top-end",
|
|
3725
3752
|
offset: 4,
|
|
3726
3753
|
boundary: playerEl,
|
|
@@ -3730,7 +3757,7 @@ class MediaSettingsMenu extends HTMLElementBase {
|
|
|
3730
3757
|
menu.style.left = `${result.left}px`;
|
|
3731
3758
|
}
|
|
3732
3759
|
attach() {
|
|
3733
|
-
const player =
|
|
3760
|
+
const player = resolvePlayer2(this);
|
|
3734
3761
|
if (!player)
|
|
3735
3762
|
return;
|
|
3736
3763
|
const unsub = player.subscribe(() => {
|
|
@@ -3740,7 +3767,7 @@ class MediaSettingsMenu extends HTMLElementBase {
|
|
|
3740
3767
|
this._cleanup = unsub;
|
|
3741
3768
|
}
|
|
3742
3769
|
renderPanel() {
|
|
3743
|
-
const player =
|
|
3770
|
+
const player = resolvePlayer2(this);
|
|
3744
3771
|
if (!player)
|
|
3745
3772
|
return;
|
|
3746
3773
|
const menu = this.shadowRoot.querySelector(".menu");
|
|
@@ -3870,7 +3897,7 @@ class MediaSettingsMenu extends HTMLElementBase {
|
|
|
3870
3897
|
}
|
|
3871
3898
|
}
|
|
3872
3899
|
// src/elements/media-seek-button.ts
|
|
3873
|
-
class
|
|
3900
|
+
class MediaSeekButton2 extends HTMLElementBase {
|
|
3874
3901
|
cleanup = null;
|
|
3875
3902
|
onClick = null;
|
|
3876
3903
|
connectedCallback() {
|
|
@@ -3898,7 +3925,7 @@ class MediaSeekButton extends HTMLElementBase {
|
|
|
3898
3925
|
this.onClick = null;
|
|
3899
3926
|
}
|
|
3900
3927
|
attach() {
|
|
3901
|
-
const player =
|
|
3928
|
+
const player = resolvePlayer2(this);
|
|
3902
3929
|
const button = this.shadowRoot?.querySelector("button");
|
|
3903
3930
|
if (!player || !button)
|
|
3904
3931
|
return;
|
|
@@ -3917,7 +3944,7 @@ class MediaSeekButton extends HTMLElementBase {
|
|
|
3917
3944
|
// src/elements/media-playback-rate-button.ts
|
|
3918
3945
|
var defaultRates = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
3919
3946
|
|
|
3920
|
-
class
|
|
3947
|
+
class MediaPlaybackRateButton2 extends HTMLElementBase {
|
|
3921
3948
|
cleanup = null;
|
|
3922
3949
|
onClick = null;
|
|
3923
3950
|
connectedCallback() {
|
|
@@ -3948,7 +3975,7 @@ class MediaPlaybackRateButton extends HTMLElementBase {
|
|
|
3948
3975
|
return [...new Set(rates.length > 0 ? rates : defaultRates)].sort((a, b) => a - b);
|
|
3949
3976
|
}
|
|
3950
3977
|
attach() {
|
|
3951
|
-
const player =
|
|
3978
|
+
const player = resolvePlayer2(this);
|
|
3952
3979
|
const button = this.shadowRoot?.querySelector("button");
|
|
3953
3980
|
if (!player || !button)
|
|
3954
3981
|
return;
|
|
@@ -3967,7 +3994,7 @@ class MediaPlaybackRateButton extends HTMLElementBase {
|
|
|
3967
3994
|
// src/elements/media-airplay-button.ts
|
|
3968
3995
|
var AIRPLAY_ICON = "M6.2 19h11.6L12 13.2 6.2 19zM19 3H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h2v-2H5V5h14v10h-2v2h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z";
|
|
3969
3996
|
|
|
3970
|
-
class
|
|
3997
|
+
class MediaAirplayButton2 extends HTMLElementBase {
|
|
3971
3998
|
cleanup = null;
|
|
3972
3999
|
connectedCallback() {
|
|
3973
4000
|
if (!this.shadowRoot) {
|
|
@@ -3992,7 +4019,7 @@ class MediaAirplayButton extends HTMLElementBase {
|
|
|
3992
4019
|
this.cleanup = null;
|
|
3993
4020
|
}
|
|
3994
4021
|
attach() {
|
|
3995
|
-
const player =
|
|
4022
|
+
const player = resolvePlayer2(this);
|
|
3996
4023
|
const button = this.shadowRoot?.querySelector("button");
|
|
3997
4024
|
if (!player || !button)
|
|
3998
4025
|
return;
|
|
@@ -4026,7 +4053,7 @@ class MediaAirplayButton extends HTMLElementBase {
|
|
|
4026
4053
|
}
|
|
4027
4054
|
}
|
|
4028
4055
|
// src/elements/media-live-button.ts
|
|
4029
|
-
class
|
|
4056
|
+
class MediaLiveButton2 extends HTMLElementBase {
|
|
4030
4057
|
cleanup = null;
|
|
4031
4058
|
connectedCallback() {
|
|
4032
4059
|
if (!this.shadowRoot) {
|
|
@@ -4049,7 +4076,7 @@ class MediaLiveButton extends HTMLElementBase {
|
|
|
4049
4076
|
this.cleanup = null;
|
|
4050
4077
|
}
|
|
4051
4078
|
attach() {
|
|
4052
|
-
const player =
|
|
4079
|
+
const player = resolvePlayer2(this);
|
|
4053
4080
|
const button = this.shadowRoot?.querySelector("button");
|
|
4054
4081
|
if (!player || !button)
|
|
4055
4082
|
return;
|
|
@@ -4081,7 +4108,7 @@ class MediaLiveButton extends HTMLElementBase {
|
|
|
4081
4108
|
}
|
|
4082
4109
|
}
|
|
4083
4110
|
// src/elements/media-error-display.ts
|
|
4084
|
-
class
|
|
4111
|
+
class MediaErrorDisplay2 extends HTMLElementBase {
|
|
4085
4112
|
cleanup = null;
|
|
4086
4113
|
connectedCallback() {
|
|
4087
4114
|
if (!this.shadowRoot) {
|
|
@@ -4102,7 +4129,7 @@ class MediaErrorDisplay extends HTMLElementBase {
|
|
|
4102
4129
|
this.cleanup = null;
|
|
4103
4130
|
}
|
|
4104
4131
|
attach() {
|
|
4105
|
-
const player =
|
|
4132
|
+
const player = resolvePlayer2(this);
|
|
4106
4133
|
const message = this.shadowRoot?.querySelector("p");
|
|
4107
4134
|
if (!player || !message)
|
|
4108
4135
|
return;
|
|
@@ -4122,7 +4149,7 @@ class MediaErrorDisplay extends HTMLElementBase {
|
|
|
4122
4149
|
// src/elements/media-remote-playback-button.ts
|
|
4123
4150
|
var REMOTE_ICON = "M1 18v3h3a3 3 0 0 0-3-3zm0-4v2a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7zm0-4v2c5 0 9 4 9 9h2c0-6.1-4.9-11-11-11zm18-7H5a2 2 0 0 0-2 2v3h2V5h14v10h-5v2h5a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z";
|
|
4124
4151
|
|
|
4125
|
-
class
|
|
4152
|
+
class MediaRemotePlaybackButton2 extends HTMLElementBase {
|
|
4126
4153
|
cleanup = null;
|
|
4127
4154
|
connectedCallback() {
|
|
4128
4155
|
if (!this.shadowRoot) {
|
|
@@ -4147,7 +4174,7 @@ class MediaRemotePlaybackButton extends HTMLElementBase {
|
|
|
4147
4174
|
this.cleanup = null;
|
|
4148
4175
|
}
|
|
4149
4176
|
attach() {
|
|
4150
|
-
const player =
|
|
4177
|
+
const player = resolvePlayer2(this);
|
|
4151
4178
|
const button = this.shadowRoot?.querySelector("button");
|
|
4152
4179
|
if (!player || !button)
|
|
4153
4180
|
return;
|
|
@@ -4210,27 +4237,27 @@ class MediaRemotePlaybackButton extends HTMLElementBase {
|
|
|
4210
4237
|
}
|
|
4211
4238
|
// src/elements/index.ts
|
|
4212
4239
|
var elements = [
|
|
4213
|
-
["video-player",
|
|
4214
|
-
["video-skin",
|
|
4215
|
-
["media-play-button",
|
|
4216
|
-
["media-mute-button",
|
|
4217
|
-
["media-fullscreen-button",
|
|
4218
|
-
["media-pip-button",
|
|
4219
|
-
["media-time-display",
|
|
4220
|
-
["media-time-group",
|
|
4221
|
-
["media-time-separator",
|
|
4222
|
-
["media-preview-time",
|
|
4223
|
-
["media-progress-bar",
|
|
4224
|
-
["media-volume-slider",
|
|
4225
|
-
["media-settings-menu",
|
|
4226
|
-
["media-seek-button",
|
|
4227
|
-
["media-playback-rate-button",
|
|
4228
|
-
["media-airplay-button",
|
|
4229
|
-
["media-live-button",
|
|
4230
|
-
["media-error-display",
|
|
4231
|
-
["media-remote-playback-button",
|
|
4240
|
+
["video-player", VideoPlayerElement2],
|
|
4241
|
+
["video-skin", VideoSkin2],
|
|
4242
|
+
["media-play-button", MediaPlayButton2],
|
|
4243
|
+
["media-mute-button", MediaMuteButton2],
|
|
4244
|
+
["media-fullscreen-button", MediaFullscreenButton2],
|
|
4245
|
+
["media-pip-button", MediaPipButton2],
|
|
4246
|
+
["media-time-display", MediaTimeDisplay2],
|
|
4247
|
+
["media-time-group", MediaTimeGroup2],
|
|
4248
|
+
["media-time-separator", MediaTimeSeparator2],
|
|
4249
|
+
["media-preview-time", MediaPreviewTime2],
|
|
4250
|
+
["media-progress-bar", MediaProgressBar2],
|
|
4251
|
+
["media-volume-slider", MediaVolumeSlider2],
|
|
4252
|
+
["media-settings-menu", MediaSettingsMenu2],
|
|
4253
|
+
["media-seek-button", MediaSeekButton2],
|
|
4254
|
+
["media-playback-rate-button", MediaPlaybackRateButton2],
|
|
4255
|
+
["media-airplay-button", MediaAirplayButton2],
|
|
4256
|
+
["media-live-button", MediaLiveButton2],
|
|
4257
|
+
["media-error-display", MediaErrorDisplay2],
|
|
4258
|
+
["media-remote-playback-button", MediaRemotePlaybackButton2]
|
|
4232
4259
|
];
|
|
4233
|
-
function
|
|
4260
|
+
function registerElements2() {
|
|
4234
4261
|
for (const [name, ctor] of elements) {
|
|
4235
4262
|
if (!customElements.get(name)) {
|
|
4236
4263
|
customElements.define(name, ctor);
|
|
@@ -4238,4 +4265,4 @@ function registerElements() {
|
|
|
4238
4265
|
}
|
|
4239
4266
|
}
|
|
4240
4267
|
|
|
4241
|
-
export {
|
|
4268
|
+
export { isMediaSessionSupported2, createMediaSession2, updateMetadata2, isOrientationLockSupported2, lockOrientation2, unlockOrientation2, BaseProvider2, isHTML5Source2, HTML5Provider2, html5Loader2, extractYouTubeId2, isYouTubeSource2, YouTubeProvider2, youtubeLoader2, extractVimeoId2, extractVimeoHash2, isVimeoSource2, VimeoProvider2, vimeoLoader2, isHLSSource2, isNativeHLSSupported2, HLSProvider2, hlsLoader2, isDASHSource2, DASHProvider2, dashLoader2, defaultLoaders2, findLoader2, detectMediaType2, getPreconnectHints2, Player2, createPlayer2, getPlayer2, VideoPlayerElement2, formatTime2, formatTimePhrase2, toISODuration2, resolvePlayer2, VideoSkin2, MediaPlayButton2, MediaMuteButton2, MediaFullscreenButton2, MediaPipButton2, MediaTimeDisplay2, MediaTimeGroup2, MediaTimeSeparator2, MediaPreviewTime2, MediaProgressBar2, MediaVolumeSlider2, computePosition2, applyPosition2, MediaSettingsMenu2, MediaSeekButton2, MediaPlaybackRateButton2, MediaAirplayButton2, MediaLiveButton2, MediaErrorDisplay2, MediaRemotePlaybackButton2, registerElements2 };
|