vidply 1.0.24 → 1.0.26
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 +5 -0
- package/dist/dev/vidply.HLSRenderer-X46P47LY.js +261 -0
- package/dist/dev/vidply.HLSRenderer-X46P47LY.js.map +7 -0
- package/dist/dev/vidply.HTML5Renderer-LXQ3I45Q.js +12 -0
- package/dist/dev/vidply.HTML5Renderer-LXQ3I45Q.js.map +7 -0
- package/dist/dev/vidply.TranscriptManager-GZKY44ON.js +1744 -0
- package/dist/dev/vidply.TranscriptManager-GZKY44ON.js.map +7 -0
- package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js +213 -0
- package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js.map +7 -0
- package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js +227 -0
- package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js.map +7 -0
- package/dist/dev/vidply.chunk-UEIJOJH6.js +243 -0
- package/dist/dev/vidply.chunk-UEIJOJH6.js.map +7 -0
- package/dist/dev/vidply.chunk-UH5MTGKF.js +1630 -0
- package/dist/dev/vidply.chunk-UH5MTGKF.js.map +7 -0
- package/dist/dev/vidply.de-THBIMP4S.js +180 -0
- package/dist/dev/vidply.de-THBIMP4S.js.map +7 -0
- package/dist/dev/vidply.es-6VWDNNNL.js +180 -0
- package/dist/dev/vidply.es-6VWDNNNL.js.map +7 -0
- package/dist/{vidply.esm.js → dev/vidply.esm.js} +279 -5135
- package/dist/dev/vidply.esm.js.map +7 -0
- package/dist/dev/vidply.fr-WHTWCHWT.js +180 -0
- package/dist/dev/vidply.fr-WHTWCHWT.js.map +7 -0
- package/dist/dev/vidply.ja-BFQNPOFI.js +180 -0
- package/dist/dev/vidply.ja-BFQNPOFI.js.map +7 -0
- package/dist/{vidply.js → legacy/vidply.js} +7676 -7458
- package/dist/legacy/vidply.js.map +7 -0
- package/dist/legacy/vidply.min.js +6 -0
- package/dist/{vidply.min.meta.json → legacy/vidply.min.meta.json} +108 -87
- package/dist/prod/vidply.HLSRenderer-LDXSMWTI.min.js +6 -0
- package/dist/prod/vidply.HTML5Renderer-XJCSUETP.min.js +6 -0
- package/dist/prod/vidply.TranscriptManager-UZ6DUFB6.min.js +6 -0
- package/dist/prod/vidply.VimeoRenderer-P3PU27S7.min.js +6 -0
- package/dist/prod/vidply.YouTubeRenderer-DGKKWB5M.min.js +6 -0
- package/dist/prod/vidply.chunk-BQBGEJF7.min.js +6 -0
- package/dist/prod/vidply.chunk-MBUR3U5L.min.js +6 -0
- package/dist/prod/vidply.de-SWFW4HYT.min.js +6 -0
- package/dist/prod/vidply.es-7BJ2DJAY.min.js +6 -0
- package/dist/prod/vidply.esm.min.js +21 -0
- package/dist/prod/vidply.fr-DPVR5DFY.min.js +6 -0
- package/dist/prod/vidply.ja-PEBVWKVH.min.js +6 -0
- package/dist/vidply.css +1 -1
- package/dist/vidply.esm.min.meta.json +273 -96
- package/dist/vidply.min.css +1 -1
- package/package.json +3 -3
- package/src/controls/ControlBar.js +2 -4
- package/src/core/Player.js +64 -20
- package/src/features/PlaylistManager.js +5 -4
- package/src/i18n/i18n.js +51 -7
- package/src/i18n/translations.js +35 -18
- package/src/icons/Icons.js +2 -20
- package/src/renderers/HLSRenderer.js +7 -0
- package/dist/vidply.esm.js.map +0 -7
- package/dist/vidply.esm.min.js +0 -22
- package/dist/vidply.js.map +0 -7
- package/dist/vidply.min.js +0 -22
package/README.md
CHANGED
|
@@ -684,6 +684,11 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
684
684
|
|
|
685
685
|
## Documentation
|
|
686
686
|
|
|
687
|
+
### Guides
|
|
688
|
+
- **[User's Guide](docs/Users-Guide.md)** - Complete integration guide for web developers
|
|
689
|
+
- **[Developer Quickstart](docs/Developers-Quickstart.md)** - Quick reference for contributors
|
|
690
|
+
|
|
691
|
+
### Reference
|
|
687
692
|
- [Getting Started Guide](docs/GETTING_STARTED.md) - Basic setup and usage
|
|
688
693
|
- [Usage Guide](docs/USAGE.md) - Detailed usage examples
|
|
689
694
|
- [Playlist Guide](docs/PLAYLIST.md) - Audio/video playlists with fullscreen support
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Universal, Accessible Video Player
|
|
3
|
+
* (c) 2025 Matthias Peltzer
|
|
4
|
+
* Released under GPL-2.0-or-later License
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// src/renderers/HLSRenderer.js
|
|
8
|
+
var HLSRenderer = class {
|
|
9
|
+
constructor(player) {
|
|
10
|
+
this.player = player;
|
|
11
|
+
this.media = player.element;
|
|
12
|
+
this.hls = null;
|
|
13
|
+
}
|
|
14
|
+
async init() {
|
|
15
|
+
if (this.canPlayNatively()) {
|
|
16
|
+
this.player.log("Using native HLS support");
|
|
17
|
+
await this.initNative();
|
|
18
|
+
} else {
|
|
19
|
+
this.player.log("Using hls.js for HLS support");
|
|
20
|
+
await this.initHlsJs();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
canPlayNatively() {
|
|
24
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
25
|
+
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
|
26
|
+
if (!isSafari && !isIOS) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const video = document.createElement("video");
|
|
30
|
+
return video.canPlayType("application/vnd.apple.mpegurl") !== "";
|
|
31
|
+
}
|
|
32
|
+
async initNative() {
|
|
33
|
+
const HTML5Renderer = (await import("./vidply.HTML5Renderer-LXQ3I45Q.js")).HTML5Renderer;
|
|
34
|
+
const renderer = new HTML5Renderer(this.player);
|
|
35
|
+
await renderer.init();
|
|
36
|
+
Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach((method) => {
|
|
37
|
+
if (method !== "constructor" && typeof renderer[method] === "function") {
|
|
38
|
+
this[method] = renderer[method].bind(renderer);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async initHlsJs() {
|
|
43
|
+
this.media.controls = false;
|
|
44
|
+
this.media.removeAttribute("controls");
|
|
45
|
+
if (!window.Hls) {
|
|
46
|
+
await this.loadHlsJs();
|
|
47
|
+
}
|
|
48
|
+
if (!window.Hls.isSupported()) {
|
|
49
|
+
throw new Error("HLS is not supported in this browser");
|
|
50
|
+
}
|
|
51
|
+
this.hls = new window.Hls({
|
|
52
|
+
debug: this.player.options.debug,
|
|
53
|
+
enableWorker: true,
|
|
54
|
+
lowLatencyMode: false,
|
|
55
|
+
backBufferLength: 90,
|
|
56
|
+
maxBufferLength: 30,
|
|
57
|
+
maxMaxBufferLength: 600,
|
|
58
|
+
maxBufferSize: 60 * 1e3 * 1e3,
|
|
59
|
+
maxBufferHole: 0.5,
|
|
60
|
+
// Network retry settings
|
|
61
|
+
manifestLoadingTimeOut: 1e4,
|
|
62
|
+
manifestLoadingMaxRetry: 4,
|
|
63
|
+
manifestLoadingRetryDelay: 1e3,
|
|
64
|
+
manifestLoadingMaxRetryTimeout: 64e3,
|
|
65
|
+
levelLoadingTimeOut: 1e4,
|
|
66
|
+
levelLoadingMaxRetry: 4,
|
|
67
|
+
levelLoadingRetryDelay: 1e3,
|
|
68
|
+
levelLoadingMaxRetryTimeout: 64e3,
|
|
69
|
+
fragLoadingTimeOut: 2e4,
|
|
70
|
+
fragLoadingMaxRetry: 6,
|
|
71
|
+
fragLoadingRetryDelay: 1e3,
|
|
72
|
+
fragLoadingMaxRetryTimeout: 64e3
|
|
73
|
+
});
|
|
74
|
+
this.hls.attachMedia(this.media);
|
|
75
|
+
let src;
|
|
76
|
+
const sourceElement = this.player.element.querySelector("source");
|
|
77
|
+
if (sourceElement) {
|
|
78
|
+
src = sourceElement.getAttribute("src");
|
|
79
|
+
} else {
|
|
80
|
+
src = this.player.element.getAttribute("src") || this.player.element.src;
|
|
81
|
+
}
|
|
82
|
+
this.player.log(`Loading HLS source: ${src}`, "log");
|
|
83
|
+
if (!src) {
|
|
84
|
+
throw new Error("No HLS source found");
|
|
85
|
+
}
|
|
86
|
+
this.hls.loadSource(src);
|
|
87
|
+
this.attachHlsEvents();
|
|
88
|
+
this.attachMediaEvents();
|
|
89
|
+
}
|
|
90
|
+
async loadHlsJs() {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const script = document.createElement("script");
|
|
93
|
+
script.src = "https://cdn.jsdelivr.net/npm/hls.js@latest";
|
|
94
|
+
script.onload = () => resolve();
|
|
95
|
+
script.onerror = () => reject(new Error("Failed to load hls.js"));
|
|
96
|
+
document.head.appendChild(script);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
attachHlsEvents() {
|
|
100
|
+
this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {
|
|
101
|
+
this.player.log("HLS manifest loaded, found " + data.levels.length + " quality levels");
|
|
102
|
+
this.player.emit("hlsmanifestparsed", data);
|
|
103
|
+
});
|
|
104
|
+
this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {
|
|
105
|
+
this.player.log("HLS level switched to " + data.level);
|
|
106
|
+
this.player.emit("hlslevelswitched", data);
|
|
107
|
+
});
|
|
108
|
+
this.hls.on(window.Hls.Events.ERROR, (event, data) => {
|
|
109
|
+
this.handleHlsError(data);
|
|
110
|
+
});
|
|
111
|
+
this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {
|
|
112
|
+
this.player.state.buffering = false;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
attachMediaEvents() {
|
|
116
|
+
this.media.addEventListener("loadedmetadata", () => {
|
|
117
|
+
this.player.state.duration = this.media.duration;
|
|
118
|
+
this.player.emit("loadedmetadata");
|
|
119
|
+
});
|
|
120
|
+
this.media.addEventListener("play", () => {
|
|
121
|
+
this.player.state.playing = true;
|
|
122
|
+
this.player.state.paused = false;
|
|
123
|
+
this.player.state.ended = false;
|
|
124
|
+
this.player.emit("play");
|
|
125
|
+
if (this.player.options.onPlay) {
|
|
126
|
+
this.player.options.onPlay.call(this.player);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
this.media.addEventListener("pause", () => {
|
|
130
|
+
this.player.state.playing = false;
|
|
131
|
+
this.player.state.paused = true;
|
|
132
|
+
this.player.emit("pause");
|
|
133
|
+
if (this.player.options.onPause) {
|
|
134
|
+
this.player.options.onPause.call(this.player);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
this.media.addEventListener("ended", () => {
|
|
138
|
+
this.player.state.playing = false;
|
|
139
|
+
this.player.state.paused = true;
|
|
140
|
+
this.player.state.ended = true;
|
|
141
|
+
this.player.emit("ended");
|
|
142
|
+
if (this.player.options.onEnded) {
|
|
143
|
+
this.player.options.onEnded.call(this.player);
|
|
144
|
+
}
|
|
145
|
+
if (this.player.options.loop) {
|
|
146
|
+
this.player.seek(0);
|
|
147
|
+
this.player.play();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
this.media.addEventListener("timeupdate", () => {
|
|
151
|
+
this.player.state.currentTime = this.media.currentTime;
|
|
152
|
+
this.player.emit("timeupdate", this.media.currentTime);
|
|
153
|
+
if (this.player.options.onTimeUpdate) {
|
|
154
|
+
this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
this.media.addEventListener("volumechange", () => {
|
|
158
|
+
this.player.state.volume = this.media.volume;
|
|
159
|
+
this.player.state.muted = this.media.muted;
|
|
160
|
+
this.player.emit("volumechange", this.media.volume);
|
|
161
|
+
});
|
|
162
|
+
this.media.addEventListener("waiting", () => {
|
|
163
|
+
this.player.state.buffering = true;
|
|
164
|
+
this.player.emit("waiting");
|
|
165
|
+
});
|
|
166
|
+
this.media.addEventListener("canplay", () => {
|
|
167
|
+
this.player.state.buffering = false;
|
|
168
|
+
this.player.emit("canplay");
|
|
169
|
+
});
|
|
170
|
+
this.media.addEventListener("error", () => {
|
|
171
|
+
this.player.handleError(this.media.error);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
handleHlsError(data) {
|
|
175
|
+
this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, "warn");
|
|
176
|
+
if (data.response) {
|
|
177
|
+
this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, "warn");
|
|
178
|
+
}
|
|
179
|
+
if (data.fatal) {
|
|
180
|
+
switch (data.type) {
|
|
181
|
+
case window.Hls.ErrorTypes.NETWORK_ERROR:
|
|
182
|
+
this.player.log("Fatal network error, trying to recover...", "error");
|
|
183
|
+
this.player.log(`Network error details: ${data.details}`, "error");
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
this.hls.startLoad();
|
|
186
|
+
}, 1e3);
|
|
187
|
+
break;
|
|
188
|
+
case window.Hls.ErrorTypes.MEDIA_ERROR:
|
|
189
|
+
this.player.log("Fatal media error, trying to recover...", "error");
|
|
190
|
+
this.hls.recoverMediaError();
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
this.player.log("Fatal error, cannot recover", "error");
|
|
194
|
+
this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));
|
|
195
|
+
this.hls.destroy();
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
this.player.log("Non-fatal HLS error: " + data.details, "warn");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
play() {
|
|
203
|
+
const scrollX = window.scrollX;
|
|
204
|
+
const scrollY = window.scrollY;
|
|
205
|
+
const promise = this.media.play();
|
|
206
|
+
window.scrollTo(scrollX, scrollY);
|
|
207
|
+
if (promise !== void 0) {
|
|
208
|
+
promise.catch((error) => {
|
|
209
|
+
this.player.log("Play failed:", error, "warn");
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
pause() {
|
|
214
|
+
this.media.pause();
|
|
215
|
+
}
|
|
216
|
+
seek(time) {
|
|
217
|
+
this.media.currentTime = time;
|
|
218
|
+
}
|
|
219
|
+
setVolume(volume) {
|
|
220
|
+
this.media.volume = volume;
|
|
221
|
+
}
|
|
222
|
+
setMuted(muted) {
|
|
223
|
+
this.media.muted = muted;
|
|
224
|
+
}
|
|
225
|
+
setPlaybackSpeed(speed) {
|
|
226
|
+
this.media.playbackRate = speed;
|
|
227
|
+
}
|
|
228
|
+
switchQuality(levelIndex) {
|
|
229
|
+
if (this.hls) {
|
|
230
|
+
this.hls.currentLevel = levelIndex;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
getQualities() {
|
|
234
|
+
if (this.hls && this.hls.levels) {
|
|
235
|
+
return this.hls.levels.map((level, index) => ({
|
|
236
|
+
index,
|
|
237
|
+
height: level.height,
|
|
238
|
+
width: level.width,
|
|
239
|
+
bitrate: level.bitrate,
|
|
240
|
+
name: `${level.height}p`
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
getCurrentQuality() {
|
|
246
|
+
if (this.hls) {
|
|
247
|
+
return this.hls.currentLevel;
|
|
248
|
+
}
|
|
249
|
+
return -1;
|
|
250
|
+
}
|
|
251
|
+
destroy() {
|
|
252
|
+
if (this.hls) {
|
|
253
|
+
this.hls.destroy();
|
|
254
|
+
this.hls = null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
export {
|
|
259
|
+
HLSRenderer
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=vidply.HLSRenderer-X46P47LY.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/renderers/HLSRenderer.js"],
|
|
4
|
+
"sourcesContent": ["/**\r\n * HLS Streaming Renderer\r\n * Uses hls.js for browsers that don't natively support HLS\r\n */\r\n\r\nexport class HLSRenderer {\r\n constructor(player) {\r\n this.player = player;\r\n this.media = player.element;\r\n this.hls = null;\r\n }\r\n\r\n async init() {\r\n // Check if browser natively supports HLS (Safari)\r\n if (this.canPlayNatively()) {\r\n this.player.log('Using native HLS support');\r\n await this.initNative();\r\n } else {\r\n this.player.log('Using hls.js for HLS support');\r\n await this.initHlsJs();\r\n }\r\n }\r\n\r\n canPlayNatively() {\r\n // Only use native HLS on Safari/iOS where it actually works properly\r\n // Chrome reports it can play HLS but doesn't have proper quality switching\r\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\r\n const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;\r\n \r\n if (!isSafari && !isIOS) {\r\n // Force hls.js on non-Safari browsers for proper quality switching\r\n return false;\r\n }\r\n \r\n const video = document.createElement('video');\r\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\r\n }\r\n\r\n async initNative() {\r\n // Use HTML5 renderer for native HLS support\r\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\r\n const renderer = new HTML5Renderer(this.player);\r\n await renderer.init();\r\n \r\n // Copy methods\r\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach(method => {\r\n if (method !== 'constructor' && typeof renderer[method] === 'function') {\r\n this[method] = renderer[method].bind(renderer);\r\n }\r\n });\r\n }\r\n\r\n async initHlsJs() {\r\n // Hide native controls\r\n this.media.controls = false;\r\n this.media.removeAttribute('controls');\r\n \r\n // Load hls.js if not already loaded\r\n if (!window.Hls) {\r\n await this.loadHlsJs();\r\n }\r\n\r\n if (!window.Hls.isSupported()) {\r\n throw new Error('HLS is not supported in this browser');\r\n }\r\n\r\n // Create hls.js instance with better error recovery\r\n this.hls = new window.Hls({\r\n debug: this.player.options.debug,\r\n enableWorker: true,\r\n lowLatencyMode: false,\r\n backBufferLength: 90,\r\n maxBufferLength: 30,\r\n maxMaxBufferLength: 600,\r\n maxBufferSize: 60 * 1000 * 1000,\r\n maxBufferHole: 0.5,\r\n // Network retry settings\r\n manifestLoadingTimeOut: 10000,\r\n manifestLoadingMaxRetry: 4,\r\n manifestLoadingRetryDelay: 1000,\r\n manifestLoadingMaxRetryTimeout: 64000,\r\n levelLoadingTimeOut: 10000,\r\n levelLoadingMaxRetry: 4,\r\n levelLoadingRetryDelay: 1000,\r\n levelLoadingMaxRetryTimeout: 64000,\r\n fragLoadingTimeOut: 20000,\r\n fragLoadingMaxRetry: 6,\r\n fragLoadingRetryDelay: 1000,\r\n fragLoadingMaxRetryTimeout: 64000\r\n });\r\n\r\n // Attach media element\r\n this.hls.attachMedia(this.media);\r\n\r\n // Load source - Get from attribute to avoid blob URL conversion\r\n let src;\r\n const sourceElement = this.player.element.querySelector('source');\r\n if (sourceElement) {\r\n // Use getAttribute to get the original URL, not the blob-converted one\r\n src = sourceElement.getAttribute('src');\r\n } else {\r\n // Fallback to element's src attribute\r\n src = this.player.element.getAttribute('src') || this.player.element.src;\r\n }\r\n \r\n this.player.log(`Loading HLS source: ${src}`, 'log');\r\n \r\n if (!src) {\r\n throw new Error('No HLS source found');\r\n }\r\n \r\n this.hls.loadSource(src);\r\n\r\n // Attach events\r\n this.attachHlsEvents();\r\n this.attachMediaEvents();\r\n }\r\n\r\n async loadHlsJs() {\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error('Failed to load hls.js'));\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n attachHlsEvents() {\r\n this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {\r\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\r\n this.player.emit('hlsmanifestparsed', data);\r\n });\r\n\r\n this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {\r\n this.player.log('HLS level switched to ' + data.level);\r\n this.player.emit('hlslevelswitched', data);\r\n });\r\n\r\n this.hls.on(window.Hls.Events.ERROR, (event, data) => {\r\n this.handleHlsError(data);\r\n });\r\n\r\n this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {\r\n this.player.state.buffering = false;\r\n });\r\n }\r\n\r\n attachMediaEvents() {\r\n // Use same events as HTML5 renderer\r\n this.media.addEventListener('loadedmetadata', () => {\r\n this.player.state.duration = this.media.duration;\r\n this.player.emit('loadedmetadata');\r\n });\r\n\r\n this.media.addEventListener('play', () => {\r\n this.player.state.playing = true;\r\n this.player.state.paused = false;\r\n this.player.state.ended = false;\r\n this.player.emit('play');\r\n \r\n if (this.player.options.onPlay) {\r\n this.player.options.onPlay.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('pause', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.emit('pause');\r\n \r\n if (this.player.options.onPause) {\r\n this.player.options.onPause.call(this.player);\r\n }\r\n });\r\n\r\n this.media.addEventListener('ended', () => {\r\n this.player.state.playing = false;\r\n this.player.state.paused = true;\r\n this.player.state.ended = true;\r\n this.player.emit('ended');\r\n \r\n if (this.player.options.onEnded) {\r\n this.player.options.onEnded.call(this.player);\r\n }\r\n \r\n if (this.player.options.loop) {\r\n this.player.seek(0);\r\n this.player.play();\r\n }\r\n });\r\n\r\n this.media.addEventListener('timeupdate', () => {\r\n this.player.state.currentTime = this.media.currentTime;\r\n this.player.emit('timeupdate', this.media.currentTime);\r\n \r\n if (this.player.options.onTimeUpdate) {\r\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\r\n }\r\n });\r\n\r\n this.media.addEventListener('volumechange', () => {\r\n this.player.state.volume = this.media.volume;\r\n this.player.state.muted = this.media.muted;\r\n this.player.emit('volumechange', this.media.volume);\r\n });\r\n\r\n this.media.addEventListener('waiting', () => {\r\n this.player.state.buffering = true;\r\n this.player.emit('waiting');\r\n });\r\n\r\n this.media.addEventListener('canplay', () => {\r\n this.player.state.buffering = false;\r\n this.player.emit('canplay');\r\n });\r\n\r\n this.media.addEventListener('error', () => {\r\n this.player.handleError(this.media.error);\r\n });\r\n }\r\n\r\n handleHlsError(data) {\r\n // Log detailed error info\r\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\r\n if (data.response) {\r\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\r\n }\r\n \r\n if (data.fatal) {\r\n switch (data.type) {\r\n case window.Hls.ErrorTypes.NETWORK_ERROR:\r\n this.player.log('Fatal network error, trying to recover...', 'error');\r\n this.player.log(`Network error details: ${data.details}`, 'error');\r\n setTimeout(() => {\r\n this.hls.startLoad();\r\n }, 1000);\r\n break;\r\n \r\n case window.Hls.ErrorTypes.MEDIA_ERROR:\r\n this.player.log('Fatal media error, trying to recover...', 'error');\r\n this.hls.recoverMediaError();\r\n break;\r\n \r\n default:\r\n this.player.log('Fatal error, cannot recover', 'error');\r\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\r\n this.hls.destroy();\r\n break;\r\n }\r\n } else {\r\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\r\n }\r\n }\r\n\r\n play() {\r\n // Save scroll position to prevent browser from scrolling to video\r\n const scrollX = window.scrollX;\r\n const scrollY = window.scrollY;\r\n \r\n const promise = this.media.play();\r\n \r\n // Restore scroll position immediately to prevent auto-scroll\r\n window.scrollTo(scrollX, scrollY);\r\n \r\n if (promise !== undefined) {\r\n promise.catch(error => {\r\n this.player.log('Play failed:', error, 'warn');\r\n });\r\n }\r\n }\r\n\r\n pause() {\r\n this.media.pause();\r\n }\r\n\r\n seek(time) {\r\n this.media.currentTime = time;\r\n }\r\n\r\n setVolume(volume) {\r\n this.media.volume = volume;\r\n }\r\n\r\n setMuted(muted) {\r\n this.media.muted = muted;\r\n }\r\n\r\n setPlaybackSpeed(speed) {\r\n this.media.playbackRate = speed;\r\n }\r\n\r\n switchQuality(levelIndex) {\r\n if (this.hls) {\r\n this.hls.currentLevel = levelIndex;\r\n }\r\n }\r\n\r\n getQualities() {\r\n if (this.hls && this.hls.levels) {\r\n return this.hls.levels.map((level, index) => ({\r\n index,\r\n height: level.height,\r\n width: level.width,\r\n bitrate: level.bitrate,\r\n name: `${level.height}p`\r\n }));\r\n }\r\n return [];\r\n }\r\n\r\n getCurrentQuality() {\r\n if (this.hls) {\r\n return this.hls.currentLevel;\r\n }\r\n return -1;\r\n }\r\n\r\n destroy() {\r\n if (this.hls) {\r\n this.hls.destroy();\r\n this.hls = null;\r\n }\r\n }\r\n}\r\n\r\n"],
|
|
5
|
+
"mappings": ";;;;;;;AAKO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAAY,QAAQ;AAClB,SAAK,SAAS;AACd,SAAK,QAAQ,OAAO;AACpB,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,MAAM,OAAO;AAEX,QAAI,KAAK,gBAAgB,GAAG;AAC1B,WAAK,OAAO,IAAI,0BAA0B;AAC1C,YAAM,KAAK,WAAW;AAAA,IACxB,OAAO;AACL,WAAK,OAAO,IAAI,8BAA8B;AAC9C,YAAM,KAAK,UAAU;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,kBAAkB;AAGhB,UAAM,WAAW,iCAAiC,KAAK,UAAU,SAAS;AAC1E,UAAM,QAAQ,mBAAmB,KAAK,UAAU,SAAS,KAAK,CAAC,OAAO;AAEtE,QAAI,CAAC,YAAY,CAAC,OAAO;AAEvB,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,WAAO,MAAM,YAAY,+BAA+B,MAAM;AAAA,EAChE;AAAA,EAEA,MAAM,aAAa;AAEjB,UAAM,iBAAiB,MAAM,OAAO,oCAAoB,GAAG;AAC3D,UAAM,WAAW,IAAI,cAAc,KAAK,MAAM;AAC9C,UAAM,SAAS,KAAK;AAGpB,WAAO,oBAAoB,OAAO,eAAe,QAAQ,CAAC,EAAE,QAAQ,YAAU;AAC5E,UAAI,WAAW,iBAAiB,OAAO,SAAS,MAAM,MAAM,YAAY;AACtE,aAAK,MAAM,IAAI,SAAS,MAAM,EAAE,KAAK,QAAQ;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,YAAY;AAEhB,SAAK,MAAM,WAAW;AACtB,SAAK,MAAM,gBAAgB,UAAU;AAGrC,QAAI,CAAC,OAAO,KAAK;AACf,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,QAAI,CAAC,OAAO,IAAI,YAAY,GAAG;AAC7B,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAGA,SAAK,MAAM,IAAI,OAAO,IAAI;AAAA,MACxB,OAAO,KAAK,OAAO,QAAQ;AAAA,MAC3B,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,oBAAoB;AAAA,MACpB,eAAe,KAAK,MAAO;AAAA,MAC3B,eAAe;AAAA;AAAA,MAEf,wBAAwB;AAAA,MACxB,yBAAyB;AAAA,MACzB,2BAA2B;AAAA,MAC3B,gCAAgC;AAAA,MAChC,qBAAqB;AAAA,MACrB,sBAAsB;AAAA,MACtB,wBAAwB;AAAA,MACxB,6BAA6B;AAAA,MAC7B,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,uBAAuB;AAAA,MACvB,4BAA4B;AAAA,IAC9B,CAAC;AAGD,SAAK,IAAI,YAAY,KAAK,KAAK;AAG/B,QAAI;AACJ,UAAM,gBAAgB,KAAK,OAAO,QAAQ,cAAc,QAAQ;AAChE,QAAI,eAAe;AAEjB,YAAM,cAAc,aAAa,KAAK;AAAA,IACxC,OAAO;AAEL,YAAM,KAAK,OAAO,QAAQ,aAAa,KAAK,KAAK,KAAK,OAAO,QAAQ;AAAA,IACvE;AAEA,SAAK,OAAO,IAAI,uBAAuB,GAAG,IAAI,KAAK;AAEnD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AAEA,SAAK,IAAI,WAAW,GAAG;AAGvB,SAAK,gBAAgB;AACrB,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,MAAM,YAAY;AAChB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,MAAM;AACb,aAAO,SAAS,MAAM,QAAQ;AAC9B,aAAO,UAAU,MAAM,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAChE,eAAS,KAAK,YAAY,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB;AAChB,SAAK,IAAI,GAAG,OAAO,IAAI,OAAO,iBAAiB,CAAC,OAAO,SAAS;AAC9D,WAAK,OAAO,IAAI,gCAAgC,KAAK,OAAO,SAAS,iBAAiB;AACtF,WAAK,OAAO,KAAK,qBAAqB,IAAI;AAAA,IAC5C,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAI,OAAO,gBAAgB,CAAC,OAAO,SAAS;AAC7D,WAAK,OAAO,IAAI,2BAA2B,KAAK,KAAK;AACrD,WAAK,OAAO,KAAK,oBAAoB,IAAI;AAAA,IAC3C,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAI,OAAO,OAAO,CAAC,OAAO,SAAS;AACpD,WAAK,eAAe,IAAI;AAAA,IAC1B,CAAC;AAED,SAAK,IAAI,GAAG,OAAO,IAAI,OAAO,eAAe,MAAM;AACjD,WAAK,OAAO,MAAM,YAAY;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEA,oBAAoB;AAElB,SAAK,MAAM,iBAAiB,kBAAkB,MAAM;AAClD,WAAK,OAAO,MAAM,WAAW,KAAK,MAAM;AACxC,WAAK,OAAO,KAAK,gBAAgB;AAAA,IACnC,CAAC;AAED,SAAK,MAAM,iBAAiB,QAAQ,MAAM;AACxC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,MAAM,QAAQ;AAC1B,WAAK,OAAO,KAAK,MAAM;AAEvB,UAAI,KAAK,OAAO,QAAQ,QAAQ;AAC9B,aAAK,OAAO,QAAQ,OAAO,KAAK,KAAK,MAAM;AAAA,MAC7C;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,KAAK,OAAO;AAExB,UAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,aAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,MAC9C;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,MAAM,UAAU;AAC5B,WAAK,OAAO,MAAM,SAAS;AAC3B,WAAK,OAAO,MAAM,QAAQ;AAC1B,WAAK,OAAO,KAAK,OAAO;AAExB,UAAI,KAAK,OAAO,QAAQ,SAAS;AAC/B,aAAK,OAAO,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,MAC9C;AAEA,UAAI,KAAK,OAAO,QAAQ,MAAM;AAC5B,aAAK,OAAO,KAAK,CAAC;AAClB,aAAK,OAAO,KAAK;AAAA,MACnB;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,cAAc,MAAM;AAC9C,WAAK,OAAO,MAAM,cAAc,KAAK,MAAM;AAC3C,WAAK,OAAO,KAAK,cAAc,KAAK,MAAM,WAAW;AAErD,UAAI,KAAK,OAAO,QAAQ,cAAc;AACpC,aAAK,OAAO,QAAQ,aAAa,KAAK,KAAK,QAAQ,KAAK,MAAM,WAAW;AAAA,MAC3E;AAAA,IACF,CAAC;AAED,SAAK,MAAM,iBAAiB,gBAAgB,MAAM;AAChD,WAAK,OAAO,MAAM,SAAS,KAAK,MAAM;AACtC,WAAK,OAAO,MAAM,QAAQ,KAAK,MAAM;AACrC,WAAK,OAAO,KAAK,gBAAgB,KAAK,MAAM,MAAM;AAAA,IACpD,CAAC;AAED,SAAK,MAAM,iBAAiB,WAAW,MAAM;AAC3C,WAAK,OAAO,MAAM,YAAY;AAC9B,WAAK,OAAO,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,SAAK,MAAM,iBAAiB,WAAW,MAAM;AAC3C,WAAK,OAAO,MAAM,YAAY;AAC9B,WAAK,OAAO,KAAK,SAAS;AAAA,IAC5B,CAAC;AAED,SAAK,MAAM,iBAAiB,SAAS,MAAM;AACzC,WAAK,OAAO,YAAY,KAAK,MAAM,KAAK;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,MAAM;AAEnB,SAAK,OAAO,IAAI,qBAAqB,KAAK,IAAI,cAAc,KAAK,OAAO,YAAY,KAAK,KAAK,IAAI,MAAM;AACxG,QAAI,KAAK,UAAU;AACjB,WAAK,OAAO,IAAI,kBAAkB,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS,GAAG,IAAI,MAAM;AAAA,IAC3F;AAEA,QAAI,KAAK,OAAO;AACd,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK,OAAO,IAAI,WAAW;AACzB,eAAK,OAAO,IAAI,6CAA6C,OAAO;AACpE,eAAK,OAAO,IAAI,0BAA0B,KAAK,OAAO,IAAI,OAAO;AACjE,qBAAW,MAAM;AACf,iBAAK,IAAI,UAAU;AAAA,UACrB,GAAG,GAAI;AACP;AAAA,QAEF,KAAK,OAAO,IAAI,WAAW;AACzB,eAAK,OAAO,IAAI,2CAA2C,OAAO;AAClE,eAAK,IAAI,kBAAkB;AAC3B;AAAA,QAEF;AACE,eAAK,OAAO,IAAI,+BAA+B,OAAO;AACtD,eAAK,OAAO,YAAY,IAAI,MAAM,cAAc,KAAK,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;AAC9E,eAAK,IAAI,QAAQ;AACjB;AAAA,MACJ;AAAA,IACF,OAAO;AACL,WAAK,OAAO,IAAI,0BAA0B,KAAK,SAAS,MAAM;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,OAAO;AAEL,UAAM,UAAU,OAAO;AACvB,UAAM,UAAU,OAAO;AAEvB,UAAM,UAAU,KAAK,MAAM,KAAK;AAGhC,WAAO,SAAS,SAAS,OAAO;AAEhC,QAAI,YAAY,QAAW;AACzB,cAAQ,MAAM,WAAS;AACrB,aAAK,OAAO,IAAI,gBAAgB,OAAO,MAAM;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,QAAQ;AACN,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,KAAK,MAAM;AACT,SAAK,MAAM,cAAc;AAAA,EAC3B;AAAA,EAEA,UAAU,QAAQ;AAChB,SAAK,MAAM,SAAS;AAAA,EACtB;AAAA,EAEA,SAAS,OAAO;AACd,SAAK,MAAM,QAAQ;AAAA,EACrB;AAAA,EAEA,iBAAiB,OAAO;AACtB,SAAK,MAAM,eAAe;AAAA,EAC5B;AAAA,EAEA,cAAc,YAAY;AACxB,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,eAAe;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,eAAe;AACb,QAAI,KAAK,OAAO,KAAK,IAAI,QAAQ;AAC/B,aAAO,KAAK,IAAI,OAAO,IAAI,CAAC,OAAO,WAAW;AAAA,QAC5C;AAAA,QACA,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,SAAS,MAAM;AAAA,QACf,MAAM,GAAG,MAAM,MAAM;AAAA,MACvB,EAAE;AAAA,IACJ;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,oBAAoB;AAClB,QAAI,KAAK,KAAK;AACZ,aAAO,KAAK,IAAI;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UAAU;AACR,QAAI,KAAK,KAAK;AACZ,WAAK,IAAI,QAAQ;AACjB,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Universal, Accessible Video Player
|
|
3
|
+
* (c) 2025 Matthias Peltzer
|
|
4
|
+
* Released under GPL-2.0-or-later License
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
HTML5Renderer
|
|
8
|
+
} from "./vidply.chunk-UEIJOJH6.js";
|
|
9
|
+
export {
|
|
10
|
+
HTML5Renderer
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=vidply.HTML5Renderer-LXQ3I45Q.js.map
|