vidply 1.1.19 → 1.2.1
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/README.md +13 -6
- package/dist/dev/{vidply.AudioDescriptionManager-NRMNKZAL.js → vidply.AudioDescriptionManager-6RFVF27Z.js} +281 -23
- package/dist/dev/vidply.AudioDescriptionManager-6RFVF27Z.js.map +7 -0
- package/dist/dev/vidply.CaptionStyleMenu-R2SCQ6VP.js +300 -0
- package/dist/dev/vidply.CaptionStyleMenu-R2SCQ6VP.js.map +7 -0
- package/dist/dev/{vidply.DASHRenderer-SYXX6RRS.js → vidply.DASHRenderer-EOVEW73H.js} +39 -32
- package/dist/dev/vidply.DASHRenderer-EOVEW73H.js.map +7 -0
- package/dist/dev/{vidply.FloatingPlayerManager-HJVGUQLT.js → vidply.FloatingPlayerManager-V5XQWS75.js} +10 -5
- package/dist/dev/vidply.FloatingPlayerManager-V5XQWS75.js.map +7 -0
- package/dist/dev/{vidply.HLSRenderer-YAFEUBMC.js → vidply.HLSRenderer-ZBEFVH5W.js} +80 -45
- package/dist/dev/vidply.HLSRenderer-ZBEFVH5W.js.map +7 -0
- package/dist/dev/vidply.HTML5Renderer-P7ICKYU4.js +12 -0
- package/dist/dev/{vidply.SignLanguageManager-ZZ6DIDTP.js → vidply.SignLanguageManager-7IAJOVF6.js} +14 -13
- package/dist/dev/vidply.SignLanguageManager-7IAJOVF6.js.map +7 -0
- package/dist/dev/{vidply.SoundCloudRenderer-OFBGL7UV.js → vidply.SoundCloudRenderer-OA7QQYGN.js} +30 -18
- package/dist/dev/vidply.SoundCloudRenderer-OA7QQYGN.js.map +7 -0
- package/dist/dev/{vidply.TranscriptManager-4553RRA6.js → vidply.TranscriptManager-BPM3T23L.js} +24 -21
- package/dist/dev/vidply.TranscriptManager-BPM3T23L.js.map +7 -0
- package/dist/dev/{vidply.VimeoRenderer-EVW2RNSF.js → vidply.VimeoRenderer-BRHFYPNJ.js} +8 -9
- package/dist/dev/vidply.VimeoRenderer-BRHFYPNJ.js.map +7 -0
- package/dist/dev/{vidply.YouTubeRenderer-PZHT3GMF.js → vidply.YouTubeRenderer-HRTN4EJ5.js} +10 -25
- package/dist/dev/vidply.YouTubeRenderer-HRTN4EJ5.js.map +7 -0
- package/dist/dev/vidply.chunk-5IK3IC5V.js +57 -0
- package/dist/dev/vidply.chunk-5IK3IC5V.js.map +7 -0
- package/dist/dev/{vidply.chunk-RQGZAPWY.js → vidply.chunk-C55OBT5H.js} +5 -2
- package/dist/dev/vidply.chunk-C55OBT5H.js.map +7 -0
- package/dist/dev/vidply.chunk-HOYEMJSD.js +87 -0
- package/dist/dev/vidply.chunk-HOYEMJSD.js.map +7 -0
- package/dist/dev/{vidply.chunk-24QLI7ZK.js → vidply.chunk-JAKZNGOR.js} +2 -2
- package/dist/dev/vidply.chunk-JAKZNGOR.js.map +7 -0
- package/dist/dev/{vidply.chunk-AQDY6B5B.js → vidply.chunk-LDVFAFGC.js} +15 -48
- package/dist/dev/vidply.chunk-LDVFAFGC.js.map +7 -0
- package/dist/dev/{vidply.chunk-KMACPXZ5.js → vidply.chunk-NSMAZCMB.js} +10 -9
- package/dist/dev/vidply.chunk-NSMAZCMB.js.map +7 -0
- package/dist/dev/{vidply.chunk-MQAA3FKI.js → vidply.chunk-RQG3MA7W.js} +2 -2
- package/dist/dev/vidply.chunk-RQG3MA7W.js.map +7 -0
- package/dist/dev/{vidply.chunk-QF77EYBM.js → vidply.chunk-UHMVDBDB.js} +7 -4
- package/dist/dev/{vidply.chunk-QF77EYBM.js.map → vidply.chunk-UHMVDBDB.js.map} +2 -2
- package/dist/dev/{vidply.chunk-TM5HFGG5.js → vidply.chunk-W5BR65JY.js} +35 -19
- package/dist/dev/vidply.chunk-W5BR65JY.js.map +7 -0
- package/dist/dev/{vidply.chunk-PTYRD6ZP.js → vidply.chunk-XAK3DPTO.js} +28 -24
- package/dist/dev/vidply.chunk-XAK3DPTO.js.map +7 -0
- package/dist/dev/{vidply.chunk-NUTGO3RK.js → vidply.chunk-YVCYQZJI.js} +6 -6
- package/dist/dev/vidply.chunk-YVCYQZJI.js.map +7 -0
- package/dist/dev/{vidply.de-27ZM6TOB.js → vidply.de-5W5LBFSJ.js} +2 -2
- package/dist/dev/{vidply.es-XNGJJLWC.js → vidply.es-SHDAT6L6.js} +2 -2
- package/dist/dev/vidply.esm.js +270 -391
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/dev/{vidply.fr-AVZKPUBH.js → vidply.fr-2JANOMNB.js} +2 -2
- package/dist/dev/{vidply.ja-IZK2UXDC.js → vidply.ja-WWMSTEJH.js} +2 -2
- package/dist/legacy/vidply.js +1185 -565
- package/dist/legacy/vidply.js.map +4 -4
- package/dist/legacy/vidply.min.js +2 -2
- package/dist/legacy/vidply.min.meta.json +157 -56
- package/dist/prod/vidply.AudioDescriptionManager-YTDVDQBO.min.js +6 -0
- package/dist/prod/vidply.CaptionStyleMenu-2AFF3HF2.min.js +6 -0
- package/dist/prod/vidply.DASHRenderer-URDOTOKS.min.js +6 -0
- package/dist/prod/{vidply.FloatingPlayerManager-FNM5V76W.min.js → vidply.FloatingPlayerManager-QUBFK7CQ.min.js} +2 -2
- package/dist/prod/vidply.HLSRenderer-46KNUVAB.min.js +6 -0
- package/dist/prod/vidply.HTML5Renderer-7TQDMIGY.min.js +6 -0
- package/dist/prod/vidply.SignLanguageManager-H4C36EVL.min.js +6 -0
- package/dist/prod/vidply.SoundCloudRenderer-OYSWMW7D.min.js +6 -0
- package/dist/prod/vidply.TranscriptManager-BA3DAS63.min.js +6 -0
- package/dist/prod/vidply.VimeoRenderer-NF3COTHU.min.js +6 -0
- package/dist/prod/vidply.YouTubeRenderer-UCQKYIJ4.min.js +6 -0
- package/dist/prod/vidply.chunk-2HNCP64N.min.js +6 -0
- package/dist/prod/vidply.chunk-6ECBIYVI.min.js +6 -0
- package/dist/prod/vidply.chunk-7S5AFTST.min.js +6 -0
- package/dist/prod/vidply.chunk-EUOA2DJK.min.js +6 -0
- package/dist/prod/vidply.chunk-G6KGXNEW.min.js +6 -0
- package/dist/prod/{vidply.chunk-WE6VR5E2.min.js → vidply.chunk-JPMAK3NS.min.js} +1 -1
- package/dist/prod/{vidply.chunk-D7PUX3IJ.min.js → vidply.chunk-L4O44K63.min.js} +1 -1
- package/dist/prod/vidply.chunk-M76ABMKB.min.js +6 -0
- package/dist/prod/vidply.chunk-WRVDVD33.min.js +6 -0
- package/dist/prod/{vidply.chunk-HKXIYL5T.min.js → vidply.chunk-X2FQEQYR.min.js} +2 -2
- package/dist/prod/vidply.chunk-XXUH7ADU.min.js +6 -0
- package/dist/prod/{vidply.de-RZ2FVGU4.min.js → vidply.de-JMCATTKZ.min.js} +1 -1
- package/dist/prod/{vidply.es-KUCGSMAA.min.js → vidply.es-YVG37V7Z.min.js} +1 -1
- package/dist/prod/vidply.esm.min.js +2 -2
- package/dist/prod/{vidply.fr-2FOZ6M7L.min.js → vidply.fr-OGKGN2R4.min.js} +1 -1
- package/dist/prod/{vidply.ja-5H6AMU2R.min.js → vidply.ja-Z6DS7QLS.min.js} +1 -1
- package/dist/vidply.css +5796 -5892
- package/dist/vidply.esm.min.meta.json +430 -241
- package/dist/vidply.min.css +1 -1
- package/package.json +95 -92
- package/src/controls/CaptionManager.ts +11 -4
- package/src/controls/CaptionStyleMenu.ts +370 -0
- package/src/controls/ControlBar.ts +93 -403
- package/src/controls/KeyboardManager.ts +78 -2
- package/src/controls/SettingsDialog.ts +32 -2
- package/src/controls/TranscriptManager.ts +12 -10
- package/src/core/AudioDescriptionManager.ts +114 -23
- package/src/core/DescriptionSpeechManager.ts +232 -0
- package/src/core/FloatingPlayerManager.ts +674 -663
- package/src/core/MetadataAlertsManager.ts +2 -1
- package/src/core/Player.ts +97 -33
- package/src/core/PseudoFullscreen.ts +4 -2
- package/src/core/SignLanguageManager.ts +9 -7
- package/src/features/PlaylistManager.ts +56 -30
- package/src/i18n/translations.ts +28 -28
- package/src/icons/Icons.ts +167 -167
- package/src/index.ts +4 -1
- package/src/renderers/DASHRenderer.ts +39 -30
- package/src/renderers/HLSRenderer.ts +99 -53
- package/src/renderers/HTML5Renderer.ts +389 -382
- package/src/renderers/SoundCloudRenderer.ts +33 -18
- package/src/renderers/VimeoRenderer.ts +298 -298
- package/src/renderers/YouTubeRenderer.ts +290 -305
- package/src/styles/vidply.css +5796 -5892
- package/src/types/events.ts +2 -0
- package/src/types/globals.d.ts +313 -279
- package/src/types/index.ts +4 -4
- package/src/types/options.ts +3 -0
- package/src/types/renderer.ts +58 -63
- package/src/types/state.ts +24 -24
- package/src/utils/DOMUtils.ts +4 -3
- package/src/utils/DownloadInfo.ts +2 -2
- package/src/utils/DraggableResizable.ts +997 -994
- package/src/utils/EventEmitter.ts +59 -59
- package/src/utils/FocusUtils.ts +26 -26
- package/src/utils/FormUtils.ts +95 -95
- package/src/utils/MenuFactory.ts +483 -461
- package/src/utils/MenuUtils.ts +190 -172
- package/src/utils/PerformanceUtils.ts +63 -40
- package/src/utils/ResizeHandles.ts +58 -58
- package/src/utils/ScriptLoader.ts +137 -0
- package/src/utils/SettingsMenuFactory.ts +289 -276
- package/src/utils/StorageManager.ts +4 -1
- package/src/utils/TimeUtils.ts +67 -67
- package/src/utils/WindowComponents.ts +250 -250
- package/dist/dev/vidply.AudioDescriptionManager-NRMNKZAL.js.map +0 -7
- package/dist/dev/vidply.DASHRenderer-SYXX6RRS.js.map +0 -7
- package/dist/dev/vidply.FloatingPlayerManager-HJVGUQLT.js.map +0 -7
- package/dist/dev/vidply.HLSRenderer-YAFEUBMC.js.map +0 -7
- package/dist/dev/vidply.HTML5Renderer-ITDUMSTL.js +0 -12
- package/dist/dev/vidply.SignLanguageManager-ZZ6DIDTP.js.map +0 -7
- package/dist/dev/vidply.SoundCloudRenderer-OFBGL7UV.js.map +0 -7
- package/dist/dev/vidply.TranscriptManager-4553RRA6.js.map +0 -7
- package/dist/dev/vidply.VimeoRenderer-EVW2RNSF.js.map +0 -7
- package/dist/dev/vidply.YouTubeRenderer-PZHT3GMF.js.map +0 -7
- package/dist/dev/vidply.chunk-24QLI7ZK.js.map +0 -7
- package/dist/dev/vidply.chunk-AQDY6B5B.js.map +0 -7
- package/dist/dev/vidply.chunk-KMACPXZ5.js.map +0 -7
- package/dist/dev/vidply.chunk-MQAA3FKI.js.map +0 -7
- package/dist/dev/vidply.chunk-NUTGO3RK.js.map +0 -7
- package/dist/dev/vidply.chunk-PTYRD6ZP.js.map +0 -7
- package/dist/dev/vidply.chunk-RQGZAPWY.js.map +0 -7
- package/dist/dev/vidply.chunk-TM5HFGG5.js.map +0 -7
- package/dist/prod/vidply.AudioDescriptionManager-QVL4TD4R.min.js +0 -6
- package/dist/prod/vidply.DASHRenderer-DVBO6JRL.min.js +0 -6
- package/dist/prod/vidply.HLSRenderer-AHFQI64X.min.js +0 -6
- package/dist/prod/vidply.HTML5Renderer-WNGD745H.min.js +0 -6
- package/dist/prod/vidply.SignLanguageManager-E65WKF37.min.js +0 -6
- package/dist/prod/vidply.SoundCloudRenderer-XD3TMM5O.min.js +0 -6
- package/dist/prod/vidply.TranscriptManager-6JM6CJTM.min.js +0 -6
- package/dist/prod/vidply.VimeoRenderer-7L6RWMWE.min.js +0 -6
- package/dist/prod/vidply.YouTubeRenderer-ZAQTBKM4.min.js +0 -6
- package/dist/prod/vidply.chunk-3L3VQFPN.min.js +0 -6
- package/dist/prod/vidply.chunk-5644WA3F.min.js +0 -6
- package/dist/prod/vidply.chunk-6DG7I4DA.min.js +0 -6
- package/dist/prod/vidply.chunk-OFMLXH4A.min.js +0 -6
- package/dist/prod/vidply.chunk-VX4CE6WF.min.js +0 -6
- package/dist/prod/vidply.chunk-W5YQ5TEO.min.js +0 -6
- /package/dist/dev/{vidply.HTML5Renderer-ITDUMSTL.js.map → vidply.HTML5Renderer-P7ICKYU4.js.map} +0 -0
- /package/dist/dev/{vidply.de-27ZM6TOB.js.map → vidply.de-5W5LBFSJ.js.map} +0 -0
- /package/dist/dev/{vidply.es-XNGJJLWC.js.map → vidply.es-SHDAT6L6.js.map} +0 -0
- /package/dist/dev/{vidply.fr-AVZKPUBH.js.map → vidply.fr-2JANOMNB.js.map} +0 -0
- /package/dist/dev/{vidply.ja-IZK2UXDC.js.map → vidply.ja-WWMSTEJH.js.map} +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
|
+
* (c) 2026 Matthias Peltzer
|
|
4
|
+
* Released under GPL-2.0-or-later License
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
focusFirstElement
|
|
8
|
+
} from "./vidply.chunk-JAKZNGOR.js";
|
|
9
|
+
import {
|
|
10
|
+
DOMUtils,
|
|
11
|
+
i18n
|
|
12
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
13
|
+
|
|
14
|
+
// src/controls/CaptionStyleMenu.ts
|
|
15
|
+
function captionStylePropertyName(property) {
|
|
16
|
+
const stripped = property.replace("captions", "");
|
|
17
|
+
return stripped.charAt(0).toLowerCase() + stripped.slice(1);
|
|
18
|
+
}
|
|
19
|
+
function createStyleControl(player, label, property, options) {
|
|
20
|
+
const group = DOMUtils.createElement("div", {
|
|
21
|
+
className: `${player.options.classPrefix}-style-group`
|
|
22
|
+
});
|
|
23
|
+
const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;
|
|
24
|
+
const labelEl = DOMUtils.createElement("label", {
|
|
25
|
+
textContent: label,
|
|
26
|
+
attributes: {
|
|
27
|
+
"for": controlId
|
|
28
|
+
},
|
|
29
|
+
style: {
|
|
30
|
+
display: "block",
|
|
31
|
+
fontSize: "12px",
|
|
32
|
+
marginBottom: "4px",
|
|
33
|
+
color: "rgba(255,255,255,0.7)"
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
group.appendChild(labelEl);
|
|
37
|
+
const select = DOMUtils.createElement("select", {
|
|
38
|
+
className: `${player.options.classPrefix}-style-select`,
|
|
39
|
+
attributes: {
|
|
40
|
+
"id": controlId
|
|
41
|
+
},
|
|
42
|
+
style: {
|
|
43
|
+
width: "100%",
|
|
44
|
+
padding: "6px",
|
|
45
|
+
background: "var(--vidply-white)",
|
|
46
|
+
border: "1px solid var(--vidply-white-10)",
|
|
47
|
+
borderRadius: "4px",
|
|
48
|
+
color: "var(--vidply-black)",
|
|
49
|
+
fontSize: "13px"
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
const currentValue = player.options[property];
|
|
53
|
+
options.forEach((opt) => {
|
|
54
|
+
const option = DOMUtils.createElement("option", {
|
|
55
|
+
textContent: opt.label,
|
|
56
|
+
attributes: { value: opt.value }
|
|
57
|
+
});
|
|
58
|
+
if (opt.value === currentValue) {
|
|
59
|
+
option.selected = true;
|
|
60
|
+
}
|
|
61
|
+
select.appendChild(option);
|
|
62
|
+
});
|
|
63
|
+
select.addEventListener("mousedown", (e) => {
|
|
64
|
+
e.stopPropagation();
|
|
65
|
+
});
|
|
66
|
+
select.addEventListener("click", (e) => {
|
|
67
|
+
e.stopPropagation();
|
|
68
|
+
});
|
|
69
|
+
select.addEventListener("change", (e) => {
|
|
70
|
+
e.stopPropagation();
|
|
71
|
+
player.options[property] = e.target.value;
|
|
72
|
+
if (player.captionManager) {
|
|
73
|
+
player.captionManager.setCaptionStyle(
|
|
74
|
+
captionStylePropertyName(property),
|
|
75
|
+
e.target.value
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
group.appendChild(select);
|
|
80
|
+
return group;
|
|
81
|
+
}
|
|
82
|
+
function createColorControl(player, label, property) {
|
|
83
|
+
const group = DOMUtils.createElement("div", {
|
|
84
|
+
className: `${player.options.classPrefix}-style-group`
|
|
85
|
+
});
|
|
86
|
+
const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;
|
|
87
|
+
const labelEl = DOMUtils.createElement("label", {
|
|
88
|
+
textContent: label,
|
|
89
|
+
attributes: {
|
|
90
|
+
"for": controlId
|
|
91
|
+
},
|
|
92
|
+
style: {
|
|
93
|
+
display: "block",
|
|
94
|
+
fontSize: "12px",
|
|
95
|
+
marginBottom: "4px",
|
|
96
|
+
color: "rgba(255,255,255,0.7)"
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
group.appendChild(labelEl);
|
|
100
|
+
const input = DOMUtils.createElement("input", {
|
|
101
|
+
attributes: {
|
|
102
|
+
"id": controlId,
|
|
103
|
+
type: "color",
|
|
104
|
+
value: String(player.options[property] ?? "")
|
|
105
|
+
},
|
|
106
|
+
style: {
|
|
107
|
+
width: "100%",
|
|
108
|
+
height: "32px",
|
|
109
|
+
padding: "2px",
|
|
110
|
+
background: "rgba(255,255,255,0.1)",
|
|
111
|
+
border: "1px solid rgba(255,255,255,0.2)",
|
|
112
|
+
borderRadius: "4px",
|
|
113
|
+
cursor: "pointer"
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
input.addEventListener("mousedown", (e) => {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
});
|
|
119
|
+
input.addEventListener("click", (e) => {
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
});
|
|
122
|
+
input.addEventListener("change", (e) => {
|
|
123
|
+
e.stopPropagation();
|
|
124
|
+
player.options[property] = e.target.value;
|
|
125
|
+
if (player.captionManager) {
|
|
126
|
+
player.captionManager.setCaptionStyle(
|
|
127
|
+
captionStylePropertyName(property),
|
|
128
|
+
e.target.value
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
group.appendChild(input);
|
|
133
|
+
return group;
|
|
134
|
+
}
|
|
135
|
+
function createOpacityControl(player, label, property) {
|
|
136
|
+
const group = DOMUtils.createElement("div", {
|
|
137
|
+
className: `${player.options.classPrefix}-style-group`
|
|
138
|
+
});
|
|
139
|
+
const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;
|
|
140
|
+
const labelContainer = DOMUtils.createElement("div", {
|
|
141
|
+
style: {
|
|
142
|
+
display: "flex",
|
|
143
|
+
justifyContent: "space-between",
|
|
144
|
+
marginBottom: "4px"
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const labelEl = DOMUtils.createElement("label", {
|
|
148
|
+
textContent: label,
|
|
149
|
+
attributes: {
|
|
150
|
+
"for": controlId
|
|
151
|
+
},
|
|
152
|
+
style: {
|
|
153
|
+
fontSize: "12px",
|
|
154
|
+
color: "rgba(255,255,255,0.7)"
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
const valueEl = DOMUtils.createElement("span", {
|
|
158
|
+
textContent: Math.round(Number(player.options[property] ?? 0) * 100) + "%",
|
|
159
|
+
style: {
|
|
160
|
+
fontSize: "12px",
|
|
161
|
+
color: "rgba(255,255,255,0.7)"
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
labelContainer.appendChild(labelEl);
|
|
165
|
+
labelContainer.appendChild(valueEl);
|
|
166
|
+
group.appendChild(labelContainer);
|
|
167
|
+
const input = DOMUtils.createElement("input", {
|
|
168
|
+
attributes: {
|
|
169
|
+
"id": controlId,
|
|
170
|
+
type: "range",
|
|
171
|
+
min: "0",
|
|
172
|
+
max: "1",
|
|
173
|
+
step: "0.1",
|
|
174
|
+
value: String(player.options[property])
|
|
175
|
+
},
|
|
176
|
+
style: {
|
|
177
|
+
width: "100%",
|
|
178
|
+
cursor: "pointer"
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
input.addEventListener("mousedown", (e) => {
|
|
182
|
+
e.stopPropagation();
|
|
183
|
+
});
|
|
184
|
+
input.addEventListener("click", (e) => {
|
|
185
|
+
e.stopPropagation();
|
|
186
|
+
});
|
|
187
|
+
input.addEventListener("input", (e) => {
|
|
188
|
+
e.stopPropagation();
|
|
189
|
+
const value = parseFloat(e.target.value);
|
|
190
|
+
valueEl.textContent = Math.round(value * 100) + "%";
|
|
191
|
+
player.options[property] = value;
|
|
192
|
+
if (player.captionManager) {
|
|
193
|
+
player.captionManager.setCaptionStyle(
|
|
194
|
+
captionStylePropertyName(property),
|
|
195
|
+
value
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
group.appendChild(input);
|
|
200
|
+
return group;
|
|
201
|
+
}
|
|
202
|
+
function showCaptionStyleMenu(controlBar, button) {
|
|
203
|
+
const player = controlBar.player;
|
|
204
|
+
const existingMenu = document.querySelector(`.${player.options.classPrefix}-caption-style-menu`);
|
|
205
|
+
if (existingMenu) {
|
|
206
|
+
existingMenu.remove();
|
|
207
|
+
button.setAttribute("aria-expanded", "false");
|
|
208
|
+
if (controlBar.openMenu === existingMenu) {
|
|
209
|
+
controlBar.openMenu = null;
|
|
210
|
+
controlBar.openMenuButton = null;
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const menuLabelId = `${player.options.classPrefix}-caption-style-label-${player.instanceId || ""}`;
|
|
215
|
+
const menu = DOMUtils.createElement("div", {
|
|
216
|
+
className: `${player.options.classPrefix}-caption-style-menu ${player.options.classPrefix}-menu ${player.options.classPrefix}-settings-menu`,
|
|
217
|
+
attributes: {
|
|
218
|
+
"role": "dialog",
|
|
219
|
+
"aria-modal": "false",
|
|
220
|
+
"aria-labelledby": menuLabelId
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const visuallyHiddenLabel = DOMUtils.createElement("h2", {
|
|
224
|
+
textContent: i18n.t("player.captionStyling"),
|
|
225
|
+
attributes: { id: menuLabelId, class: `${player.options.classPrefix}-sr-only` },
|
|
226
|
+
style: {
|
|
227
|
+
position: "absolute",
|
|
228
|
+
width: "1px",
|
|
229
|
+
height: "1px",
|
|
230
|
+
padding: "0",
|
|
231
|
+
margin: "-1px",
|
|
232
|
+
overflow: "hidden",
|
|
233
|
+
clip: "rect(0,0,0,0)",
|
|
234
|
+
whiteSpace: "nowrap",
|
|
235
|
+
border: "0"
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
menu.appendChild(visuallyHiddenLabel);
|
|
239
|
+
menu.addEventListener("click", (e) => {
|
|
240
|
+
e.stopPropagation();
|
|
241
|
+
});
|
|
242
|
+
if (!player.captionManager || player.captionManager.tracks.length === 0) {
|
|
243
|
+
const noTracksItem = DOMUtils.createElement("div", {
|
|
244
|
+
className: `${player.options.classPrefix}-menu-item`,
|
|
245
|
+
textContent: i18n.t("player.noCaptions"),
|
|
246
|
+
attributes: {
|
|
247
|
+
"role": "status"
|
|
248
|
+
},
|
|
249
|
+
style: { opacity: "0.5", cursor: "default", padding: "12px 16px" }
|
|
250
|
+
});
|
|
251
|
+
menu.appendChild(noTracksItem);
|
|
252
|
+
menu.style.visibility = "hidden";
|
|
253
|
+
menu.style.display = "block";
|
|
254
|
+
controlBar.insertMenuIntoDOM(menu, button);
|
|
255
|
+
controlBar.positionMenu(menu, button, true);
|
|
256
|
+
requestAnimationFrame(() => {
|
|
257
|
+
menu.style.visibility = "visible";
|
|
258
|
+
});
|
|
259
|
+
controlBar.attachMenuCloseHandler(menu, button, true);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
menu.appendChild(createStyleControl(
|
|
263
|
+
player,
|
|
264
|
+
i18n.t("styleLabels.fontSize"),
|
|
265
|
+
"captionsFontSize",
|
|
266
|
+
[
|
|
267
|
+
{ label: i18n.t("fontSizes.small"), value: "87.5%" },
|
|
268
|
+
{ label: i18n.t("fontSizes.normal"), value: "100%" },
|
|
269
|
+
{ label: i18n.t("fontSizes.large"), value: "125%" },
|
|
270
|
+
{ label: i18n.t("fontSizes.xlarge"), value: "150%" }
|
|
271
|
+
]
|
|
272
|
+
));
|
|
273
|
+
menu.appendChild(createStyleControl(
|
|
274
|
+
player,
|
|
275
|
+
i18n.t("styleLabels.font"),
|
|
276
|
+
"captionsFontFamily",
|
|
277
|
+
[
|
|
278
|
+
{ label: i18n.t("fontFamilies.sansSerif"), value: "sans-serif" },
|
|
279
|
+
{ label: i18n.t("fontFamilies.serif"), value: "serif" },
|
|
280
|
+
{ label: i18n.t("fontFamilies.monospace"), value: "monospace" }
|
|
281
|
+
]
|
|
282
|
+
));
|
|
283
|
+
menu.appendChild(createColorControl(player, i18n.t("styleLabels.textColor"), "captionsColor"));
|
|
284
|
+
menu.appendChild(createColorControl(player, i18n.t("styleLabels.background"), "captionsBackgroundColor"));
|
|
285
|
+
menu.appendChild(createOpacityControl(player, i18n.t("styleLabels.opacity"), "captionsOpacity"));
|
|
286
|
+
menu.style.minWidth = "220px";
|
|
287
|
+
menu.style.visibility = "hidden";
|
|
288
|
+
menu.style.display = "block";
|
|
289
|
+
controlBar.insertMenuIntoDOM(menu, button);
|
|
290
|
+
controlBar.positionMenu(menu, button, true);
|
|
291
|
+
requestAnimationFrame(() => {
|
|
292
|
+
menu.style.visibility = "visible";
|
|
293
|
+
});
|
|
294
|
+
controlBar.attachMenuCloseHandler(menu, button, true);
|
|
295
|
+
focusFirstElement(menu, `.${player.options.classPrefix}-style-select`);
|
|
296
|
+
}
|
|
297
|
+
export {
|
|
298
|
+
showCaptionStyleMenu
|
|
299
|
+
};
|
|
300
|
+
//# sourceMappingURL=vidply.CaptionStyleMenu-R2SCQ6VP.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/controls/CaptionStyleMenu.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Caption-style menu (font size/family, text & background color, opacity).\n *\n * Extracted from ControlBar and loaded on demand via dynamic import() so the\n * builder code for this relatively rarely-opened panel is not part of the\n * always-loaded core bundle. ControlBar.showCaptionStyleMenu() awaits this\n * module the first time the panel is opened.\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\nimport { focusFirstElement } from '../utils/FocusUtils.js';\nimport type { ControlBar } from './ControlBar.js';\nimport type { Player } from '../core/Player.js';\n\nfunction captionStylePropertyName(property: string): string {\n const stripped = property.replace('captions', '');\n return stripped.charAt(0).toLowerCase() + stripped.slice(1);\n}\n\nfunction createStyleControl(\n player: Player,\n label: string,\n property: string,\n options: Array<{ label: string; value: string }>\n): HTMLElement {\n const group = DOMUtils.createElement('div', {\n className: `${player.options.classPrefix}-style-group`\n });\n\n const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n },\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${player.options.classPrefix}-style-select`,\n attributes: {\n 'id': controlId\n },\n style: {\n width: '100%',\n padding: '6px',\n background: 'var(--vidply-white)',\n border: '1px solid var(--vidply-white-10)',\n borderRadius: '4px',\n color: 'var(--vidply-black)',\n fontSize: '13px'\n }\n });\n\n const currentValue = player.options[property];\n options.forEach((opt) => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: { value: opt.value }\n });\n if (opt.value === currentValue) {\n (option as HTMLOptionElement).selected = true;\n }\n select.appendChild(option);\n });\n\n select.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('change', (e) => {\n e.stopPropagation();\n player.options[property] = (e.target as HTMLSelectElement).value;\n if (player.captionManager) {\n player.captionManager.setCaptionStyle(\n captionStylePropertyName(property),\n (e.target as HTMLSelectElement).value\n );\n }\n });\n\n group.appendChild(select);\n return group;\n}\n\nfunction createColorControl(player: Player, label: string, property: string): HTMLElement {\n const group = DOMUtils.createElement('div', {\n className: `${player.options.classPrefix}-style-group`\n });\n\n const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n },\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n 'id': controlId,\n type: 'color',\n value: String(player.options[property] ?? '')\n },\n style: {\n width: '100%',\n height: '32px',\n padding: '2px',\n background: 'rgba(255,255,255,0.1)',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '4px',\n cursor: 'pointer'\n }\n });\n\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('change', (e) => {\n e.stopPropagation();\n player.options[property] = (e.target as HTMLInputElement).value;\n if (player.captionManager) {\n player.captionManager.setCaptionStyle(\n captionStylePropertyName(property),\n (e.target as HTMLInputElement).value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n}\n\nfunction createOpacityControl(player: Player, label: string, property: string): HTMLElement {\n const group = DOMUtils.createElement('div', {\n className: `${player.options.classPrefix}-style-group`\n });\n\n const controlId = `${player.options.classPrefix}-${property}-${Date.now()}`;\n\n const labelContainer = DOMUtils.createElement('div', {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '4px'\n }\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': controlId\n },\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n const valueEl = DOMUtils.createElement('span', {\n textContent: Math.round(Number(player.options[property] ?? 0) * 100) + '%',\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n labelContainer.appendChild(labelEl);\n labelContainer.appendChild(valueEl);\n group.appendChild(labelContainer);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n 'id': controlId,\n type: 'range',\n min: '0',\n max: '1',\n step: '0.1',\n value: String(player.options[property])\n },\n style: {\n width: '100%',\n cursor: 'pointer'\n }\n });\n\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('input', (e) => {\n e.stopPropagation();\n const value = parseFloat((e.target as HTMLInputElement).value);\n valueEl.textContent = Math.round(value * 100) + '%';\n player.options[property] = value;\n if (player.captionManager) {\n player.captionManager.setCaptionStyle(\n captionStylePropertyName(property),\n value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n}\n\n/**\n * Build and show the caption-style dialog for the given ControlBar. Mirrors\n * the toggle/positioning behavior of the other ControlBar menus by delegating\n * back to the ControlBar's shared DOM-insertion / positioning / close helpers.\n */\nexport function showCaptionStyleMenu(controlBar: ControlBar, button: HTMLElement): void {\n const player = controlBar.player;\n\n // Remove existing menu if any (toggle behavior)\n const existingMenu = document.querySelector(`.${player.options.classPrefix}-caption-style-menu`);\n if (existingMenu) {\n existingMenu.remove();\n button.setAttribute('aria-expanded', 'false');\n if (controlBar.openMenu === existingMenu) {\n controlBar.openMenu = null;\n controlBar.openMenuButton = null;\n }\n return;\n }\n\n // The caption-style panel contains form controls (selects, color\n // inputs, sliders), not single-action menuitems. Modeling it as a\n // dialog yields correct semantics for AT and matches the\n // SettingsDialog pattern.\n const menuLabelId = `${player.options.classPrefix}-caption-style-label-${player.instanceId || ''}`;\n const menu = DOMUtils.createElement('div', {\n className: `${player.options.classPrefix}-caption-style-menu ${player.options.classPrefix}-menu ${player.options.classPrefix}-settings-menu`,\n attributes: {\n 'role': 'dialog',\n 'aria-modal': 'false',\n 'aria-labelledby': menuLabelId\n }\n });\n const visuallyHiddenLabel = DOMUtils.createElement('h2', {\n textContent: i18n.t('player.captionStyling'),\n attributes: { id: menuLabelId, class: `${player.options.classPrefix}-sr-only` },\n style: {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0,0,0,0)',\n whiteSpace: 'nowrap',\n border: '0'\n }\n });\n menu.appendChild(visuallyHiddenLabel);\n\n // Prevent menu from closing when clicking inside\n menu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Check if there are any caption tracks\n if (!player.captionManager || player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n attributes: {\n 'role': 'status'\n },\n style: { opacity: '0.5', cursor: 'default', padding: '12px 16px' }\n });\n menu.appendChild(noTracksItem);\n\n menu.style.visibility = 'hidden';\n menu.style.display = 'block';\n\n controlBar.insertMenuIntoDOM(menu, button);\n controlBar.positionMenu(menu, button, true);\n\n requestAnimationFrame(() => {\n menu.style.visibility = 'visible';\n });\n\n controlBar.attachMenuCloseHandler(menu, button, true);\n return;\n }\n\n // Font Size\n menu.appendChild(createStyleControl(\n player,\n i18n.t('styleLabels.fontSize'),\n 'captionsFontSize',\n [\n { label: i18n.t('fontSizes.small'), value: '87.5%' },\n { label: i18n.t('fontSizes.normal'), value: '100%' },\n { label: i18n.t('fontSizes.large'), value: '125%' },\n { label: i18n.t('fontSizes.xlarge'), value: '150%' }\n ]\n ));\n\n // Font Family\n menu.appendChild(createStyleControl(\n player,\n i18n.t('styleLabels.font'),\n 'captionsFontFamily',\n [\n { label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif' },\n { label: i18n.t('fontFamilies.serif'), value: 'serif' },\n { label: i18n.t('fontFamilies.monospace'), value: 'monospace' }\n ]\n ));\n\n // Text Color\n menu.appendChild(createColorControl(player, i18n.t('styleLabels.textColor'), 'captionsColor'));\n\n // Background Color\n menu.appendChild(createColorControl(player, i18n.t('styleLabels.background'), 'captionsBackgroundColor'));\n\n // Opacity\n menu.appendChild(createOpacityControl(player, i18n.t('styleLabels.opacity'), 'captionsOpacity'));\n\n // Set min-width for caption style menu\n menu.style.minWidth = '220px';\n\n menu.style.visibility = 'hidden';\n menu.style.display = 'block';\n\n controlBar.insertMenuIntoDOM(menu, button);\n controlBar.positionMenu(menu, button, true);\n\n requestAnimationFrame(() => {\n menu.style.visibility = 'visible';\n });\n\n controlBar.attachMenuCloseHandler(menu, button, true);\n\n // Auto-focus the first style select element\n focusFirstElement(menu, `.${player.options.classPrefix}-style-select`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.1
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
|
+
import {
|
|
7
|
+
loadScriptOnce
|
|
8
|
+
} from "./vidply.chunk-HOYEMJSD.js";
|
|
6
9
|
|
|
7
10
|
// src/renderers/DASHRenderer.ts
|
|
8
11
|
var DASHRenderer = class {
|
|
@@ -22,6 +25,11 @@ var DASHRenderer = class {
|
|
|
22
25
|
_pendingTimeouts;
|
|
23
26
|
_ttmlDiv;
|
|
24
27
|
_manifestUrl;
|
|
28
|
+
// Detaches all media listeners (attachMediaEvents) in destroy().
|
|
29
|
+
_listenerController;
|
|
30
|
+
// Deferred 'ready' handler from updateCaptionButtonsForStreaming, removed on
|
|
31
|
+
// destroy if it never fired.
|
|
32
|
+
_pendingReadyHandler;
|
|
25
33
|
constructor(player) {
|
|
26
34
|
this.player = player;
|
|
27
35
|
this.media = player.element;
|
|
@@ -38,6 +46,8 @@ var DASHRenderer = class {
|
|
|
38
46
|
this._pendingTimeouts = [];
|
|
39
47
|
this._ttmlDiv = null;
|
|
40
48
|
this._manifestUrl = null;
|
|
49
|
+
this._listenerController = new AbortController();
|
|
50
|
+
this._pendingReadyHandler = null;
|
|
41
51
|
}
|
|
42
52
|
async init() {
|
|
43
53
|
this.player.log("Using dash.js for DASH support");
|
|
@@ -52,7 +62,7 @@ var DASHRenderer = class {
|
|
|
52
62
|
const sourceElements = Array.from(this.media.querySelectorAll("source"));
|
|
53
63
|
let originalSrc = null;
|
|
54
64
|
if (sourceElements.length > 0) {
|
|
55
|
-
originalSrc = sourceElements[0]
|
|
65
|
+
originalSrc = sourceElements[0]?.getAttribute("src") ?? null;
|
|
56
66
|
sourceElements.forEach((source) => source.remove());
|
|
57
67
|
this.player.log("Removed <source> elements for HTML5 validity (dash.js uses MSE)");
|
|
58
68
|
}
|
|
@@ -167,18 +177,7 @@ var DASHRenderer = class {
|
|
|
167
177
|
const defaultUrl = "https://cdn.jsdelivr.net/npm/dashjs@5.2.0/dist/modern/umd/dash.all.min.js";
|
|
168
178
|
const url = this.player.options.dashScriptUrl || defaultUrl;
|
|
169
179
|
const integrity = this.player.options.dashScriptIntegrity;
|
|
170
|
-
return
|
|
171
|
-
const script = document.createElement("script");
|
|
172
|
-
script.src = url;
|
|
173
|
-
if (integrity) {
|
|
174
|
-
script.integrity = integrity;
|
|
175
|
-
script.crossOrigin = "anonymous";
|
|
176
|
-
script.referrerPolicy = "no-referrer";
|
|
177
|
-
}
|
|
178
|
-
script.onload = () => resolve();
|
|
179
|
-
script.onerror = () => reject(new Error("Failed to load dash.js"));
|
|
180
|
-
document.head.appendChild(script);
|
|
181
|
-
});
|
|
180
|
+
return loadScriptOnce(url, { integrity });
|
|
182
181
|
}
|
|
183
182
|
_setTimeout(fn, delay) {
|
|
184
183
|
const id = setTimeout(() => {
|
|
@@ -269,7 +268,7 @@ var DASHRenderer = class {
|
|
|
269
268
|
if (!textTracks) return total;
|
|
270
269
|
for (let i = 0; i < textTracks.length; i++) {
|
|
271
270
|
const track = textTracks[i];
|
|
272
|
-
if ((track.kind === "subtitles" || track.kind === "captions") && !track._vidplyStale && track.cues) {
|
|
271
|
+
if (track && (track.kind === "subtitles" || track.kind === "captions") && !track._vidplyStale && track.cues) {
|
|
273
272
|
total += track.cues.length;
|
|
274
273
|
}
|
|
275
274
|
}
|
|
@@ -386,7 +385,7 @@ var DASHRenderer = class {
|
|
|
386
385
|
let count = 0;
|
|
387
386
|
for (let i = 0; i < tracks.length; i++) {
|
|
388
387
|
const track = tracks[i];
|
|
389
|
-
if ((track.kind === "subtitles" || track.kind === "captions") && !track._vidplyStale) {
|
|
388
|
+
if (track && (track.kind === "subtitles" || track.kind === "captions") && !track._vidplyStale) {
|
|
390
389
|
count++;
|
|
391
390
|
}
|
|
392
391
|
}
|
|
@@ -438,22 +437,25 @@ var DASHRenderer = class {
|
|
|
438
437
|
}
|
|
439
438
|
const onReady = () => {
|
|
440
439
|
this.player.off("ready", onReady);
|
|
440
|
+
this._pendingReadyHandler = null;
|
|
441
441
|
doUpdate();
|
|
442
442
|
};
|
|
443
|
+
this._pendingReadyHandler = onReady;
|
|
443
444
|
this.player.on("ready", onReady);
|
|
444
445
|
}
|
|
445
446
|
attachMediaEvents() {
|
|
447
|
+
const { signal } = this._listenerController;
|
|
446
448
|
this.media.addEventListener("loadedmetadata", () => {
|
|
447
449
|
this.player.state.duration = this.media.duration;
|
|
448
450
|
this.player.emit("loadedmetadata");
|
|
449
|
-
});
|
|
451
|
+
}, { signal });
|
|
450
452
|
this.media.addEventListener("durationchange", () => {
|
|
451
453
|
const duration = this.media.duration;
|
|
452
454
|
if (duration && isFinite(duration) && duration > 0) {
|
|
453
455
|
this.player.state.duration = duration;
|
|
454
456
|
this.player.emit("durationchange", duration);
|
|
455
457
|
}
|
|
456
|
-
});
|
|
458
|
+
}, { signal });
|
|
457
459
|
this.media.addEventListener("play", () => {
|
|
458
460
|
this.player.state.playing = true;
|
|
459
461
|
this.player.state.paused = false;
|
|
@@ -462,7 +464,7 @@ var DASHRenderer = class {
|
|
|
462
464
|
if (this.player.options.onPlay) {
|
|
463
465
|
this.player.options.onPlay.call(this.player);
|
|
464
466
|
}
|
|
465
|
-
});
|
|
467
|
+
}, { signal });
|
|
466
468
|
this.media.addEventListener("pause", () => {
|
|
467
469
|
this.player.state.playing = false;
|
|
468
470
|
this.player.state.paused = true;
|
|
@@ -470,7 +472,7 @@ var DASHRenderer = class {
|
|
|
470
472
|
if (this.player.options.onPause) {
|
|
471
473
|
this.player.options.onPause.call(this.player);
|
|
472
474
|
}
|
|
473
|
-
});
|
|
475
|
+
}, { signal });
|
|
474
476
|
this.media.addEventListener("ended", () => {
|
|
475
477
|
this.player.state.playing = false;
|
|
476
478
|
this.player.state.paused = true;
|
|
@@ -483,19 +485,19 @@ var DASHRenderer = class {
|
|
|
483
485
|
this.player.seek(0);
|
|
484
486
|
this.player.play();
|
|
485
487
|
}
|
|
486
|
-
});
|
|
488
|
+
}, { signal });
|
|
487
489
|
this.media.addEventListener("timeupdate", () => {
|
|
488
490
|
this.player.state.currentTime = this.media.currentTime;
|
|
489
491
|
this.player.emit("timeupdate", this.media.currentTime);
|
|
490
492
|
if (this.player.options.onTimeUpdate) {
|
|
491
493
|
this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);
|
|
492
494
|
}
|
|
493
|
-
});
|
|
495
|
+
}, { signal });
|
|
494
496
|
this.media.addEventListener("volumechange", () => {
|
|
495
497
|
this.player.state.volume = this.media.volume;
|
|
496
498
|
this.player.state.muted = this.media.muted;
|
|
497
499
|
this.player.emit("volumechange", this.media.volume);
|
|
498
|
-
});
|
|
500
|
+
}, { signal });
|
|
499
501
|
this.media.addEventListener("seeking", () => {
|
|
500
502
|
this.player.state.seeking = true;
|
|
501
503
|
this.player.emit("seeking");
|
|
@@ -503,22 +505,22 @@ var DASHRenderer = class {
|
|
|
503
505
|
this.player.state.buffering = true;
|
|
504
506
|
this.player.emit("waiting");
|
|
505
507
|
}
|
|
506
|
-
});
|
|
508
|
+
}, { signal });
|
|
507
509
|
this.media.addEventListener("seeked", () => {
|
|
508
510
|
this.player.state.seeking = false;
|
|
509
511
|
this.player.emit("seeked");
|
|
510
|
-
});
|
|
512
|
+
}, { signal });
|
|
511
513
|
this.media.addEventListener("waiting", () => {
|
|
512
514
|
this.player.state.buffering = true;
|
|
513
515
|
this.player.emit("waiting");
|
|
514
|
-
});
|
|
516
|
+
}, { signal });
|
|
515
517
|
this.media.addEventListener("canplay", () => {
|
|
516
518
|
this.player.state.buffering = false;
|
|
517
519
|
this.player.emit("canplay");
|
|
518
|
-
});
|
|
520
|
+
}, { signal });
|
|
519
521
|
this.media.addEventListener("error", () => {
|
|
520
522
|
this.player.handleError(this.media.error);
|
|
521
|
-
});
|
|
523
|
+
}, { signal });
|
|
522
524
|
}
|
|
523
525
|
handleDashError(e) {
|
|
524
526
|
const wrapped = e;
|
|
@@ -633,7 +635,7 @@ var DASHRenderer = class {
|
|
|
633
635
|
const bitrate = Number(rep.bandwidth || rep.bitrate) || 0;
|
|
634
636
|
const kb = bitrate > 0 ? Math.round(bitrate / 1e3) : 0;
|
|
635
637
|
let name;
|
|
636
|
-
if (height > 0 && heightCounts2[height] > 1 && kb > 0) {
|
|
638
|
+
if (height > 0 && (heightCounts2[height] ?? 0) > 1 && kb > 0) {
|
|
637
639
|
name = `${height}p (${kb} kbps)`;
|
|
638
640
|
} else if (height > 0) {
|
|
639
641
|
name = `${height}p`;
|
|
@@ -662,7 +664,7 @@ var DASHRenderer = class {
|
|
|
662
664
|
const bitrate = Number(info.bitrate) || 0;
|
|
663
665
|
const kb = bitrate > 0 ? Math.round(bitrate / 1e3) : 0;
|
|
664
666
|
let name;
|
|
665
|
-
if (height > 0 && heightCounts[height] > 1 && kb > 0) {
|
|
667
|
+
if (height > 0 && (heightCounts[height] ?? 0) > 1 && kb > 0) {
|
|
666
668
|
name = `${height}p (${kb} kbps)`;
|
|
667
669
|
} else if (height > 0) {
|
|
668
670
|
name = `${height}p`;
|
|
@@ -815,6 +817,11 @@ var DASHRenderer = class {
|
|
|
815
817
|
this._pendingTimeouts = [];
|
|
816
818
|
this._stopCueUpdatePolling();
|
|
817
819
|
this._lastKnownCueCount = 0;
|
|
820
|
+
this._listenerController.abort();
|
|
821
|
+
if (this._pendingReadyHandler) {
|
|
822
|
+
this.player.off("ready", this._pendingReadyHandler);
|
|
823
|
+
this._pendingReadyHandler = null;
|
|
824
|
+
}
|
|
818
825
|
if (this._captionEnabledHandler) {
|
|
819
826
|
this.player.off("captionsenabled", this._captionEnabledHandler);
|
|
820
827
|
this._captionEnabledHandler = null;
|
|
@@ -830,7 +837,7 @@ var DASHRenderer = class {
|
|
|
830
837
|
const textTracks = this.media.textTracks;
|
|
831
838
|
for (let i = 0; i < textTracks.length; i++) {
|
|
832
839
|
const track = textTracks[i];
|
|
833
|
-
if (track.kind === "subtitles" || track.kind === "captions") {
|
|
840
|
+
if (track && (track.kind === "subtitles" || track.kind === "captions")) {
|
|
834
841
|
track._vidplyStale = true;
|
|
835
842
|
track.mode = "disabled";
|
|
836
843
|
}
|
|
@@ -855,4 +862,4 @@ var DASHRenderer = class {
|
|
|
855
862
|
export {
|
|
856
863
|
DASHRenderer
|
|
857
864
|
};
|
|
858
|
-
//# sourceMappingURL=vidply.DASHRenderer-
|
|
865
|
+
//# sourceMappingURL=vidply.DASHRenderer-EOVEW73H.js.map
|