@give-tech/ec-player-vue 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,672 @@
1
+ import { ref, shallowRef, reactive, onUnmounted, computed, onMounted, defineComponent, watch, openBlock, createElementBlock, createElementVNode, unref, normalizeClass, toDisplayString, Fragment, createCommentVNode, normalizeStyle, mergeDefaults } from "vue";
2
+ import { setLogLevel, EcPlayerCore, EnvDetector } from "@give-tech/ec-player";
3
+ import { LogLevel } from "@give-tech/ec-player";
4
+ const DEFAULT_EC_PLAYER_PROPS = {
5
+ showEnvPanel: false,
6
+ showControls: true
7
+ };
8
+ const DEFAULT_PLAYER_OPTIONS = {
9
+ targetBufferSize: 60,
10
+ decodeBatchSize: 2,
11
+ maxQueueSize: 200
12
+ };
13
+ const DEFAULT_WASM_CONFIG = {
14
+ simd: "/wasm/decoder-simd.js",
15
+ nonSimd: "/wasm/decoder.js"
16
+ };
17
+ let globalConfig = {};
18
+ function configureEcPlayer(config) {
19
+ globalConfig = { ...globalConfig, ...config };
20
+ }
21
+ function getGlobalConfig() {
22
+ return { ...globalConfig };
23
+ }
24
+ function getWasmConfig() {
25
+ return {
26
+ simd: globalConfig.wasm?.simd ?? DEFAULT_WASM_CONFIG.simd,
27
+ nonSimd: globalConfig.wasm?.nonSimd ?? DEFAULT_WASM_CONFIG.nonSimd
28
+ };
29
+ }
30
+ function getMergedConfig(props) {
31
+ return {
32
+ showEnvPanel: props.showEnvPanel ?? DEFAULT_EC_PLAYER_PROPS.showEnvPanel,
33
+ showControls: props.showControls ?? globalConfig.showControls ?? DEFAULT_EC_PLAYER_PROPS.showControls
34
+ };
35
+ }
36
+ function getMergedPlayerOptions(options) {
37
+ return {
38
+ targetBufferSize: options.targetBufferSize ?? globalConfig.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,
39
+ decodeBatchSize: options.decodeBatchSize ?? globalConfig.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,
40
+ maxQueueSize: options.maxQueueSize ?? globalConfig.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize
41
+ };
42
+ }
43
+ function resolveWasmPath(hasSimdSupport) {
44
+ const wasmConfig = getWasmConfig();
45
+ if (hasSimdSupport && wasmConfig.simd) {
46
+ console.log("[EcPlayer] Using SIMD WASM:", wasmConfig.simd);
47
+ return wasmConfig.simd;
48
+ }
49
+ if (wasmConfig.nonSimd) {
50
+ console.log("[EcPlayer] SIMD not supported, using non-SIMD WASM:", wasmConfig.nonSimd);
51
+ return wasmConfig.nonSimd;
52
+ }
53
+ console.log("[EcPlayer] No non-SIMD path configured, falling back to SIMD:", wasmConfig.simd);
54
+ return wasmConfig.simd;
55
+ }
56
+ function createConfig(options) {
57
+ const envInfo = EnvDetector.detect();
58
+ const wasmPath = resolveWasmPath(envInfo.capabilities.wasmSimd);
59
+ return {
60
+ wasmPath,
61
+ targetBufferSize: options.targetBufferSize,
62
+ decodeBatchSize: options.decodeBatchSize,
63
+ maxQueueSize: options.maxQueueSize
64
+ };
65
+ }
66
+ function usePlayer(props, emit) {
67
+ const canvasRef = ref(null);
68
+ const player = shallowRef(null);
69
+ const isLoading = ref(false);
70
+ const detectedFormat = ref("");
71
+ const isLive = ref(false);
72
+ const globalConfig2 = getGlobalConfig();
73
+ const currentOptions = reactive({
74
+ targetBufferSize: globalConfig2.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,
75
+ decodeBatchSize: globalConfig2.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,
76
+ maxQueueSize: globalConfig2.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize
77
+ });
78
+ const state = reactive({
79
+ isPlaying: false,
80
+ isLoaded: false,
81
+ isLoading: false,
82
+ fps: 0,
83
+ resolution: "-",
84
+ decoded: 0,
85
+ downloaded: 0,
86
+ droppedFrames: 0,
87
+ isPrefetching: false,
88
+ segmentIndex: 0,
89
+ totalSegments: 0,
90
+ downloadSpeed: 0,
91
+ currentTime: 0,
92
+ duration: 0
93
+ });
94
+ const callbacks = {
95
+ onStateChange: (partial) => {
96
+ Object.assign(state, partial);
97
+ emit("state-change", partial);
98
+ if (partial.isPlaying === true) {
99
+ emit("play");
100
+ } else if (partial.isPlaying === false && state.isPlaying) {
101
+ emit("pause");
102
+ }
103
+ },
104
+ onError: (error) => {
105
+ console.error("[EcPlayer] Error:", error);
106
+ emit("error", error);
107
+ }
108
+ };
109
+ async function play(options) {
110
+ const { url, isLive: isLiveParam = false } = options;
111
+ if (!url) {
112
+ emit("error", new Error("URL is required"));
113
+ return;
114
+ }
115
+ if (isLoading.value) {
116
+ console.log("[EcPlayer] Already loading, skipping...");
117
+ return;
118
+ }
119
+ let retries = 10;
120
+ while (!canvasRef.value && retries > 0) {
121
+ await new Promise((resolve) => setTimeout(resolve, 100));
122
+ retries--;
123
+ }
124
+ if (!canvasRef.value) {
125
+ const error = new Error("Canvas element not found");
126
+ emit("error", error);
127
+ return;
128
+ }
129
+ isLoading.value = true;
130
+ isLive.value = isLiveParam;
131
+ try {
132
+ if (player.value) {
133
+ player.value.destroy();
134
+ player.value = null;
135
+ }
136
+ state.isPlaying = false;
137
+ state.isLoaded = false;
138
+ state.fps = 0;
139
+ state.resolution = "-";
140
+ state.decoded = 0;
141
+ state.downloaded = 0;
142
+ state.droppedFrames = 0;
143
+ state.segmentIndex = 0;
144
+ state.totalSegments = 0;
145
+ state.downloadSpeed = 0;
146
+ state.currentTime = 0;
147
+ state.duration = 0;
148
+ detectedFormat.value = "";
149
+ const config = {
150
+ ...createConfig(currentOptions),
151
+ canvas: canvasRef.value,
152
+ isLive: isLiveParam
153
+ };
154
+ player.value = new EcPlayerCore(config, callbacks);
155
+ await player.value.load(url, isLiveParam);
156
+ detectedFormat.value = player.value.getDetectedFormat();
157
+ emit("format-detected", detectedFormat.value);
158
+ state.isLoaded = true;
159
+ emit("loaded");
160
+ await player.value.play();
161
+ console.log("[EcPlayer] Playing stream, format:", detectedFormat.value);
162
+ } catch (error) {
163
+ console.error("[EcPlayer] Failed to play:", error?.message || error);
164
+ emit("error", error);
165
+ } finally {
166
+ isLoading.value = false;
167
+ }
168
+ }
169
+ function setOptions(options) {
170
+ if (options.targetBufferSize !== void 0) {
171
+ currentOptions.targetBufferSize = options.targetBufferSize;
172
+ }
173
+ if (options.decodeBatchSize !== void 0) {
174
+ currentOptions.decodeBatchSize = options.decodeBatchSize;
175
+ }
176
+ if (options.maxQueueSize !== void 0) {
177
+ currentOptions.maxQueueSize = options.maxQueueSize;
178
+ }
179
+ console.log("[EcPlayer] Options updated:", currentOptions);
180
+ }
181
+ function setLogLevel$1(level) {
182
+ setLogLevel(level);
183
+ }
184
+ function pause() {
185
+ player.value?.pause();
186
+ }
187
+ async function resume() {
188
+ if (!player.value) return;
189
+ await player.value.play();
190
+ }
191
+ async function seek(time) {
192
+ if (!player.value) return;
193
+ await player.value.seek(time);
194
+ }
195
+ function getPlayer() {
196
+ return player.value;
197
+ }
198
+ function getState() {
199
+ return player.value?.getState() ?? { ...state };
200
+ }
201
+ function getCurrentTime() {
202
+ return player.value?.getCurrentTime() ?? 0;
203
+ }
204
+ function getDuration() {
205
+ return player.value?.getDuration() ?? 0;
206
+ }
207
+ function destroy() {
208
+ if (player.value) {
209
+ player.value.destroy();
210
+ player.value = null;
211
+ }
212
+ }
213
+ onUnmounted(() => {
214
+ destroy();
215
+ });
216
+ return {
217
+ canvasRef,
218
+ player,
219
+ state,
220
+ isLoading,
221
+ detectedFormat,
222
+ isLive,
223
+ play,
224
+ setOptions,
225
+ setLogLevel: setLogLevel$1,
226
+ pause,
227
+ resume,
228
+ seek,
229
+ getPlayer,
230
+ getState,
231
+ getCurrentTime,
232
+ getDuration,
233
+ destroy
234
+ };
235
+ }
236
+ let hideControlsTimer = null;
237
+ function useControls(params) {
238
+ const {
239
+ isPlaying,
240
+ isLoaded,
241
+ currentTime,
242
+ duration,
243
+ segmentIndex,
244
+ totalSegments,
245
+ isLive,
246
+ seek
247
+ } = params;
248
+ const showControls = ref(true);
249
+ const hoverTime = ref(null);
250
+ const hoverPosition = ref(0);
251
+ const playProgress = computed(() => {
252
+ if (duration.value === 0) return 0;
253
+ return currentTime.value / duration.value * 100;
254
+ });
255
+ const bufferProgress = computed(() => {
256
+ if (totalSegments.value === 0) return 0;
257
+ return segmentIndex.value / totalSegments.value * 100;
258
+ });
259
+ function showControlsBar() {
260
+ showControls.value = true;
261
+ if (hideControlsTimer) {
262
+ clearTimeout(hideControlsTimer);
263
+ }
264
+ hideControlsTimer = window.setTimeout(() => {
265
+ if (isPlaying.value) {
266
+ showControls.value = false;
267
+ }
268
+ }, 3e3);
269
+ }
270
+ function hideControlsBar() {
271
+ if (isPlaying.value) {
272
+ showControls.value = false;
273
+ }
274
+ }
275
+ async function handleProgressClick(event) {
276
+ if (duration.value === 0) return;
277
+ const target = event.currentTarget;
278
+ const rect = target.getBoundingClientRect();
279
+ const clickX = event.clientX - rect.left;
280
+ const percentage = clickX / rect.width;
281
+ const targetTime = percentage * duration.value;
282
+ await seek(targetTime);
283
+ }
284
+ function handleProgressHover(event) {
285
+ if (duration.value === 0) return;
286
+ const target = event.currentTarget;
287
+ const rect = target.getBoundingClientRect();
288
+ const hoverX = event.clientX - rect.left;
289
+ const percentage = Math.max(0, Math.min(1, hoverX / rect.width));
290
+ hoverTime.value = percentage * duration.value;
291
+ hoverPosition.value = percentage * 100;
292
+ }
293
+ function formatTime(ms) {
294
+ const totalSeconds = Math.floor(ms / 1e3);
295
+ const hours = Math.floor(totalSeconds / 3600);
296
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
297
+ const seconds = totalSeconds % 60;
298
+ if (hours > 0) {
299
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
300
+ }
301
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
302
+ }
303
+ return {
304
+ showControls,
305
+ hoverTime,
306
+ hoverPosition,
307
+ playProgress,
308
+ bufferProgress,
309
+ showControlsBar,
310
+ hideControlsBar,
311
+ handleProgressClick,
312
+ handleProgressHover,
313
+ formatTime
314
+ };
315
+ }
316
+ function useEnvInfo(initialShowPanel = false) {
317
+ const envInfo = ref(null);
318
+ const showEnvPanel = ref(initialShowPanel);
319
+ const envTypeText = computed(() => {
320
+ if (!envInfo.value) return "未知";
321
+ const typeMap = {
322
+ "pc-browser": "PC 浏览器",
323
+ "mobile-browser": "移动端浏览器",
324
+ "wechat-miniprogram": "微信小程序",
325
+ "alipay-miniprogram": "支付宝小程序",
326
+ "other-miniprogram": "其他小程序",
327
+ "unknown": "未知"
328
+ };
329
+ return typeMap[envInfo.value.platform] || envInfo.value.platform;
330
+ });
331
+ function toggleEnvPanel() {
332
+ showEnvPanel.value = !showEnvPanel.value;
333
+ }
334
+ function detectEnv() {
335
+ envInfo.value = EnvDetector.detect();
336
+ console.log("[EcPlayer] 环境检测结果:", envInfo.value);
337
+ }
338
+ onMounted(() => {
339
+ detectEnv();
340
+ });
341
+ return {
342
+ envInfo,
343
+ showEnvPanel,
344
+ envTypeText,
345
+ toggleEnvPanel,
346
+ detectEnv
347
+ };
348
+ }
349
+ const _hoisted_1 = { class: "gt-player-container" };
350
+ const _hoisted_2 = {
351
+ key: 0,
352
+ class: "gt-env-panel"
353
+ };
354
+ const _hoisted_3 = { class: "gt-env-row" };
355
+ const _hoisted_4 = { class: "gt-env-row" };
356
+ const _hoisted_5 = { class: "gt-env-row" };
357
+ const _hoisted_6 = { class: "gt-env-row" };
358
+ const _hoisted_7 = { class: "gt-env-row" };
359
+ const _hoisted_8 = { class: "gt-env-row" };
360
+ const _hoisted_9 = { class: "gt-env-row" };
361
+ const _hoisted_10 = { class: "gt-env-row" };
362
+ const _hoisted_11 = { class: "gt-env-row" };
363
+ const _hoisted_12 = { class: "gt-env-row" };
364
+ const _hoisted_13 = { class: "gt-env-row" };
365
+ const _hoisted_14 = { class: "gt-env-row" };
366
+ const _hoisted_15 = { class: "gt-env-row" };
367
+ const _hoisted_16 = { class: "gt-env-row" };
368
+ const _hoisted_17 = {
369
+ key: 1,
370
+ class: "gt-loading-spinner"
371
+ };
372
+ const _hoisted_18 = {
373
+ key: 0,
374
+ viewBox: "0 0 24 24",
375
+ fill: "currentColor"
376
+ };
377
+ const _hoisted_19 = {
378
+ key: 1,
379
+ viewBox: "0 0 24 24",
380
+ fill: "currentColor"
381
+ };
382
+ const _hoisted_20 = {
383
+ key: 0,
384
+ class: "gt-live-indicator"
385
+ };
386
+ const _hoisted_21 = {
387
+ key: 1,
388
+ class: "gt-time-display"
389
+ };
390
+ const _hoisted_22 = { class: "gt-time-current" };
391
+ const _hoisted_23 = { class: "gt-time-duration" };
392
+ const _hoisted_24 = { class: "gt-progress-bar" };
393
+ const _hoisted_25 = {
394
+ key: 3,
395
+ class: "gt-flex-spacer"
396
+ };
397
+ const _hoisted_26 = {
398
+ key: 4,
399
+ class: "gt-info-badge"
400
+ };
401
+ const _hoisted_27 = ["title"];
402
+ const _sfc_main = /* @__PURE__ */ defineComponent({
403
+ __name: "EcPlayer",
404
+ props: /* @__PURE__ */ mergeDefaults({
405
+ showEnvPanel: { type: Boolean },
406
+ showControls: { type: Boolean }
407
+ }, DEFAULT_EC_PLAYER_PROPS),
408
+ emits: ["play", "pause", "loaded", "error", "state-change", "format-detected"],
409
+ setup(__props, { expose: __expose, emit: __emit }) {
410
+ const props = __props;
411
+ const emit = __emit;
412
+ const canvasRef = ref(null);
413
+ const { envInfo, showEnvPanel, envTypeText, toggleEnvPanel } = useEnvInfo(props.showEnvPanel);
414
+ const player = usePlayer(props, emit);
415
+ watch(canvasRef, (el) => {
416
+ player.canvasRef.value = el;
417
+ }, { immediate: true });
418
+ const isLive = computed(() => player.isLive.value);
419
+ const isPlayingRef = computed(() => player.state.isPlaying);
420
+ const isLoadedRef = computed(() => player.state.isLoaded);
421
+ const currentTimeRef = computed(() => player.state.currentTime);
422
+ const durationRef = computed(() => player.state.duration);
423
+ const segmentIndexRef = computed(() => player.state.segmentIndex);
424
+ const totalSegmentsRef = computed(() => player.state.totalSegments);
425
+ const controls = useControls({
426
+ isPlaying: isPlayingRef,
427
+ isLoaded: isLoadedRef,
428
+ currentTime: currentTimeRef,
429
+ duration: durationRef,
430
+ segmentIndex: segmentIndexRef,
431
+ totalSegments: totalSegmentsRef,
432
+ isLive,
433
+ seek: player.seek
434
+ });
435
+ const videoWrapperRef = ref(null);
436
+ const showControlsProp = computed(() => props.showControls);
437
+ function togglePlayback() {
438
+ if (player.state.isPlaying) {
439
+ player.pause();
440
+ } else {
441
+ player.resume();
442
+ }
443
+ }
444
+ __expose({
445
+ play: player.play,
446
+ setOptions: player.setOptions,
447
+ setLogLevel: player.setLogLevel,
448
+ pause: player.pause,
449
+ seek: player.seek,
450
+ getPlayer: player.getPlayer,
451
+ getState: player.getState,
452
+ getCurrentTime: player.getCurrentTime,
453
+ getDuration: player.getDuration
454
+ });
455
+ return (_ctx, _cache) => {
456
+ return openBlock(), createElementBlock("div", _hoisted_1, [
457
+ createElementVNode("div", {
458
+ class: "gt-video-wrapper",
459
+ ref_key: "videoWrapperRef",
460
+ ref: videoWrapperRef,
461
+ onMouseenter: _cache[4] || (_cache[4] = //@ts-ignore
462
+ (...args) => unref(controls).showControlsBar && unref(controls).showControlsBar(...args)),
463
+ onMousemove: _cache[5] || (_cache[5] = //@ts-ignore
464
+ (...args) => unref(controls).showControlsBar && unref(controls).showControlsBar(...args)),
465
+ onMouseleave: _cache[6] || (_cache[6] = //@ts-ignore
466
+ (...args) => unref(controls).hideControlsBar && unref(controls).hideControlsBar(...args))
467
+ }, [
468
+ createElementVNode("canvas", {
469
+ ref_key: "canvasRef",
470
+ ref: canvasRef,
471
+ class: "gt-player-canvas"
472
+ }, null, 512),
473
+ unref(showEnvPanel) && unref(envInfo) ? (openBlock(), createElementBlock("div", _hoisted_2, [
474
+ createElementVNode("div", _hoisted_3, [
475
+ _cache[7] || (_cache[7] = createElementVNode("span", null, "platform", -1)),
476
+ createElementVNode("span", {
477
+ class: normalizeClass(unref(envInfo).isMiniProgram ? "warn" : "")
478
+ }, toDisplayString(unref(envTypeText)), 3)
479
+ ]),
480
+ _cache[22] || (_cache[22] = createElementVNode("div", { class: "gt-env-divider" }, null, -1)),
481
+ createElementVNode("div", _hoisted_4, [
482
+ _cache[8] || (_cache[8] = createElementVNode("span", null, "SIMD", -1)),
483
+ createElementVNode("span", {
484
+ class: normalizeClass(unref(envInfo).capabilities.wasmSimd ? "ok" : "err")
485
+ }, toDisplayString(unref(envInfo).capabilities.wasmSimd ? "Yes" : "No"), 3)
486
+ ]),
487
+ createElementVNode("div", _hoisted_5, [
488
+ _cache[9] || (_cache[9] = createElementVNode("span", null, "WebGL", -1)),
489
+ createElementVNode("span", {
490
+ class: normalizeClass(unref(envInfo).capabilities.webGL ? "ok" : "err")
491
+ }, toDisplayString(unref(envInfo).capabilities.webGL ? "Yes" : "No"), 3)
492
+ ]),
493
+ createElementVNode("div", _hoisted_6, [
494
+ _cache[10] || (_cache[10] = createElementVNode("span", null, "WebGL2", -1)),
495
+ createElementVNode("span", {
496
+ class: normalizeClass(unref(envInfo).capabilities.webGL2 ? "ok" : "err")
497
+ }, toDisplayString(unref(envInfo).capabilities.webGL2 ? "Yes" : "No"), 3)
498
+ ]),
499
+ createElementVNode("div", _hoisted_7, [
500
+ _cache[11] || (_cache[11] = createElementVNode("span", null, "SAB", -1)),
501
+ createElementVNode("span", {
502
+ class: normalizeClass(unref(envInfo).capabilities.sharedArrayBuffer ? "ok" : "err")
503
+ }, toDisplayString(unref(envInfo).capabilities.sharedArrayBuffer ? "Yes" : "No"), 3)
504
+ ]),
505
+ createElementVNode("div", _hoisted_8, [
506
+ _cache[12] || (_cache[12] = createElementVNode("span", null, "Threads", -1)),
507
+ createElementVNode("span", {
508
+ class: normalizeClass(unref(envInfo).capabilities.wasmThreads ? "ok" : "err")
509
+ }, toDisplayString(unref(envInfo).capabilities.wasmThreads ? "Yes" : "No"), 3)
510
+ ]),
511
+ createElementVNode("div", _hoisted_9, [
512
+ _cache[13] || (_cache[13] = createElementVNode("span", null, "WebAudio", -1)),
513
+ createElementVNode("span", {
514
+ class: normalizeClass(unref(envInfo).capabilities.webAudio ? "ok" : "err")
515
+ }, toDisplayString(unref(envInfo).capabilities.webAudio ? "Yes" : "No"), 3)
516
+ ]),
517
+ createElementVNode("div", _hoisted_10, [
518
+ _cache[14] || (_cache[14] = createElementVNode("span", null, "Stream", -1)),
519
+ createElementVNode("span", {
520
+ class: normalizeClass(unref(envInfo).capabilities.readableStream ? "ok" : "err")
521
+ }, toDisplayString(unref(envInfo).capabilities.readableStream ? "Yes" : "No"), 3)
522
+ ]),
523
+ unref(player).state.isLoaded ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
524
+ _cache[21] || (_cache[21] = createElementVNode("div", { class: "gt-env-divider" }, null, -1)),
525
+ createElementVNode("div", _hoisted_11, [
526
+ _cache[15] || (_cache[15] = createElementVNode("span", null, "FPS", -1)),
527
+ createElementVNode("span", null, toDisplayString(unref(player).state.fps), 1)
528
+ ]),
529
+ createElementVNode("div", _hoisted_12, [
530
+ _cache[16] || (_cache[16] = createElementVNode("span", null, "Resolution", -1)),
531
+ createElementVNode("span", null, toDisplayString(unref(player).state.resolution), 1)
532
+ ]),
533
+ createElementVNode("div", _hoisted_13, [
534
+ _cache[17] || (_cache[17] = createElementVNode("span", null, "downloaded", -1)),
535
+ createElementVNode("span", null, toDisplayString(unref(player).state.downloaded), 1)
536
+ ]),
537
+ createElementVNode("div", _hoisted_14, [
538
+ _cache[18] || (_cache[18] = createElementVNode("span", null, "decoded", -1)),
539
+ createElementVNode("span", null, toDisplayString(unref(player).state.decoded), 1)
540
+ ]),
541
+ createElementVNode("div", _hoisted_15, [
542
+ _cache[19] || (_cache[19] = createElementVNode("span", null, "Dropped", -1)),
543
+ createElementVNode("span", null, toDisplayString(unref(player).state.droppedFrames), 1)
544
+ ]),
545
+ createElementVNode("div", _hoisted_16, [
546
+ _cache[20] || (_cache[20] = createElementVNode("span", null, "Speed", -1)),
547
+ createElementVNode("span", null, toDisplayString(unref(player).state.downloadSpeed || 0) + " KB/s", 1)
548
+ ])
549
+ ], 64)) : createCommentVNode("", true)
550
+ ])) : createCommentVNode("", true),
551
+ unref(player).isLoading.value ? (openBlock(), createElementBlock("div", _hoisted_17, [..._cache[23] || (_cache[23] = [
552
+ createElementVNode("div", { class: "gt-spinner" }, null, -1)
553
+ ])])) : createCommentVNode("", true),
554
+ showControlsProp.value ? (openBlock(), createElementBlock("div", {
555
+ key: 2,
556
+ class: normalizeClass(["gt-video-controls", { visible: unref(controls).showControls.value || !unref(player).state.isPlaying }])
557
+ }, [
558
+ createElementVNode("button", {
559
+ class: "gt-control-btn",
560
+ onClick: togglePlayback
561
+ }, [
562
+ unref(player).state.isPlaying ? (openBlock(), createElementBlock("svg", _hoisted_18, [..._cache[24] || (_cache[24] = [
563
+ createElementVNode("rect", {
564
+ x: "6",
565
+ y: "4",
566
+ width: "4",
567
+ height: "16",
568
+ rx: "1"
569
+ }, null, -1),
570
+ createElementVNode("rect", {
571
+ x: "14",
572
+ y: "4",
573
+ width: "4",
574
+ height: "16",
575
+ rx: "1"
576
+ }, null, -1)
577
+ ])])) : (openBlock(), createElementBlock("svg", _hoisted_19, [..._cache[25] || (_cache[25] = [
578
+ createElementVNode("path", { d: "M8 5v14l11-7z" }, null, -1)
579
+ ])]))
580
+ ]),
581
+ isLive.value ? (openBlock(), createElementBlock("span", _hoisted_20, [..._cache[26] || (_cache[26] = [
582
+ createElementVNode("span", { class: "gt-live-dot" }, null, -1),
583
+ createElementVNode("span", { class: "gt-live-text" }, "实时", -1)
584
+ ])])) : (openBlock(), createElementBlock("span", _hoisted_21, [
585
+ createElementVNode("span", _hoisted_22, toDisplayString(unref(controls).formatTime(unref(player).state.currentTime)), 1),
586
+ _cache[27] || (_cache[27] = createElementVNode("span", { class: "gt-time-separator" }, "/", -1)),
587
+ createElementVNode("span", _hoisted_23, toDisplayString(unref(controls).formatTime(unref(player).state.duration)), 1)
588
+ ])),
589
+ !isLive.value ? (openBlock(), createElementBlock("div", {
590
+ key: 2,
591
+ class: "gt-progress-container",
592
+ onClick: _cache[0] || (_cache[0] = //@ts-ignore
593
+ (...args) => unref(controls).handleProgressClick && unref(controls).handleProgressClick(...args)),
594
+ onMousemove: _cache[1] || (_cache[1] = //@ts-ignore
595
+ (...args) => unref(controls).handleProgressHover && unref(controls).handleProgressHover(...args)),
596
+ onMouseleave: _cache[2] || (_cache[2] = ($event) => unref(controls).hoverTime.value = null)
597
+ }, [
598
+ createElementVNode("div", _hoisted_24, [
599
+ createElementVNode("div", {
600
+ class: "gt-progress-buffered",
601
+ style: normalizeStyle({ width: unref(controls).bufferProgress.value + "%" })
602
+ }, null, 4),
603
+ createElementVNode("div", {
604
+ class: "gt-progress-played",
605
+ style: normalizeStyle({ width: unref(controls).playProgress.value + "%" })
606
+ }, [..._cache[28] || (_cache[28] = [
607
+ createElementVNode("div", { class: "gt-progress-handle" }, null, -1)
608
+ ])], 4)
609
+ ]),
610
+ unref(controls).hoverTime.value !== null ? (openBlock(), createElementBlock("div", {
611
+ key: 0,
612
+ class: "gt-progress-tooltip",
613
+ style: normalizeStyle({ left: unref(controls).hoverPosition.value + "%" })
614
+ }, toDisplayString(unref(controls).formatTime(unref(controls).hoverTime.value)), 5)) : createCommentVNode("", true)
615
+ ], 32)) : (openBlock(), createElementBlock("div", _hoisted_25)),
616
+ unref(player).detectedFormat.value ? (openBlock(), createElementBlock("span", _hoisted_26, toDisplayString(unref(player).detectedFormat.value), 1)) : createCommentVNode("", true),
617
+ createElementVNode("button", {
618
+ class: "gt-control-btn gt-env-info-btn",
619
+ onClick: _cache[3] || (_cache[3] = //@ts-ignore
620
+ (...args) => unref(toggleEnvPanel) && unref(toggleEnvPanel)(...args)),
621
+ title: unref(showEnvPanel) ? "隐藏信息" : "显示信息"
622
+ }, [..._cache[29] || (_cache[29] = [
623
+ createElementVNode("svg", {
624
+ viewBox: "0 0 24 24",
625
+ fill: "currentColor"
626
+ }, [
627
+ createElementVNode("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" })
628
+ ], -1)
629
+ ])], 8, _hoisted_27)
630
+ ], 2)) : createCommentVNode("", true),
631
+ unref(player).state.isLoaded && !unref(player).state.isPlaying ? (openBlock(), createElementBlock("div", {
632
+ key: 3,
633
+ class: "gt-center-play-btn",
634
+ onClick: togglePlayback
635
+ }, [..._cache[30] || (_cache[30] = [
636
+ createElementVNode("svg", {
637
+ viewBox: "0 0 24 24",
638
+ fill: "currentColor"
639
+ }, [
640
+ createElementVNode("path", { d: "M8 5v14l11-7z" })
641
+ ], -1)
642
+ ])])) : createCommentVNode("", true)
643
+ ], 544)
644
+ ]);
645
+ };
646
+ }
647
+ });
648
+ const _export_sfc = (sfc, props) => {
649
+ const target = sfc.__vccOpts || sfc;
650
+ for (const [key, val] of props) {
651
+ target[key] = val;
652
+ }
653
+ return target;
654
+ };
655
+ const EcPlayer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b2f99f46"]]);
656
+ export {
657
+ DEFAULT_EC_PLAYER_PROPS,
658
+ DEFAULT_PLAYER_OPTIONS,
659
+ DEFAULT_WASM_CONFIG,
660
+ EcPlayer,
661
+ LogLevel,
662
+ configureEcPlayer,
663
+ getGlobalConfig,
664
+ getMergedConfig,
665
+ getMergedPlayerOptions,
666
+ getWasmConfig,
667
+ resolveWasmPath,
668
+ useControls,
669
+ useEnvInfo,
670
+ usePlayer
671
+ };
672
+ //# sourceMappingURL=index.js.map