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