@give-tech/ec-player-vue 1.0.1 → 1.0.2
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/composables/useControls.d.ts.map +1 -1
- package/dist/composables/usePlayer.d.ts +0 -1
- package/dist/composables/usePlayer.d.ts.map +1 -1
- package/dist/ec-player-vue.css +45 -45
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useControls.d.ts","sourceRoot":"","sources":["../../src/composables/useControls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAE7C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa;IACb,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,YAAY;IACZ,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,eAAe;IACf,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,cAAc;IACd,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,WAAW;IACX,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,WAAW;IACX,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,aAAa;IACb,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpB,WAAW;IACX,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc;IACd,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,mBAAmB;IACnB,SAAS,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC7B,mBAAmB;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,cAAc;IACd,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,cAAc;IACd,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,YAAY;IACZ,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,YAAY;IACZ,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,cAAc;IACd,mBAAmB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,cAAc;IACd,mBAAmB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAChD,YAAY;IACZ,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;CACnC;
|
|
1
|
+
{"version":3,"file":"useControls.d.ts","sourceRoot":"","sources":["../../src/composables/useControls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAE7C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,aAAa;IACb,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,YAAY;IACZ,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,eAAe;IACf,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,cAAc;IACd,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,WAAW;IACX,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,WAAW;IACX,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,aAAa;IACb,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpB,WAAW;IACX,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc;IACd,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,mBAAmB;IACnB,SAAS,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC7B,mBAAmB;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,cAAc;IACd,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,cAAc;IACd,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,YAAY;IACZ,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,YAAY;IACZ,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B,cAAc;IACd,mBAAmB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,cAAc;IACd,mBAAmB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAChD,YAAY;IACZ,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAA;CACnC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAoGxE"}
|
|
@@ -54,7 +54,6 @@ export declare function usePlayer(props: EcPlayerProps, emit: {
|
|
|
54
54
|
(e: 'pause'): void;
|
|
55
55
|
(e: 'loaded'): void;
|
|
56
56
|
(e: 'error', error: Error): void;
|
|
57
|
-
(e: 'state-change', state: Partial<EcPlayerState>): void;
|
|
58
57
|
(e: 'format-detected', format: string): void;
|
|
59
58
|
}): UsePlayerReturn;
|
|
60
59
|
//# sourceMappingURL=usePlayer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePlayer.d.ts","sourceRoot":"","sources":["../../src/composables/usePlayer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA0C,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AACtE,OAAO,EACL,YAAY,EAIZ,KAAK,aAAa,EAEnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAG5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IACxC,YAAY;IACZ,MAAM,EAAE,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAChC,YAAY;IACZ,KAAK,EAAE,aAAa,CAAA;IACpB,aAAa;IACb,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,aAAa;IACb,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,aAAa;IACb,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpB,SAAS;IACT,IAAI,EAAE,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE,WAAW;IACX,UAAU,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,aAAa;IACb,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,SAAS;IACT,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,WAAW;IACX,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS;IACT,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,cAAc;IACd,SAAS,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;IACpC,WAAW;IACX,QAAQ,EAAE,MAAM,aAAa,CAAA;IAC7B,aAAa;IACb,cAAc,EAAE,MAAM,MAAM,CAAA;IAC5B,YAAY;IACZ,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,YAAY;IACZ,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAkBD;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE;IACJ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAClB,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IACnB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAChC,CAAC,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"usePlayer.d.ts","sourceRoot":"","sources":["../../src/composables/usePlayer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAA0C,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AACtE,OAAO,EACL,YAAY,EAIZ,KAAK,aAAa,EAEnB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAG5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IACxC,YAAY;IACZ,MAAM,EAAE,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAChC,YAAY;IACZ,KAAK,EAAE,aAAa,CAAA;IACpB,aAAa;IACb,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,aAAa;IACb,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,aAAa;IACb,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpB,SAAS;IACT,IAAI,EAAE,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnE,WAAW;IACX,UAAU,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,aAAa;IACb,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,SAAS;IACT,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,WAAW;IACX,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,SAAS;IACT,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,cAAc;IACd,SAAS,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;IACpC,WAAW;IACX,QAAQ,EAAE,MAAM,aAAa,CAAA;IAC7B,aAAa;IACb,cAAc,EAAE,MAAM,MAAM,CAAA;IAC5B,YAAY;IACZ,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,YAAY;IACZ,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAkBD;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE;IACJ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAClB,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IACnB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAChC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7C,GACA,eAAe,CA+NjB"}
|
package/dist/ec-player-vue.css
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
|
|
2
|
-
.gt-player-container[data-v-
|
|
2
|
+
.gt-player-container[data-v-71bbf3ca] {
|
|
3
3
|
width: 100%;
|
|
4
4
|
max-width: 800px;
|
|
5
5
|
margin: 0 auto;
|
|
6
6
|
}
|
|
7
|
-
.gt-video-wrapper[data-v-
|
|
7
|
+
.gt-video-wrapper[data-v-71bbf3ca] {
|
|
8
8
|
position: relative;
|
|
9
9
|
background: #000;
|
|
10
10
|
border-radius: 4px;
|
|
11
11
|
overflow: hidden;
|
|
12
12
|
width: 100%;
|
|
13
13
|
}
|
|
14
|
-
.gt-player-canvas[data-v-
|
|
14
|
+
.gt-player-canvas[data-v-71bbf3ca] {
|
|
15
15
|
width: 100%;
|
|
16
16
|
height: auto;
|
|
17
17
|
display: block;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/* 加载中动画 */
|
|
21
|
-
.gt-loading-spinner[data-v-
|
|
21
|
+
.gt-loading-spinner[data-v-71bbf3ca] {
|
|
22
22
|
position: absolute;
|
|
23
23
|
top: 0;
|
|
24
24
|
left: 0;
|
|
@@ -30,22 +30,22 @@
|
|
|
30
30
|
background: rgba(0, 0, 0, 0.5);
|
|
31
31
|
z-index: 10;
|
|
32
32
|
}
|
|
33
|
-
.gt-spinner[data-v-
|
|
33
|
+
.gt-spinner[data-v-71bbf3ca] {
|
|
34
34
|
width: 8vmin;
|
|
35
35
|
height: 8vmin;
|
|
36
36
|
border: 0.5vmin solid rgba(255, 255, 255, 0.3);
|
|
37
37
|
border-top-color: #fff;
|
|
38
38
|
border-radius: 50%;
|
|
39
|
-
animation: gt-spin-
|
|
39
|
+
animation: gt-spin-71bbf3ca 1s linear infinite;
|
|
40
40
|
}
|
|
41
|
-
@keyframes gt-spin-
|
|
41
|
+
@keyframes gt-spin-71bbf3ca {
|
|
42
42
|
to {
|
|
43
43
|
transform: rotate(360deg);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/* 视频控制条 */
|
|
48
|
-
.gt-video-controls[data-v-
|
|
48
|
+
.gt-video-controls[data-v-71bbf3ca] {
|
|
49
49
|
position: absolute;
|
|
50
50
|
bottom: 0;
|
|
51
51
|
left: 0;
|
|
@@ -58,13 +58,13 @@ to {
|
|
|
58
58
|
align-items: center;
|
|
59
59
|
gap: 12px;
|
|
60
60
|
}
|
|
61
|
-
.gt-flex-spacer[data-v-
|
|
61
|
+
.gt-flex-spacer[data-v-71bbf3ca] {
|
|
62
62
|
flex: 1;
|
|
63
63
|
}
|
|
64
|
-
.gt-video-controls.visible[data-v-
|
|
64
|
+
.gt-video-controls.visible[data-v-71bbf3ca] {
|
|
65
65
|
opacity: 1;
|
|
66
66
|
}
|
|
67
|
-
.gt-control-btn[data-v-
|
|
67
|
+
.gt-control-btn[data-v-71bbf3ca] {
|
|
68
68
|
width: 28px;
|
|
69
69
|
height: 28px;
|
|
70
70
|
border: none;
|
|
@@ -78,14 +78,14 @@ to {
|
|
|
78
78
|
transition: all 0.2s ease;
|
|
79
79
|
flex-shrink: 0;
|
|
80
80
|
}
|
|
81
|
-
.gt-control-btn[data-v-
|
|
81
|
+
.gt-control-btn[data-v-71bbf3ca]:hover {
|
|
82
82
|
background: rgba(255, 255, 255, 0.2);
|
|
83
83
|
}
|
|
84
|
-
.gt-control-btn svg[data-v-
|
|
84
|
+
.gt-control-btn svg[data-v-71bbf3ca] {
|
|
85
85
|
width: 14px;
|
|
86
86
|
height: 14px;
|
|
87
87
|
}
|
|
88
|
-
.gt-progress-container[data-v-
|
|
88
|
+
.gt-progress-container[data-v-71bbf3ca] {
|
|
89
89
|
flex: 1;
|
|
90
90
|
position: relative;
|
|
91
91
|
cursor: pointer;
|
|
@@ -93,7 +93,7 @@ to {
|
|
|
93
93
|
display: flex;
|
|
94
94
|
align-items: center;
|
|
95
95
|
}
|
|
96
|
-
.gt-progress-bar[data-v-
|
|
96
|
+
.gt-progress-bar[data-v-71bbf3ca] {
|
|
97
97
|
width: 100%;
|
|
98
98
|
height: 4px;
|
|
99
99
|
background: rgba(255, 255, 255, 0.2);
|
|
@@ -102,10 +102,10 @@ to {
|
|
|
102
102
|
overflow: hidden;
|
|
103
103
|
transition: height 0.2s ease;
|
|
104
104
|
}
|
|
105
|
-
.gt-progress-container:hover .gt-progress-bar[data-v-
|
|
105
|
+
.gt-progress-container:hover .gt-progress-bar[data-v-71bbf3ca] {
|
|
106
106
|
height: 6px;
|
|
107
107
|
}
|
|
108
|
-
.gt-progress-buffered[data-v-
|
|
108
|
+
.gt-progress-buffered[data-v-71bbf3ca] {
|
|
109
109
|
position: absolute;
|
|
110
110
|
top: 0;
|
|
111
111
|
left: 0;
|
|
@@ -114,7 +114,7 @@ to {
|
|
|
114
114
|
border-radius: 2px;
|
|
115
115
|
transition: width 0.1s;
|
|
116
116
|
}
|
|
117
|
-
.gt-progress-played[data-v-
|
|
117
|
+
.gt-progress-played[data-v-71bbf3ca] {
|
|
118
118
|
position: absolute;
|
|
119
119
|
top: 0;
|
|
120
120
|
left: 0;
|
|
@@ -123,7 +123,7 @@ to {
|
|
|
123
123
|
border-radius: 2px;
|
|
124
124
|
transition: width 0.1s;
|
|
125
125
|
}
|
|
126
|
-
.gt-progress-handle[data-v-
|
|
126
|
+
.gt-progress-handle[data-v-71bbf3ca] {
|
|
127
127
|
position: absolute;
|
|
128
128
|
right: -6px;
|
|
129
129
|
top: 50%;
|
|
@@ -136,11 +136,11 @@ to {
|
|
|
136
136
|
opacity: 0;
|
|
137
137
|
transition: opacity 0.2s, transform 0.2s;
|
|
138
138
|
}
|
|
139
|
-
.gt-progress-container:hover .gt-progress-handle[data-v-
|
|
139
|
+
.gt-progress-container:hover .gt-progress-handle[data-v-71bbf3ca] {
|
|
140
140
|
opacity: 1;
|
|
141
141
|
transform: translateY(-50%) scale(1.2);
|
|
142
142
|
}
|
|
143
|
-
.gt-progress-tooltip[data-v-
|
|
143
|
+
.gt-progress-tooltip[data-v-71bbf3ca] {
|
|
144
144
|
position: absolute;
|
|
145
145
|
bottom: calc(100% + 8px);
|
|
146
146
|
transform: translateX(-50%);
|
|
@@ -152,18 +152,18 @@ to {
|
|
|
152
152
|
white-space: nowrap;
|
|
153
153
|
pointer-events: none;
|
|
154
154
|
}
|
|
155
|
-
.gt-time-display[data-v-
|
|
155
|
+
.gt-time-display[data-v-71bbf3ca] {
|
|
156
156
|
color: white;
|
|
157
157
|
font-size: 12px;
|
|
158
158
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
159
159
|
white-space: nowrap;
|
|
160
160
|
flex-shrink: 0;
|
|
161
161
|
}
|
|
162
|
-
.gt-time-separator[data-v-
|
|
162
|
+
.gt-time-separator[data-v-71bbf3ca] {
|
|
163
163
|
margin: 0 4px;
|
|
164
164
|
opacity: 0.6;
|
|
165
165
|
}
|
|
166
|
-
.gt-info-badge[data-v-
|
|
166
|
+
.gt-info-badge[data-v-71bbf3ca] {
|
|
167
167
|
background: rgba(255, 255, 255, 0.2);
|
|
168
168
|
color: white;
|
|
169
169
|
padding: 4px 10px;
|
|
@@ -175,7 +175,7 @@ to {
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
/* 直播指示器 */
|
|
178
|
-
.gt-live-indicator[data-v-
|
|
178
|
+
.gt-live-indicator[data-v-71bbf3ca] {
|
|
179
179
|
display: flex;
|
|
180
180
|
align-items: center;
|
|
181
181
|
gap: 6px;
|
|
@@ -183,17 +183,17 @@ to {
|
|
|
183
183
|
font-size: 12px;
|
|
184
184
|
font-weight: 500;
|
|
185
185
|
}
|
|
186
|
-
.gt-live-dot[data-v-
|
|
186
|
+
.gt-live-dot[data-v-71bbf3ca] {
|
|
187
187
|
width: 8px;
|
|
188
188
|
height: 8px;
|
|
189
189
|
background: #ff2d55;
|
|
190
190
|
border-radius: 50%;
|
|
191
|
-
animation: gt-live-pulse-
|
|
191
|
+
animation: gt-live-pulse-71bbf3ca 1.5s ease-in-out infinite;
|
|
192
192
|
}
|
|
193
|
-
.gt-live-text[data-v-
|
|
193
|
+
.gt-live-text[data-v-71bbf3ca] {
|
|
194
194
|
color: #ff2d55;
|
|
195
195
|
}
|
|
196
|
-
@keyframes gt-live-pulse-
|
|
196
|
+
@keyframes gt-live-pulse-71bbf3ca {
|
|
197
197
|
0%, 100% {
|
|
198
198
|
opacity: 1;
|
|
199
199
|
}
|
|
@@ -203,7 +203,7 @@ to {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/* 居中播放按钮 */
|
|
206
|
-
.gt-center-play-btn[data-v-
|
|
206
|
+
.gt-center-play-btn[data-v-71bbf3ca] {
|
|
207
207
|
position: absolute;
|
|
208
208
|
top: 50%;
|
|
209
209
|
left: 50%;
|
|
@@ -218,11 +218,11 @@ to {
|
|
|
218
218
|
cursor: pointer;
|
|
219
219
|
transition: all 0.2s ease;
|
|
220
220
|
}
|
|
221
|
-
.gt-center-play-btn[data-v-
|
|
221
|
+
.gt-center-play-btn[data-v-71bbf3ca]:hover {
|
|
222
222
|
background: rgba(0, 0, 0, 0.7);
|
|
223
223
|
transform: translate(-50%, -50%) scale(1.05);
|
|
224
224
|
}
|
|
225
|
-
.gt-center-play-btn svg[data-v-
|
|
225
|
+
.gt-center-play-btn svg[data-v-71bbf3ca] {
|
|
226
226
|
width: 24px;
|
|
227
227
|
height: 24px;
|
|
228
228
|
color: white;
|
|
@@ -230,7 +230,7 @@ to {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
/* 环境信息面板 */
|
|
233
|
-
.gt-env-panel[data-v-
|
|
233
|
+
.gt-env-panel[data-v-71bbf3ca] {
|
|
234
234
|
position: absolute;
|
|
235
235
|
top: 12px;
|
|
236
236
|
left: 12px;
|
|
@@ -244,46 +244,46 @@ to {
|
|
|
244
244
|
max-height: calc(100% - 24px);
|
|
245
245
|
overflow-y: auto;
|
|
246
246
|
backdrop-filter: blur(10px);
|
|
247
|
-
animation: gt-env-fade-in-
|
|
247
|
+
animation: gt-env-fade-in-71bbf3ca 0.15s ease;
|
|
248
248
|
z-index: 15;
|
|
249
249
|
}
|
|
250
|
-
.gt-env-panel[data-v-
|
|
250
|
+
.gt-env-panel[data-v-71bbf3ca]::-webkit-scrollbar {
|
|
251
251
|
width: 4px;
|
|
252
252
|
}
|
|
253
|
-
.gt-env-panel[data-v-
|
|
253
|
+
.gt-env-panel[data-v-71bbf3ca]::-webkit-scrollbar-track {
|
|
254
254
|
background: transparent;
|
|
255
255
|
}
|
|
256
|
-
.gt-env-panel[data-v-
|
|
256
|
+
.gt-env-panel[data-v-71bbf3ca]::-webkit-scrollbar-thumb {
|
|
257
257
|
background: rgba(255, 255, 255, 0.3);
|
|
258
258
|
border-radius: 2px;
|
|
259
259
|
}
|
|
260
|
-
@keyframes gt-env-fade-in-
|
|
260
|
+
@keyframes gt-env-fade-in-71bbf3ca {
|
|
261
261
|
from { opacity: 0; transform: translateY(-4px);
|
|
262
262
|
}
|
|
263
263
|
to { opacity: 1; transform: translateY(0);
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
-
.gt-env-panel .gt-env-row[data-v-
|
|
266
|
+
.gt-env-panel .gt-env-row[data-v-71bbf3ca] {
|
|
267
267
|
display: flex;
|
|
268
268
|
justify-content: space-between;
|
|
269
269
|
align-items: center;
|
|
270
270
|
padding: 2px 0;
|
|
271
271
|
color: rgba(255, 255, 255, 0.7);
|
|
272
272
|
}
|
|
273
|
-
.gt-env-panel .gt-env-row span[data-v-
|
|
273
|
+
.gt-env-panel .gt-env-row span[data-v-71bbf3ca]:first-child {
|
|
274
274
|
color: rgba(255, 255, 255, 0.5);
|
|
275
275
|
margin-right: 16px;
|
|
276
276
|
}
|
|
277
|
-
.gt-env-panel .gt-env-row span[data-v-
|
|
277
|
+
.gt-env-panel .gt-env-row span[data-v-71bbf3ca]:last-child {
|
|
278
278
|
font-variant-numeric: tabular-nums;
|
|
279
279
|
}
|
|
280
|
-
.gt-env-panel .gt-env-row .ok[data-v-
|
|
280
|
+
.gt-env-panel .gt-env-row .ok[data-v-71bbf3ca] { color: #4caf50;
|
|
281
281
|
}
|
|
282
|
-
.gt-env-panel .gt-env-row .warn[data-v-
|
|
282
|
+
.gt-env-panel .gt-env-row .warn[data-v-71bbf3ca] { color: #ff9800;
|
|
283
283
|
}
|
|
284
|
-
.gt-env-panel .gt-env-row .err[data-v-
|
|
284
|
+
.gt-env-panel .gt-env-row .err[data-v-71bbf3ca] { color: #f44336;
|
|
285
285
|
}
|
|
286
|
-
.gt-env-divider[data-v-
|
|
286
|
+
.gt-env-divider[data-v-71bbf3ca] {
|
|
287
287
|
height: 1px;
|
|
288
288
|
background: rgba(255, 255, 255, 0.1);
|
|
289
289
|
margin: 4px 0;
|
package/dist/index.js
CHANGED
|
@@ -94,7 +94,6 @@ function usePlayer(props, emit) {
|
|
|
94
94
|
const callbacks = {
|
|
95
95
|
onStateChange: (partial) => {
|
|
96
96
|
Object.assign(state, partial);
|
|
97
|
-
emit("state-change", partial);
|
|
98
97
|
if (partial.isPlaying === true) {
|
|
99
98
|
emit("play");
|
|
100
99
|
} else if (partial.isPlaying === false && state.isPlaying) {
|
|
@@ -233,8 +232,8 @@ function usePlayer(props, emit) {
|
|
|
233
232
|
destroy
|
|
234
233
|
};
|
|
235
234
|
}
|
|
236
|
-
let hideControlsTimer = null;
|
|
237
235
|
function useControls(params) {
|
|
236
|
+
let hideControlsTimer = null;
|
|
238
237
|
const {
|
|
239
238
|
isPlaying,
|
|
240
239
|
isLoaded,
|
|
@@ -405,7 +404,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
405
404
|
showEnvPanel: { type: Boolean },
|
|
406
405
|
showControls: { type: Boolean }
|
|
407
406
|
}, DEFAULT_EC_PLAYER_PROPS),
|
|
408
|
-
emits: ["play", "pause", "loaded", "error", "
|
|
407
|
+
emits: ["play", "pause", "loaded", "error", "format-detected"],
|
|
409
408
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
410
409
|
const props = __props;
|
|
411
410
|
const emit = __emit;
|
|
@@ -652,7 +651,7 @@ const _export_sfc = (sfc, props) => {
|
|
|
652
651
|
}
|
|
653
652
|
return target;
|
|
654
653
|
};
|
|
655
|
-
const EcPlayer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
654
|
+
const EcPlayer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-71bbf3ca"]]);
|
|
656
655
|
export {
|
|
657
656
|
DEFAULT_EC_PLAYER_PROPS,
|
|
658
657
|
DEFAULT_PLAYER_OPTIONS,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/composables/usePlayer.ts","../src/composables/useControls.ts","../src/composables/useEnvInfo.ts","../src/components/EcPlayer.vue"],"sourcesContent":["/**\n * Vue 组件类型定义\n */\n\nimport type { EcPlayerCoreConfig, EcPlayerState, EcEnvInfo } from '@give-tech/ec-player'\nexport { LogLevel } from '@give-tech/ec-player'\n\n/**\n * WASM 路径配置\n */\nexport interface WasmPathConfig {\n /**\n * SIMD 版本 WASM 路径(推荐,性能更好)\n * 用于支持 SIMD 的现代浏览器\n */\n simd?: string\n /**\n * 非 SIMD 版本 WASM 路径\n * 用于不支持 SIMD 的旧浏览器作为降级方案\n */\n nonSimd?: string\n}\n\n/**\n * 全局配置\n *\n * 必须在使用 EcPlayer 组件前调用\n *\n * @example\n * ```typescript\n * // main.ts\n * import { configureEcPlayer } from '@give-tech/ec-player-vue'\n *\n * // 配置 SIMD 和非 SIMD 路径,支持自动降级\n * configureEcPlayer({\n * wasm: {\n * simd: '/wasm/decoder-simd.js',\n * nonSimd: '/wasm/decoder.js'\n * }\n * })\n *\n * // 使用 CDN\n * configureEcPlayer({\n * wasm: {\n * simd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder-simd.js',\n * nonSimd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder.js'\n * }\n * })\n * ```\n */\nexport interface EcPlayerGlobalConfig {\n /**\n * WASM 路径配置(必填)\n * 支持 SIMD 和非 SIMD 自动降级\n */\n wasm?: WasmPathConfig\n /** 默认是否显示控制条 */\n showControls?: boolean\n /** 默认缓冲目标帧数 */\n targetBufferSize?: number\n /** 默认每批解码帧数 */\n decodeBatchSize?: number\n /** 默认队列上限 */\n maxQueueSize?: number\n}\n\n/**\n * 播放器配置选项\n */\nexport interface PlayerOptions {\n /** 帧缓冲区目标大小 */\n targetBufferSize?: number\n /** 每批解码帧数 */\n decodeBatchSize?: number\n /** NAL/Sample 队列上限 */\n maxQueueSize?: number\n}\n\n/**\n * EcPlayer 组件 Props\n */\nexport interface EcPlayerProps {\n /** 是否显示环境信息面板 */\n showEnvPanel?: boolean\n /** 是否显示控制条 */\n showControls?: boolean\n}\n\n/**\n * EcPlayer 组件 Emits\n */\nexport interface EcPlayerEmits {\n /** 播放状态变化 - 开始播放时触发 */\n (e: 'play'): void\n /** 播放状态变化 - 暂停时触发 */\n (e: 'pause'): void\n /** 加载完成时触发 */\n (e: 'loaded'): void\n /** 错误时触发 */\n (e: 'error', error: Error): void\n /** 状态更新时触发 */\n (e: 'state-change', state: Partial<EcPlayerState>): void\n /** 格式检测完成时触发 */\n (e: 'format-detected', format: string): void\n}\n\n/**\n * EcPlayer 组件 Expose 方法\n */\nexport interface EcPlayerExpose {\n /**\n * 播放视频\n * @param options 播放选项\n * @param options.url 视频 URL\n * @param options.isLive 是否为直播流\n */\n play: (options: { url: string; isLive?: boolean }) => Promise<void>\n /**\n * 设置播放器配置\n * @param options 配置选项\n */\n setOptions: (options: PlayerOptions) => void\n /**\n * 设置日志级别\n * @param level 日志级别\n */\n setLogLevel: (level: number) => void\n /** 暂停 */\n pause: () => void\n /** 跳转到指定时间(毫秒) */\n seek: (time: number) => Promise<void>\n /** 获取播放器实例 */\n getPlayer: () => unknown\n /** 获取当前状态 */\n getState: () => EcPlayerState\n /** 获取当前播放时间(毫秒) */\n getCurrentTime: () => number\n /** 获取总时长(毫秒) */\n getDuration: () => number\n}\n\n/**\n * 环境信息面板数据\n */\nexport interface EnvPanelData {\n envInfo: EcEnvInfo | null\n state: Partial<EcPlayerState>\n}\n\n/**\n * 播放器配置(从 Props 转换)\n */\nexport interface PlayerConfigFromProps extends EcPlayerCoreConfig {\n wasmPath: string\n targetBufferSize: number\n decodeBatchSize: number\n maxQueueSize: number\n}\n\n/**\n * 默认 Props 值\n */\nexport const DEFAULT_EC_PLAYER_PROPS: Required<EcPlayerProps> = {\n showEnvPanel: false,\n showControls: true\n}\n\n/**\n * 默认播放器配置\n */\nexport const DEFAULT_PLAYER_OPTIONS: Required<PlayerOptions> = {\n targetBufferSize: 60,\n decodeBatchSize: 2,\n maxQueueSize: 200\n}\n\n/**\n * 默认 WASM 配置\n */\nexport const DEFAULT_WASM_CONFIG: WasmPathConfig = {\n simd: '/wasm/decoder-simd.js',\n nonSimd: '/wasm/decoder.js'\n}\n\n/**\n * 全局配置存储\n */\nlet globalConfig: EcPlayerGlobalConfig = {}\n\n/**\n * 配置 EcPlayer 全局默认值\n *\n * @example\n * ```typescript\n * // main.ts\n * import { configureEcPlayer } from '@give-tech/ec-player-vue'\n *\n * // 配置 SIMD 和非 SIMD 路径,支持自动降级\n * configureEcPlayer({\n * wasm: {\n * simd: '/wasm/decoder-simd.js',\n * nonSimd: '/wasm/decoder.js'\n * }\n * })\n *\n * // 使用 CDN\n * configureEcPlayer({\n * wasm: {\n * simd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder-simd.js',\n * nonSimd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder.js'\n * }\n * })\n * ```\n */\nexport function configureEcPlayer(config: EcPlayerGlobalConfig): void {\n globalConfig = { ...globalConfig, ...config }\n}\n\n/**\n * 获取全局配置\n */\nexport function getGlobalConfig(): EcPlayerGlobalConfig {\n return { ...globalConfig }\n}\n\n/**\n * 获取 WASM 路径配置\n */\nexport function getWasmConfig(): WasmPathConfig {\n return {\n simd: globalConfig.wasm?.simd ?? DEFAULT_WASM_CONFIG.simd,\n nonSimd: globalConfig.wasm?.nonSimd ?? DEFAULT_WASM_CONFIG.nonSimd\n }\n}\n\n/**\n * 获取合并后的配置(props > 全局配置 > 默认值)\n */\nexport function getMergedConfig(props: EcPlayerProps): Required<EcPlayerProps> {\n return {\n showEnvPanel: props.showEnvPanel ?? DEFAULT_EC_PLAYER_PROPS.showEnvPanel,\n showControls: props.showControls ?? globalConfig.showControls ?? DEFAULT_EC_PLAYER_PROPS.showControls\n }\n}\n\n/**\n * 获取合并后的播放器配置(options > 全局配置 > 默认值)\n */\nexport function getMergedPlayerOptions(options: PlayerOptions): Required<PlayerOptions> {\n return {\n targetBufferSize: options.targetBufferSize ?? globalConfig.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,\n decodeBatchSize: options.decodeBatchSize ?? globalConfig.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,\n maxQueueSize: options.maxQueueSize ?? globalConfig.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize\n }\n}\n\n/**\n * 根据环境能力选择合适的 WASM 路径\n *\n * @param hasSimdSupport 是否支持 SIMD\n * @returns 实际使用的 WASM 路径\n */\nexport function resolveWasmPath(hasSimdSupport: boolean): string {\n const wasmConfig = getWasmConfig()\n\n // 根据 SIMD 支持情况选择\n if (hasSimdSupport && wasmConfig.simd) {\n console.log('[EcPlayer] Using SIMD WASM:', wasmConfig.simd)\n return wasmConfig.simd\n }\n\n if (wasmConfig.nonSimd) {\n console.log('[EcPlayer] SIMD not supported, using non-SIMD WASM:', wasmConfig.nonSimd)\n return wasmConfig.nonSimd\n }\n\n // 降级到 SIMD 版本(兜底)\n console.log('[EcPlayer] No non-SIMD path configured, falling back to SIMD:', wasmConfig.simd)\n return wasmConfig.simd!\n}\n","/**\n * 播放器核心逻辑\n */\n\nimport { ref, shallowRef, reactive, onUnmounted, type Ref } from 'vue'\nimport {\n EcPlayerCore,\n EnvDetector,\n setLogLevel as coreSetLogLevel,\n type EcPlayerCoreConfig,\n type EcPlayerState,\n type EcPlayerCallbacks\n} from '@give-tech/ec-player'\nimport type { EcPlayerProps, PlayerOptions } from '../types'\nimport { resolveWasmPath, DEFAULT_PLAYER_OPTIONS, getGlobalConfig } from '../types'\n\n/**\n * 播放器逻辑返回值\n */\nexport interface UsePlayerReturn {\n /** Canvas 元素引用 */\n canvasRef: Ref<HTMLCanvasElement | null>\n /** 播放器实例 */\n player: Ref<EcPlayerCore | null>\n /** 响应式状态 */\n state: EcPlayerState\n /** 是否正在加载 */\n isLoading: Ref<boolean>\n /** 检测到的格式 */\n detectedFormat: Ref<string>\n /** 是否为直播流 */\n isLive: Ref<boolean>\n /** 播放 */\n play: (options: { url: string; isLive?: boolean }) => Promise<void>\n /** 设置配置 */\n setOptions: (options: PlayerOptions) => void\n /** 设置日志级别 */\n setLogLevel: (level: number) => void\n /** 暂停 */\n pause: () => void\n /** 恢复播放 */\n resume: () => Promise<void>\n /** 跳转 */\n seek: (time: number) => Promise<void>\n /** 获取播放器实例 */\n getPlayer: () => EcPlayerCore | null\n /** 获取状态 */\n getState: () => EcPlayerState\n /** 获取当前时间 */\n getCurrentTime: () => number\n /** 获取总时长 */\n getDuration: () => number\n /** 销毁播放器 */\n destroy: () => void\n}\n\n/**\n * 从配置选项创建播放器配置\n */\nfunction createConfig(options: Required<PlayerOptions>): Omit<EcPlayerCoreConfig, 'isLive'> {\n // 检测 SIMD 支持\n const envInfo = EnvDetector.detect()\n const wasmPath = resolveWasmPath(envInfo.capabilities.wasmSimd)\n\n return {\n wasmPath,\n targetBufferSize: options.targetBufferSize,\n decodeBatchSize: options.decodeBatchSize,\n maxQueueSize: options.maxQueueSize\n }\n}\n\n/**\n * 播放器逻辑 Hook\n */\nexport function usePlayer(\n props: EcPlayerProps,\n emit: {\n (e: 'play'): void\n (e: 'pause'): void\n (e: 'loaded'): void\n (e: 'error', error: Error): void\n (e: 'state-change', state: Partial<EcPlayerState>): void\n (e: 'format-detected', format: string): void\n }\n): UsePlayerReturn {\n const canvasRef = ref<HTMLCanvasElement | null>(null)\n const player = shallowRef<EcPlayerCore | null>(null)\n const isLoading = ref(false)\n const detectedFormat = ref('')\n const isLive = ref(false) // 跟踪当前是否为直播流\n\n // 当前播放器配置(初始化时合并全局配置和默认值)\n const globalConfig = getGlobalConfig()\n const currentOptions = reactive<Required<PlayerOptions>>({\n targetBufferSize: globalConfig.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,\n decodeBatchSize: globalConfig.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,\n maxQueueSize: globalConfig.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize\n })\n\n // 响应式状态\n const state = reactive<EcPlayerState>({\n isPlaying: false,\n isLoaded: false,\n isLoading: false,\n fps: 0,\n resolution: '-',\n decoded: 0,\n downloaded: 0,\n droppedFrames: 0,\n isPrefetching: false,\n segmentIndex: 0,\n totalSegments: 0,\n downloadSpeed: 0,\n currentTime: 0,\n duration: 0\n })\n\n // 创建回调\n const callbacks: EcPlayerCallbacks = {\n onStateChange: (partial) => {\n Object.assign(state, partial)\n emit('state-change', partial)\n\n // 派发 play/pause 事件\n if (partial.isPlaying === true) {\n emit('play')\n } else if (partial.isPlaying === false && state.isPlaying) {\n emit('pause')\n }\n },\n onError: (error) => {\n console.error('[EcPlayer] Error:', error)\n emit('error', error)\n }\n }\n\n // 播放(加载并播放)\n async function play(options: { url: string; isLive?: boolean }): Promise<void> {\n const { url, isLive: isLiveParam = false } = options\n if (!url) {\n emit('error', new Error('URL is required'))\n return\n }\n\n if (isLoading.value) {\n console.log('[EcPlayer] Already loading, skipping...')\n return\n }\n\n // 等待 canvas 准备好\n let retries = 10\n while (!canvasRef.value && retries > 0) {\n await new Promise(resolve => setTimeout(resolve, 100))\n retries--\n }\n\n if (!canvasRef.value) {\n const error = new Error('Canvas element not found')\n emit('error', error)\n return\n }\n\n isLoading.value = true\n isLive.value = isLiveParam\n\n try {\n // 销毁旧播放器\n if (player.value) {\n player.value.destroy()\n player.value = null\n }\n\n // 重置状态\n state.isPlaying = false\n state.isLoaded = false\n state.fps = 0\n state.resolution = '-'\n state.decoded = 0\n state.downloaded = 0\n state.droppedFrames = 0\n state.segmentIndex = 0\n state.totalSegments = 0\n state.downloadSpeed = 0\n state.currentTime = 0\n state.duration = 0\n detectedFormat.value = ''\n\n // 创建配置\n const config: EcPlayerCoreConfig & { canvas: HTMLCanvasElement } = {\n ...createConfig(currentOptions),\n canvas: canvasRef.value,\n isLive: isLiveParam\n }\n\n // 创建播放器\n player.value = new EcPlayerCore(config, callbacks)\n\n // 加载视频\n await player.value.load(url, isLiveParam)\n\n // 获取检测到的格式\n detectedFormat.value = player.value.getDetectedFormat()\n emit('format-detected', detectedFormat.value)\n\n // 标记加载完成\n state.isLoaded = true\n emit('loaded')\n\n // 开始播放\n await player.value.play()\n\n console.log('[EcPlayer] Playing stream, format:', detectedFormat.value)\n } catch (error: any) {\n console.error('[EcPlayer] Failed to play:', error?.message || error)\n emit('error', error)\n } finally {\n isLoading.value = false\n }\n }\n\n // 设置配置\n function setOptions(options: PlayerOptions): void {\n if (options.targetBufferSize !== undefined) {\n currentOptions.targetBufferSize = options.targetBufferSize\n }\n if (options.decodeBatchSize !== undefined) {\n currentOptions.decodeBatchSize = options.decodeBatchSize\n }\n if (options.maxQueueSize !== undefined) {\n currentOptions.maxQueueSize = options.maxQueueSize\n }\n console.log('[EcPlayer] Options updated:', currentOptions)\n }\n\n // 设置日志级别\n function setLogLevel(level: number): void {\n coreSetLogLevel(level)\n }\n\n // 暂停\n function pause(): void {\n player.value?.pause()\n }\n\n // 恢复播放\n async function resume(): Promise<void> {\n if (!player.value) return\n await player.value.play()\n }\n\n // 跳转\n async function seek(time: number): Promise<void> {\n if (!player.value) return\n await player.value.seek(time)\n }\n\n // 获取播放器实例\n function getPlayer(): EcPlayerCore | null {\n return player.value\n }\n\n // 获取状态\n function getState(): EcPlayerState {\n return player.value?.getState() ?? { ...state }\n }\n\n // 获取当前时间\n function getCurrentTime(): number {\n return player.value?.getCurrentTime() ?? 0\n }\n\n // 获取总时长\n function getDuration(): number {\n return player.value?.getDuration() ?? 0\n }\n\n // 销毁播放器\n function destroy(): void {\n if (player.value) {\n player.value.destroy()\n player.value = null\n }\n }\n\n // 组件卸载时销毁\n onUnmounted(() => {\n destroy()\n })\n\n return {\n canvasRef,\n player,\n state,\n isLoading,\n detectedFormat,\n isLive,\n play,\n setOptions,\n setLogLevel,\n pause,\n resume,\n seek,\n getPlayer,\n getState,\n getCurrentTime,\n getDuration,\n destroy\n }\n}\n","/**\n * 播放器控制条逻辑\n */\n\nimport { ref, computed, type Ref } from 'vue'\n\n/**\n * 控制条逻辑参数\n */\nexport interface UseControlsParams {\n /** 是否正在播放 */\n isPlaying: Ref<boolean>\n /** 是否已加载 */\n isLoaded: Ref<boolean>\n /** 当前时间(毫秒) */\n currentTime: Ref<number>\n /** 总时长(毫秒) */\n duration: Ref<number>\n /** 分片索引 */\n segmentIndex: Ref<number>\n /** 总分片数 */\n totalSegments: Ref<number>\n /** 是否为直播流 */\n isLive: Ref<boolean>\n /** 跳转方法 */\n seek: (time: number) => Promise<void>\n}\n\n/**\n * 控制条逻辑返回值\n */\nexport interface UseControlsReturn {\n /** 是否显示控制条 */\n showControls: Ref<boolean>\n /** 进度条 hover 时间 */\n hoverTime: Ref<number | null>\n /** 进度条 hover 位置 */\n hoverPosition: Ref<number>\n /** 播放进度百分比 */\n playProgress: Ref<number>\n /** 缓冲进度百分比 */\n bufferProgress: Ref<number>\n /** 显示控制条 */\n showControlsBar: () => void\n /** 隐藏控制条 */\n hideControlsBar: () => void\n /** 处理进度条点击 */\n handleProgressClick: (event: MouseEvent) => Promise<void>\n /** 处理进度条悬停 */\n handleProgressHover: (event: MouseEvent) => void\n /** 格式化时间 */\n formatTime: (ms: number) => string\n}\n\nlet hideControlsTimer: number | null = null\n\n/**\n * 控制条逻辑 Hook\n */\nexport function useControls(params: UseControlsParams): UseControlsReturn {\n const {\n isPlaying,\n isLoaded,\n currentTime,\n duration,\n segmentIndex,\n totalSegments,\n isLive,\n seek\n } = params\n\n const showControls = ref(true)\n const hoverTime = ref<number | null>(null)\n const hoverPosition = ref(0)\n\n // 计算播放进度\n const playProgress = computed(() => {\n if (duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n })\n\n // 计算缓冲进度\n const bufferProgress = computed(() => {\n if (totalSegments.value === 0) return 0\n return (segmentIndex.value / totalSegments.value) * 100\n })\n\n // 显示控制条\n function showControlsBar(): void {\n showControls.value = true\n if (hideControlsTimer) {\n clearTimeout(hideControlsTimer)\n }\n hideControlsTimer = window.setTimeout(() => {\n if (isPlaying.value) {\n showControls.value = false\n }\n }, 3000)\n }\n\n // 隐藏控制条\n function hideControlsBar(): void {\n if (isPlaying.value) {\n showControls.value = false\n }\n }\n\n // 处理进度条点击\n async function handleProgressClick(event: MouseEvent): Promise<void> {\n if (duration.value === 0) return\n\n const target = event.currentTarget as HTMLElement\n const rect = target.getBoundingClientRect()\n const clickX = event.clientX - rect.left\n const percentage = clickX / rect.width\n const targetTime = percentage * duration.value\n\n await seek(targetTime)\n }\n\n // 处理进度条悬停\n function handleProgressHover(event: MouseEvent): void {\n if (duration.value === 0) return\n\n const target = event.currentTarget as HTMLElement\n const rect = target.getBoundingClientRect()\n const hoverX = event.clientX - rect.left\n const percentage = Math.max(0, Math.min(1, hoverX / rect.width))\n\n hoverTime.value = percentage * duration.value\n hoverPosition.value = percentage * 100\n }\n\n // 格式化时间\n function formatTime(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000)\n const hours = Math.floor(totalSeconds / 3600)\n const minutes = Math.floor((totalSeconds % 3600) / 60)\n const seconds = totalSeconds % 60\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`\n }\n return `${minutes}:${seconds.toString().padStart(2, '0')}`\n }\n\n return {\n showControls,\n hoverTime,\n hoverPosition,\n playProgress,\n bufferProgress,\n showControlsBar,\n hideControlsBar,\n handleProgressClick,\n handleProgressHover,\n formatTime\n }\n}\n","/**\n * 环境信息逻辑\n */\n\nimport { ref, computed, onMounted, type Ref } from 'vue'\nimport { EnvDetector, type EcEnvInfo } from '@give-tech/ec-player'\n\n/**\n * 环境信息逻辑返回值\n */\nexport interface UseEnvInfoReturn {\n /** 环境信息 */\n envInfo: Ref<EcEnvInfo | null>\n /** 是否显示环境面板 */\n showEnvPanel: Ref<boolean>\n /** 环境类型文本 */\n envTypeText: Ref<string>\n /** 切换环境面板显示 */\n toggleEnvPanel: () => void\n /** 检测环境 */\n detectEnv: () => void\n}\n\n/**\n * 环境信息逻辑 Hook\n */\nexport function useEnvInfo(\n initialShowPanel: boolean = false\n): UseEnvInfoReturn {\n const envInfo = ref<EcEnvInfo | null>(null)\n const showEnvPanel = ref(initialShowPanel)\n\n // 环境类型文本\n const envTypeText = computed(() => {\n if (!envInfo.value) return '未知'\n const typeMap: Record<string, string> = {\n 'pc-browser': 'PC 浏览器',\n 'mobile-browser': '移动端浏览器',\n 'wechat-miniprogram': '微信小程序',\n 'alipay-miniprogram': '支付宝小程序',\n 'other-miniprogram': '其他小程序',\n 'unknown': '未知',\n }\n return typeMap[envInfo.value.platform] || envInfo.value.platform\n })\n\n // 切换环境面板显示\n function toggleEnvPanel(): void {\n showEnvPanel.value = !showEnvPanel.value\n }\n\n // 检测环境\n function detectEnv(): void {\n envInfo.value = EnvDetector.detect()\n console.log('[EcPlayer] 环境检测结果:', envInfo.value)\n }\n\n // 组件挂载时检测环境\n onMounted(() => {\n detectEnv()\n })\n\n return {\n envInfo,\n showEnvPanel,\n envTypeText,\n toggleEnvPanel,\n detectEnv\n }\n}\n","<template>\n <div class=\"gt-player-container\">\n <div\n class=\"gt-video-wrapper\"\n ref=\"videoWrapperRef\"\n @mouseenter=\"controls.showControlsBar\"\n @mousemove=\"controls.showControlsBar\"\n @mouseleave=\"controls.hideControlsBar\"\n >\n <canvas ref=\"canvasRef\" class=\"gt-player-canvas\"></canvas>\n\n <!-- 环境信息面板 -->\n <div v-if=\"showEnvPanel && envInfo\" class=\"gt-env-panel\">\n <div class=\"gt-env-row\">\n <span>platform</span>\n <span :class=\"envInfo.isMiniProgram ? 'warn' : ''\">{{ envTypeText }}</span>\n </div>\n <div class=\"gt-env-divider\"></div>\n <div class=\"gt-env-row\">\n <span>SIMD</span>\n <span :class=\"envInfo.capabilities.wasmSimd ? 'ok' : 'err'\">\n {{ envInfo.capabilities.wasmSimd ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebGL</span>\n <span :class=\"envInfo.capabilities.webGL ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webGL ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebGL2</span>\n <span :class=\"envInfo.capabilities.webGL2 ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webGL2 ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>SAB</span>\n <span :class=\"envInfo.capabilities.sharedArrayBuffer ? 'ok' : 'err'\">\n {{ envInfo.capabilities.sharedArrayBuffer ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>Threads</span>\n <span :class=\"envInfo.capabilities.wasmThreads ? 'ok' : 'err'\">\n {{ envInfo.capabilities.wasmThreads ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebAudio</span>\n <span :class=\"envInfo.capabilities.webAudio ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webAudio ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>Stream</span>\n <span :class=\"envInfo.capabilities.readableStream ? 'ok' : 'err'\">\n {{ envInfo.capabilities.readableStream ? 'Yes' : 'No' }}\n </span>\n </div>\n <template v-if=\"player.state.isLoaded\">\n <div class=\"gt-env-divider\"></div>\n <div class=\"gt-env-row\"><span>FPS</span><span>{{ player.state.fps }}</span></div>\n <div class=\"gt-env-row\"><span>Resolution</span><span>{{ player.state.resolution }}</span></div>\n <div class=\"gt-env-row\"><span>downloaded</span><span>{{ player.state.downloaded }}</span></div>\n <div class=\"gt-env-row\"><span>decoded</span><span>{{ player.state.decoded }}</span></div>\n <div class=\"gt-env-row\"><span>Dropped</span><span>{{ player.state.droppedFrames }}</span></div>\n <div class=\"gt-env-row\"><span>Speed</span><span>{{ player.state.downloadSpeed || 0 }} KB/s</span></div>\n </template>\n </div>\n\n <!-- 加载中动画 -->\n <div class=\"gt-loading-spinner\" v-if=\"player.isLoading.value\">\n <div class=\"gt-spinner\"></div>\n </div>\n\n <!-- 视频控制条 -->\n <div\n v-if=\"showControlsProp\"\n class=\"gt-video-controls\"\n :class=\"{ visible: controls.showControls.value || !player.state.isPlaying }\"\n >\n <button class=\"gt-control-btn\" @click=\"togglePlayback\">\n <svg v-if=\"player.state.isPlaying\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/>\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/>\n </svg>\n <svg v-else viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n </button>\n\n <!-- 直播标识 -->\n <span class=\"gt-live-indicator\" v-if=\"isLive\">\n <span class=\"gt-live-dot\"></span>\n <span class=\"gt-live-text\">实时</span>\n </span>\n\n <!-- 点播时间显示 -->\n <span class=\"gt-time-display\" v-else>\n <span class=\"gt-time-current\">{{ controls.formatTime(player.state.currentTime) }}</span>\n <span class=\"gt-time-separator\">/</span>\n <span class=\"gt-time-duration\">{{ controls.formatTime(player.state.duration) }}</span>\n </span>\n\n <!-- 进度条 (仅点播) -->\n <div\n v-if=\"!isLive\"\n class=\"gt-progress-container\"\n @click=\"controls.handleProgressClick\"\n @mousemove=\"controls.handleProgressHover\"\n @mouseleave=\"controls.hoverTime.value = null\"\n >\n <div class=\"gt-progress-bar\">\n <div class=\"gt-progress-buffered\" :style=\"{ width: controls.bufferProgress.value + '%' }\"></div>\n <div class=\"gt-progress-played\" :style=\"{ width: controls.playProgress.value + '%' }\">\n <div class=\"gt-progress-handle\"></div>\n </div>\n </div>\n <div\n class=\"gt-progress-tooltip\"\n v-if=\"controls.hoverTime.value !== null\"\n :style=\"{ left: controls.hoverPosition.value + '%' }\"\n >\n {{ controls.formatTime(controls.hoverTime.value) }}\n </div>\n </div>\n\n <!-- 直播流占位符 -->\n <div class=\"gt-flex-spacer\" v-else></div>\n\n <!-- 格式标识 -->\n <span class=\"gt-info-badge\" v-if=\"player.detectedFormat.value\">{{ player.detectedFormat.value }}</span>\n\n <!-- 环境信息按钮 -->\n <button class=\"gt-control-btn gt-env-info-btn\" @click=\"toggleEnvPanel\" :title=\"showEnvPanel ? '隐藏信息' : '显示信息'\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <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\"/>\n </svg>\n </button>\n </div>\n\n <!-- 大播放按钮(居中) -->\n <div\n class=\"gt-center-play-btn\"\n v-if=\"player.state.isLoaded && !player.state.isPlaying\"\n @click=\"togglePlayback\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { usePlayer } from '../composables/usePlayer'\nimport { useControls } from '../composables/useControls'\nimport { useEnvInfo } from '../composables/useEnvInfo'\nimport type { EcPlayerProps, EcPlayerExpose } from '../types'\nimport { DEFAULT_EC_PLAYER_PROPS } from '../types'\n\n// Props\nconst props = withDefaults(defineProps<EcPlayerProps>(), DEFAULT_EC_PLAYER_PROPS)\n\n// Emits\nconst emit = defineEmits<{\n (e: 'play'): void\n (e: 'pause'): void\n (e: 'loaded'): void\n (e: 'error', error: Error): void\n (e: 'state-change', state: Partial<{ isPlaying: boolean; isLoaded: boolean; isLoading: boolean; fps: number; resolution: string; decoded: number; downloaded: number; droppedFrames: number; isPrefetching: boolean; segmentIndex: number; totalSegments: number; downloadSpeed: number; currentTime: number; duration: number }>): void\n (e: 'format-detected', format: string): void\n}>()\n\n// Canvas ref(本地)\nconst canvasRef = ref<HTMLCanvasElement | null>(null)\n\n// 环境信息逻辑\nconst { envInfo, showEnvPanel, envTypeText, toggleEnvPanel } = useEnvInfo(props.showEnvPanel)\n\n// 播放器逻辑\nconst player = usePlayer(props, emit)\n\n// 同步 canvas ref 到 player\nwatch(canvasRef, (el) => {\n player.canvasRef.value = el\n}, { immediate: true })\n\n// isLive 计算属性(用于模板)\nconst isLive = computed(() => player.isLive.value)\n\n// 控制条逻辑\nconst isPlayingRef = computed(() => player.state.isPlaying)\nconst isLoadedRef = computed(() => player.state.isLoaded)\nconst currentTimeRef = computed(() => player.state.currentTime)\nconst durationRef = computed(() => player.state.duration)\nconst segmentIndexRef = computed(() => player.state.segmentIndex)\nconst totalSegmentsRef = computed(() => player.state.totalSegments)\n\nconst controls = useControls({\n isPlaying: isPlayingRef,\n isLoaded: isLoadedRef,\n currentTime: currentTimeRef,\n duration: durationRef,\n segmentIndex: segmentIndexRef,\n totalSegments: totalSegmentsRef,\n isLive,\n seek: player.seek\n})\n\n// 视频包装器引用\nconst videoWrapperRef = ref<HTMLElement | null>(null)\n\n// 显示控制条属性(用于条件渲染)\nconst showControlsProp = computed(() => props.showControls)\n\n// 切换播放/暂停\nfunction togglePlayback(): void {\n if (player.state.isPlaying) {\n player.pause()\n } else {\n player.resume()\n }\n}\n\n// Expose 方法\ndefineExpose<EcPlayerExpose>({\n play: player.play,\n setOptions: player.setOptions,\n setLogLevel: player.setLogLevel,\n pause: player.pause,\n seek: player.seek,\n getPlayer: player.getPlayer,\n getState: player.getState,\n getCurrentTime: player.getCurrentTime,\n getDuration: player.getDuration\n})\n</script>\n\n<style scoped>\n.gt-player-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.gt-video-wrapper {\n position: relative;\n background: #000;\n border-radius: 4px;\n overflow: hidden;\n width: 100%;\n}\n\n.gt-player-canvas {\n width: 100%;\n height: auto;\n display: block;\n}\n\n/* 加载中动画 */\n.gt-loading-spinner {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10;\n}\n\n.gt-spinner {\n width: 8vmin;\n height: 8vmin;\n border: 0.5vmin solid rgba(255, 255, 255, 0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: gt-spin 1s linear infinite;\n}\n\n@keyframes gt-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* 视频控制条 */\n.gt-video-controls {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 10px 16px;\n background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));\n opacity: 0;\n transition: opacity 0.3s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.gt-flex-spacer {\n flex: 1;\n}\n\n.gt-video-controls.visible {\n opacity: 1;\n}\n\n.gt-control-btn {\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.gt-control-btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.gt-control-btn svg {\n width: 14px;\n height: 14px;\n}\n\n.gt-progress-container {\n flex: 1;\n position: relative;\n cursor: pointer;\n height: 20px;\n display: flex;\n align-items: center;\n}\n\n.gt-progress-bar {\n width: 100%;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n transition: height 0.2s ease;\n}\n\n.gt-progress-container:hover .gt-progress-bar {\n height: 6px;\n}\n\n.gt-progress-buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.4);\n border-radius: 2px;\n transition: width 0.1s;\n}\n\n.gt-progress-played {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: #ff2d55;\n border-radius: 2px;\n transition: width 0.1s;\n}\n\n.gt-progress-handle {\n position: absolute;\n right: -6px;\n top: 50%;\n transform: translateY(-50%);\n width: 14px;\n height: 14px;\n background: #ff2d55;\n border-radius: 50%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n opacity: 0;\n transition: opacity 0.2s, transform 0.2s;\n}\n\n.gt-progress-container:hover .gt-progress-handle {\n opacity: 1;\n transform: translateY(-50%) scale(1.2);\n}\n\n.gt-progress-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.85);\n color: white;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 11px;\n white-space: nowrap;\n pointer-events: none;\n}\n\n.gt-time-display {\n color: white;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.gt-time-separator {\n margin: 0 4px;\n opacity: 0.6;\n}\n\n.gt-info-badge {\n background: rgba(255, 255, 255, 0.2);\n color: white;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* 直播指示器 */\n.gt-live-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n color: white;\n font-size: 12px;\n font-weight: 500;\n}\n\n.gt-live-dot {\n width: 8px;\n height: 8px;\n background: #ff2d55;\n border-radius: 50%;\n animation: gt-live-pulse 1.5s ease-in-out infinite;\n}\n\n.gt-live-text {\n color: #ff2d55;\n}\n\n@keyframes gt-live-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.4;\n }\n}\n\n/* 居中播放按钮 */\n.gt-center-play-btn {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 56px;\n height: 56px;\n background: rgba(0, 0, 0, 0.5);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.gt-center-play-btn:hover {\n background: rgba(0, 0, 0, 0.7);\n transform: translate(-50%, -50%) scale(1.05);\n}\n\n.gt-center-play-btn svg {\n width: 24px;\n height: 24px;\n color: white;\n margin-left: 3px;\n}\n\n/* 环境信息面板 */\n.gt-env-panel {\n position: absolute;\n top: 12px;\n left: 12px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 6px;\n padding: 8px 10px;\n font-size: 11px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n min-width: 160px;\n max-width: 200px;\n max-height: calc(100% - 24px);\n overflow-y: auto;\n backdrop-filter: blur(10px);\n animation: gt-env-fade-in 0.15s ease;\n z-index: 15;\n}\n\n.gt-env-panel::-webkit-scrollbar {\n width: 4px;\n}\n\n.gt-env-panel::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.gt-env-panel::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n@keyframes gt-env-fade-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.gt-env-panel .gt-env-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 2px 0;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.gt-env-panel .gt-env-row span:first-child {\n color: rgba(255, 255, 255, 0.5);\n margin-right: 16px;\n}\n\n.gt-env-panel .gt-env-row span:last-child {\n font-variant-numeric: tabular-nums;\n}\n\n.gt-env-panel .gt-env-row .ok { color: #4caf50; }\n.gt-env-panel .gt-env-row .warn { color: #ff9800; }\n.gt-env-panel .gt-env-row .err { color: #f44336; }\n\n.gt-env-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.1);\n margin: 4px 0;\n}\n</style>\n"],"names":["globalConfig","setLogLevel","coreSetLogLevel","_openBlock","_createElementBlock","_createElementVNode","_unref","_normalizeClass","_Fragment","_toDisplayString","_normalizeStyle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/types.ts","../src/composables/usePlayer.ts","../src/composables/useControls.ts","../src/composables/useEnvInfo.ts","../src/components/EcPlayer.vue"],"sourcesContent":["/**\n * Vue 组件类型定义\n */\n\nimport type { EcPlayerCoreConfig, EcPlayerState, EcEnvInfo } from '@give-tech/ec-player'\nexport { LogLevel } from '@give-tech/ec-player'\n\n/**\n * WASM 路径配置\n */\nexport interface WasmPathConfig {\n /**\n * SIMD 版本 WASM 路径(推荐,性能更好)\n * 用于支持 SIMD 的现代浏览器\n */\n simd?: string\n /**\n * 非 SIMD 版本 WASM 路径\n * 用于不支持 SIMD 的旧浏览器作为降级方案\n */\n nonSimd?: string\n}\n\n/**\n * 全局配置\n *\n * 必须在使用 EcPlayer 组件前调用\n *\n * @example\n * ```typescript\n * // main.ts\n * import { configureEcPlayer } from '@give-tech/ec-player-vue'\n *\n * // 配置 SIMD 和非 SIMD 路径,支持自动降级\n * configureEcPlayer({\n * wasm: {\n * simd: '/wasm/decoder-simd.js',\n * nonSimd: '/wasm/decoder.js'\n * }\n * })\n *\n * // 使用 CDN\n * configureEcPlayer({\n * wasm: {\n * simd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder-simd.js',\n * nonSimd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder.js'\n * }\n * })\n * ```\n */\nexport interface EcPlayerGlobalConfig {\n /**\n * WASM 路径配置(必填)\n * 支持 SIMD 和非 SIMD 自动降级\n */\n wasm?: WasmPathConfig\n /** 默认是否显示控制条 */\n showControls?: boolean\n /** 默认缓冲目标帧数 */\n targetBufferSize?: number\n /** 默认每批解码帧数 */\n decodeBatchSize?: number\n /** 默认队列上限 */\n maxQueueSize?: number\n}\n\n/**\n * 播放器配置选项\n */\nexport interface PlayerOptions {\n /** 帧缓冲区目标大小 */\n targetBufferSize?: number\n /** 每批解码帧数 */\n decodeBatchSize?: number\n /** NAL/Sample 队列上限 */\n maxQueueSize?: number\n}\n\n/**\n * EcPlayer 组件 Props\n */\nexport interface EcPlayerProps {\n /** 是否显示环境信息面板 */\n showEnvPanel?: boolean\n /** 是否显示控制条 */\n showControls?: boolean\n}\n\n/**\n * EcPlayer 组件 Emits\n */\nexport interface EcPlayerEmits {\n /** 播放状态变化 - 开始播放时触发 */\n (e: 'play'): void\n /** 播放状态变化 - 暂停时触发 */\n (e: 'pause'): void\n /** 加载完成时触发 */\n (e: 'loaded'): void\n /** 错误时触发 */\n (e: 'error', error: Error): void\n /** 格式检测完成时触发 */\n (e: 'format-detected', format: string): void\n}\n\n/**\n * EcPlayer 组件 Expose 方法\n */\nexport interface EcPlayerExpose {\n /**\n * 播放视频\n * @param options 播放选项\n * @param options.url 视频 URL\n * @param options.isLive 是否为直播流\n */\n play: (options: { url: string; isLive?: boolean }) => Promise<void>\n /**\n * 设置播放器配置\n * @param options 配置选项\n */\n setOptions: (options: PlayerOptions) => void\n /**\n * 设置日志级别\n * @param level 日志级别\n */\n setLogLevel: (level: number) => void\n /** 暂停 */\n pause: () => void\n /** 跳转到指定时间(毫秒) */\n seek: (time: number) => Promise<void>\n /** 获取播放器实例 */\n getPlayer: () => unknown\n /** 获取当前状态 */\n getState: () => EcPlayerState\n /** 获取当前播放时间(毫秒) */\n getCurrentTime: () => number\n /** 获取总时长(毫秒) */\n getDuration: () => number\n}\n\n/**\n * 环境信息面板数据\n */\nexport interface EnvPanelData {\n envInfo: EcEnvInfo | null\n state: Partial<EcPlayerState>\n}\n\n/**\n * 播放器配置(从 Props 转换)\n */\nexport interface PlayerConfigFromProps extends EcPlayerCoreConfig {\n wasmPath: string\n targetBufferSize: number\n decodeBatchSize: number\n maxQueueSize: number\n}\n\n/**\n * 默认 Props 值\n */\nexport const DEFAULT_EC_PLAYER_PROPS: Required<EcPlayerProps> = {\n showEnvPanel: false,\n showControls: true\n}\n\n/**\n * 默认播放器配置\n */\nexport const DEFAULT_PLAYER_OPTIONS: Required<PlayerOptions> = {\n targetBufferSize: 60,\n decodeBatchSize: 2,\n maxQueueSize: 200\n}\n\n/**\n * 默认 WASM 配置\n */\nexport const DEFAULT_WASM_CONFIG: WasmPathConfig = {\n simd: '/wasm/decoder-simd.js',\n nonSimd: '/wasm/decoder.js'\n}\n\n/**\n * 全局配置存储\n */\nlet globalConfig: EcPlayerGlobalConfig = {}\n\n/**\n * 配置 EcPlayer 全局默认值\n *\n * @example\n * ```typescript\n * // main.ts\n * import { configureEcPlayer } from '@give-tech/ec-player-vue'\n *\n * // 配置 SIMD 和非 SIMD 路径,支持自动降级\n * configureEcPlayer({\n * wasm: {\n * simd: '/wasm/decoder-simd.js',\n * nonSimd: '/wasm/decoder.js'\n * }\n * })\n *\n * // 使用 CDN\n * configureEcPlayer({\n * wasm: {\n * simd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder-simd.js',\n * nonSimd: 'https://unpkg.com/@give-tech/ec-player@latest/wasm/decoder.js'\n * }\n * })\n * ```\n */\nexport function configureEcPlayer(config: EcPlayerGlobalConfig): void {\n globalConfig = { ...globalConfig, ...config }\n}\n\n/**\n * 获取全局配置\n */\nexport function getGlobalConfig(): EcPlayerGlobalConfig {\n return { ...globalConfig }\n}\n\n/**\n * 获取 WASM 路径配置\n */\nexport function getWasmConfig(): WasmPathConfig {\n return {\n simd: globalConfig.wasm?.simd ?? DEFAULT_WASM_CONFIG.simd,\n nonSimd: globalConfig.wasm?.nonSimd ?? DEFAULT_WASM_CONFIG.nonSimd\n }\n}\n\n/**\n * 获取合并后的配置(props > 全局配置 > 默认值)\n */\nexport function getMergedConfig(props: EcPlayerProps): Required<EcPlayerProps> {\n return {\n showEnvPanel: props.showEnvPanel ?? DEFAULT_EC_PLAYER_PROPS.showEnvPanel,\n showControls: props.showControls ?? globalConfig.showControls ?? DEFAULT_EC_PLAYER_PROPS.showControls\n }\n}\n\n/**\n * 获取合并后的播放器配置(options > 全局配置 > 默认值)\n */\nexport function getMergedPlayerOptions(options: PlayerOptions): Required<PlayerOptions> {\n return {\n targetBufferSize: options.targetBufferSize ?? globalConfig.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,\n decodeBatchSize: options.decodeBatchSize ?? globalConfig.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,\n maxQueueSize: options.maxQueueSize ?? globalConfig.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize\n }\n}\n\n/**\n * 根据环境能力选择合适的 WASM 路径\n *\n * @param hasSimdSupport 是否支持 SIMD\n * @returns 实际使用的 WASM 路径\n */\nexport function resolveWasmPath(hasSimdSupport: boolean): string {\n const wasmConfig = getWasmConfig()\n\n // 根据 SIMD 支持情况选择\n if (hasSimdSupport && wasmConfig.simd) {\n console.log('[EcPlayer] Using SIMD WASM:', wasmConfig.simd)\n return wasmConfig.simd\n }\n\n if (wasmConfig.nonSimd) {\n console.log('[EcPlayer] SIMD not supported, using non-SIMD WASM:', wasmConfig.nonSimd)\n return wasmConfig.nonSimd\n }\n\n // 降级到 SIMD 版本(兜底)\n console.log('[EcPlayer] No non-SIMD path configured, falling back to SIMD:', wasmConfig.simd)\n return wasmConfig.simd!\n}\n","/**\n * 播放器核心逻辑\n */\n\nimport { ref, shallowRef, reactive, onUnmounted, type Ref } from 'vue'\nimport {\n EcPlayerCore,\n EnvDetector,\n setLogLevel as coreSetLogLevel,\n type EcPlayerCoreConfig,\n type EcPlayerState,\n type EcPlayerCallbacks\n} from '@give-tech/ec-player'\nimport type { EcPlayerProps, PlayerOptions } from '../types'\nimport { resolveWasmPath, DEFAULT_PLAYER_OPTIONS, getGlobalConfig } from '../types'\n\n/**\n * 播放器逻辑返回值\n */\nexport interface UsePlayerReturn {\n /** Canvas 元素引用 */\n canvasRef: Ref<HTMLCanvasElement | null>\n /** 播放器实例 */\n player: Ref<EcPlayerCore | null>\n /** 响应式状态 */\n state: EcPlayerState\n /** 是否正在加载 */\n isLoading: Ref<boolean>\n /** 检测到的格式 */\n detectedFormat: Ref<string>\n /** 是否为直播流 */\n isLive: Ref<boolean>\n /** 播放 */\n play: (options: { url: string; isLive?: boolean }) => Promise<void>\n /** 设置配置 */\n setOptions: (options: PlayerOptions) => void\n /** 设置日志级别 */\n setLogLevel: (level: number) => void\n /** 暂停 */\n pause: () => void\n /** 恢复播放 */\n resume: () => Promise<void>\n /** 跳转 */\n seek: (time: number) => Promise<void>\n /** 获取播放器实例 */\n getPlayer: () => EcPlayerCore | null\n /** 获取状态 */\n getState: () => EcPlayerState\n /** 获取当前时间 */\n getCurrentTime: () => number\n /** 获取总时长 */\n getDuration: () => number\n /** 销毁播放器 */\n destroy: () => void\n}\n\n/**\n * 从配置选项创建播放器配置\n */\nfunction createConfig(options: Required<PlayerOptions>): Omit<EcPlayerCoreConfig, 'isLive'> {\n // 检测 SIMD 支持\n const envInfo = EnvDetector.detect()\n const wasmPath = resolveWasmPath(envInfo.capabilities.wasmSimd)\n\n return {\n wasmPath,\n targetBufferSize: options.targetBufferSize,\n decodeBatchSize: options.decodeBatchSize,\n maxQueueSize: options.maxQueueSize\n }\n}\n\n/**\n * 播放器逻辑 Hook\n */\nexport function usePlayer(\n props: EcPlayerProps,\n emit: {\n (e: 'play'): void\n (e: 'pause'): void\n (e: 'loaded'): void\n (e: 'error', error: Error): void\n (e: 'format-detected', format: string): void\n }\n): UsePlayerReturn {\n const canvasRef = ref<HTMLCanvasElement | null>(null)\n const player = shallowRef<EcPlayerCore | null>(null)\n const isLoading = ref(false)\n const detectedFormat = ref('')\n const isLive = ref(false) // 跟踪当前是否为直播流\n\n // 当前播放器配置(初始化时合并全局配置和默认值)\n const globalConfig = getGlobalConfig()\n const currentOptions = reactive<Required<PlayerOptions>>({\n targetBufferSize: globalConfig.targetBufferSize ?? DEFAULT_PLAYER_OPTIONS.targetBufferSize,\n decodeBatchSize: globalConfig.decodeBatchSize ?? DEFAULT_PLAYER_OPTIONS.decodeBatchSize,\n maxQueueSize: globalConfig.maxQueueSize ?? DEFAULT_PLAYER_OPTIONS.maxQueueSize\n })\n\n // 响应式状态\n const state = reactive<EcPlayerState>({\n isPlaying: false,\n isLoaded: false,\n isLoading: false,\n fps: 0,\n resolution: '-',\n decoded: 0,\n downloaded: 0,\n droppedFrames: 0,\n isPrefetching: false,\n segmentIndex: 0,\n totalSegments: 0,\n downloadSpeed: 0,\n currentTime: 0,\n duration: 0\n })\n\n // 创建回调\n const callbacks: EcPlayerCallbacks = {\n onStateChange: (partial) => {\n Object.assign(state, partial)\n\n // 派发 play/pause 事件\n if (partial.isPlaying === true) {\n emit('play')\n } else if (partial.isPlaying === false && state.isPlaying) {\n emit('pause')\n }\n },\n onError: (error) => {\n console.error('[EcPlayer] Error:', error)\n emit('error', error)\n }\n }\n\n // 播放(加载并播放)\n async function play(options: { url: string; isLive?: boolean }): Promise<void> {\n const { url, isLive: isLiveParam = false } = options\n if (!url) {\n emit('error', new Error('URL is required'))\n return\n }\n\n if (isLoading.value) {\n console.log('[EcPlayer] Already loading, skipping...')\n return\n }\n\n // 等待 canvas 准备好\n let retries = 10\n while (!canvasRef.value && retries > 0) {\n await new Promise(resolve => setTimeout(resolve, 100))\n retries--\n }\n\n if (!canvasRef.value) {\n const error = new Error('Canvas element not found')\n emit('error', error)\n return\n }\n\n isLoading.value = true\n isLive.value = isLiveParam\n\n try {\n // 销毁旧播放器\n if (player.value) {\n player.value.destroy()\n player.value = null\n }\n\n // 重置状态\n state.isPlaying = false\n state.isLoaded = false\n state.fps = 0\n state.resolution = '-'\n state.decoded = 0\n state.downloaded = 0\n state.droppedFrames = 0\n state.segmentIndex = 0\n state.totalSegments = 0\n state.downloadSpeed = 0\n state.currentTime = 0\n state.duration = 0\n detectedFormat.value = ''\n\n // 创建配置\n const config: EcPlayerCoreConfig & { canvas: HTMLCanvasElement } = {\n ...createConfig(currentOptions),\n canvas: canvasRef.value,\n isLive: isLiveParam\n }\n\n // 创建播放器\n player.value = new EcPlayerCore(config, callbacks)\n\n // 加载视频\n await player.value.load(url, isLiveParam)\n\n // 获取检测到的格式\n detectedFormat.value = player.value.getDetectedFormat()\n emit('format-detected', detectedFormat.value)\n\n // 标记加载完成\n state.isLoaded = true\n emit('loaded')\n\n // 开始播放\n await player.value.play()\n\n console.log('[EcPlayer] Playing stream, format:', detectedFormat.value)\n } catch (error: any) {\n console.error('[EcPlayer] Failed to play:', error?.message || error)\n emit('error', error)\n } finally {\n isLoading.value = false\n }\n }\n\n // 设置配置\n function setOptions(options: PlayerOptions): void {\n if (options.targetBufferSize !== undefined) {\n currentOptions.targetBufferSize = options.targetBufferSize\n }\n if (options.decodeBatchSize !== undefined) {\n currentOptions.decodeBatchSize = options.decodeBatchSize\n }\n if (options.maxQueueSize !== undefined) {\n currentOptions.maxQueueSize = options.maxQueueSize\n }\n console.log('[EcPlayer] Options updated:', currentOptions)\n }\n\n // 设置日志级别\n function setLogLevel(level: number): void {\n coreSetLogLevel(level)\n }\n\n // 暂停\n function pause(): void {\n player.value?.pause()\n }\n\n // 恢复播放\n async function resume(): Promise<void> {\n if (!player.value) return\n await player.value.play()\n }\n\n // 跳转\n async function seek(time: number): Promise<void> {\n if (!player.value) return\n await player.value.seek(time)\n }\n\n // 获取播放器实例\n function getPlayer(): EcPlayerCore | null {\n return player.value\n }\n\n // 获取状态\n function getState(): EcPlayerState {\n return player.value?.getState() ?? { ...state }\n }\n\n // 获取当前时间\n function getCurrentTime(): number {\n return player.value?.getCurrentTime() ?? 0\n }\n\n // 获取总时长\n function getDuration(): number {\n return player.value?.getDuration() ?? 0\n }\n\n // 销毁播放器\n function destroy(): void {\n if (player.value) {\n player.value.destroy()\n player.value = null\n }\n }\n\n // 组件卸载时销毁\n onUnmounted(() => {\n destroy()\n })\n\n return {\n canvasRef,\n player,\n state,\n isLoading,\n detectedFormat,\n isLive,\n play,\n setOptions,\n setLogLevel,\n pause,\n resume,\n seek,\n getPlayer,\n getState,\n getCurrentTime,\n getDuration,\n destroy\n }\n}\n","/**\n * 播放器控制条逻辑\n */\n\nimport { ref, computed, type Ref } from 'vue'\n\n/**\n * 控制条逻辑参数\n */\nexport interface UseControlsParams {\n /** 是否正在播放 */\n isPlaying: Ref<boolean>\n /** 是否已加载 */\n isLoaded: Ref<boolean>\n /** 当前时间(毫秒) */\n currentTime: Ref<number>\n /** 总时长(毫秒) */\n duration: Ref<number>\n /** 分片索引 */\n segmentIndex: Ref<number>\n /** 总分片数 */\n totalSegments: Ref<number>\n /** 是否为直播流 */\n isLive: Ref<boolean>\n /** 跳转方法 */\n seek: (time: number) => Promise<void>\n}\n\n/**\n * 控制条逻辑返回值\n */\nexport interface UseControlsReturn {\n /** 是否显示控制条 */\n showControls: Ref<boolean>\n /** 进度条 hover 时间 */\n hoverTime: Ref<number | null>\n /** 进度条 hover 位置 */\n hoverPosition: Ref<number>\n /** 播放进度百分比 */\n playProgress: Ref<number>\n /** 缓冲进度百分比 */\n bufferProgress: Ref<number>\n /** 显示控制条 */\n showControlsBar: () => void\n /** 隐藏控制条 */\n hideControlsBar: () => void\n /** 处理进度条点击 */\n handleProgressClick: (event: MouseEvent) => Promise<void>\n /** 处理进度条悬停 */\n handleProgressHover: (event: MouseEvent) => void\n /** 格式化时间 */\n formatTime: (ms: number) => string\n}\n\n/**\n * 控制条逻辑 Hook\n */\nexport function useControls(params: UseControlsParams): UseControlsReturn {\n let hideControlsTimer: number | null = null\n const {\n isPlaying,\n isLoaded,\n currentTime,\n duration,\n segmentIndex,\n totalSegments,\n isLive,\n seek\n } = params\n\n const showControls = ref(true)\n const hoverTime = ref<number | null>(null)\n const hoverPosition = ref(0)\n\n // 计算播放进度\n const playProgress = computed(() => {\n if (duration.value === 0) return 0\n return (currentTime.value / duration.value) * 100\n })\n\n // 计算缓冲进度\n const bufferProgress = computed(() => {\n if (totalSegments.value === 0) return 0\n return (segmentIndex.value / totalSegments.value) * 100\n })\n\n // 显示控制条\n function showControlsBar(): void {\n showControls.value = true\n if (hideControlsTimer) {\n clearTimeout(hideControlsTimer)\n }\n hideControlsTimer = window.setTimeout(() => {\n if (isPlaying.value) {\n showControls.value = false\n }\n }, 3000)\n }\n\n // 隐藏控制条\n function hideControlsBar(): void {\n if (isPlaying.value) {\n showControls.value = false\n }\n }\n\n // 处理进度条点击\n async function handleProgressClick(event: MouseEvent): Promise<void> {\n if (duration.value === 0) return\n\n const target = event.currentTarget as HTMLElement\n const rect = target.getBoundingClientRect()\n const clickX = event.clientX - rect.left\n const percentage = clickX / rect.width\n const targetTime = percentage * duration.value\n\n await seek(targetTime)\n }\n\n // 处理进度条悬停\n function handleProgressHover(event: MouseEvent): void {\n if (duration.value === 0) return\n\n const target = event.currentTarget as HTMLElement\n const rect = target.getBoundingClientRect()\n const hoverX = event.clientX - rect.left\n const percentage = Math.max(0, Math.min(1, hoverX / rect.width))\n\n hoverTime.value = percentage * duration.value\n hoverPosition.value = percentage * 100\n }\n\n // 格式化时间\n function formatTime(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000)\n const hours = Math.floor(totalSeconds / 3600)\n const minutes = Math.floor((totalSeconds % 3600) / 60)\n const seconds = totalSeconds % 60\n\n if (hours > 0) {\n return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`\n }\n return `${minutes}:${seconds.toString().padStart(2, '0')}`\n }\n\n return {\n showControls,\n hoverTime,\n hoverPosition,\n playProgress,\n bufferProgress,\n showControlsBar,\n hideControlsBar,\n handleProgressClick,\n handleProgressHover,\n formatTime\n }\n}\n","/**\n * 环境信息逻辑\n */\n\nimport { ref, computed, onMounted, type Ref } from 'vue'\nimport { EnvDetector, type EcEnvInfo } from '@give-tech/ec-player'\n\n/**\n * 环境信息逻辑返回值\n */\nexport interface UseEnvInfoReturn {\n /** 环境信息 */\n envInfo: Ref<EcEnvInfo | null>\n /** 是否显示环境面板 */\n showEnvPanel: Ref<boolean>\n /** 环境类型文本 */\n envTypeText: Ref<string>\n /** 切换环境面板显示 */\n toggleEnvPanel: () => void\n /** 检测环境 */\n detectEnv: () => void\n}\n\n/**\n * 环境信息逻辑 Hook\n */\nexport function useEnvInfo(\n initialShowPanel: boolean = false\n): UseEnvInfoReturn {\n const envInfo = ref<EcEnvInfo | null>(null)\n const showEnvPanel = ref(initialShowPanel)\n\n // 环境类型文本\n const envTypeText = computed(() => {\n if (!envInfo.value) return '未知'\n const typeMap: Record<string, string> = {\n 'pc-browser': 'PC 浏览器',\n 'mobile-browser': '移动端浏览器',\n 'wechat-miniprogram': '微信小程序',\n 'alipay-miniprogram': '支付宝小程序',\n 'other-miniprogram': '其他小程序',\n 'unknown': '未知',\n }\n return typeMap[envInfo.value.platform] || envInfo.value.platform\n })\n\n // 切换环境面板显示\n function toggleEnvPanel(): void {\n showEnvPanel.value = !showEnvPanel.value\n }\n\n // 检测环境\n function detectEnv(): void {\n envInfo.value = EnvDetector.detect()\n console.log('[EcPlayer] 环境检测结果:', envInfo.value)\n }\n\n // 组件挂载时检测环境\n onMounted(() => {\n detectEnv()\n })\n\n return {\n envInfo,\n showEnvPanel,\n envTypeText,\n toggleEnvPanel,\n detectEnv\n }\n}\n","<template>\n <div class=\"gt-player-container\">\n <div\n class=\"gt-video-wrapper\"\n ref=\"videoWrapperRef\"\n @mouseenter=\"controls.showControlsBar\"\n @mousemove=\"controls.showControlsBar\"\n @mouseleave=\"controls.hideControlsBar\"\n >\n <canvas ref=\"canvasRef\" class=\"gt-player-canvas\"></canvas>\n\n <!-- 环境信息面板 -->\n <div v-if=\"showEnvPanel && envInfo\" class=\"gt-env-panel\">\n <div class=\"gt-env-row\">\n <span>platform</span>\n <span :class=\"envInfo.isMiniProgram ? 'warn' : ''\">{{ envTypeText }}</span>\n </div>\n <div class=\"gt-env-divider\"></div>\n <div class=\"gt-env-row\">\n <span>SIMD</span>\n <span :class=\"envInfo.capabilities.wasmSimd ? 'ok' : 'err'\">\n {{ envInfo.capabilities.wasmSimd ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebGL</span>\n <span :class=\"envInfo.capabilities.webGL ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webGL ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebGL2</span>\n <span :class=\"envInfo.capabilities.webGL2 ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webGL2 ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>SAB</span>\n <span :class=\"envInfo.capabilities.sharedArrayBuffer ? 'ok' : 'err'\">\n {{ envInfo.capabilities.sharedArrayBuffer ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>Threads</span>\n <span :class=\"envInfo.capabilities.wasmThreads ? 'ok' : 'err'\">\n {{ envInfo.capabilities.wasmThreads ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>WebAudio</span>\n <span :class=\"envInfo.capabilities.webAudio ? 'ok' : 'err'\">\n {{ envInfo.capabilities.webAudio ? 'Yes' : 'No' }}\n </span>\n </div>\n <div class=\"gt-env-row\">\n <span>Stream</span>\n <span :class=\"envInfo.capabilities.readableStream ? 'ok' : 'err'\">\n {{ envInfo.capabilities.readableStream ? 'Yes' : 'No' }}\n </span>\n </div>\n <template v-if=\"player.state.isLoaded\">\n <div class=\"gt-env-divider\"></div>\n <div class=\"gt-env-row\"><span>FPS</span><span>{{ player.state.fps }}</span></div>\n <div class=\"gt-env-row\"><span>Resolution</span><span>{{ player.state.resolution }}</span></div>\n <div class=\"gt-env-row\"><span>downloaded</span><span>{{ player.state.downloaded }}</span></div>\n <div class=\"gt-env-row\"><span>decoded</span><span>{{ player.state.decoded }}</span></div>\n <div class=\"gt-env-row\"><span>Dropped</span><span>{{ player.state.droppedFrames }}</span></div>\n <div class=\"gt-env-row\"><span>Speed</span><span>{{ player.state.downloadSpeed || 0 }} KB/s</span></div>\n </template>\n </div>\n\n <!-- 加载中动画 -->\n <div class=\"gt-loading-spinner\" v-if=\"player.isLoading.value\">\n <div class=\"gt-spinner\"></div>\n </div>\n\n <!-- 视频控制条 -->\n <div\n v-if=\"showControlsProp\"\n class=\"gt-video-controls\"\n :class=\"{ visible: controls.showControls.value || !player.state.isPlaying }\"\n >\n <button class=\"gt-control-btn\" @click=\"togglePlayback\">\n <svg v-if=\"player.state.isPlaying\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/>\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\"/>\n </svg>\n <svg v-else viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n </button>\n\n <!-- 直播标识 -->\n <span class=\"gt-live-indicator\" v-if=\"isLive\">\n <span class=\"gt-live-dot\"></span>\n <span class=\"gt-live-text\">实时</span>\n </span>\n\n <!-- 点播时间显示 -->\n <span class=\"gt-time-display\" v-else>\n <span class=\"gt-time-current\">{{ controls.formatTime(player.state.currentTime) }}</span>\n <span class=\"gt-time-separator\">/</span>\n <span class=\"gt-time-duration\">{{ controls.formatTime(player.state.duration) }}</span>\n </span>\n\n <!-- 进度条 (仅点播) -->\n <div\n v-if=\"!isLive\"\n class=\"gt-progress-container\"\n @click=\"controls.handleProgressClick\"\n @mousemove=\"controls.handleProgressHover\"\n @mouseleave=\"controls.hoverTime.value = null\"\n >\n <div class=\"gt-progress-bar\">\n <div class=\"gt-progress-buffered\" :style=\"{ width: controls.bufferProgress.value + '%' }\"></div>\n <div class=\"gt-progress-played\" :style=\"{ width: controls.playProgress.value + '%' }\">\n <div class=\"gt-progress-handle\"></div>\n </div>\n </div>\n <div\n class=\"gt-progress-tooltip\"\n v-if=\"controls.hoverTime.value !== null\"\n :style=\"{ left: controls.hoverPosition.value + '%' }\"\n >\n {{ controls.formatTime(controls.hoverTime.value) }}\n </div>\n </div>\n\n <!-- 直播流占位符 -->\n <div class=\"gt-flex-spacer\" v-else></div>\n\n <!-- 格式标识 -->\n <span class=\"gt-info-badge\" v-if=\"player.detectedFormat.value\">{{ player.detectedFormat.value }}</span>\n\n <!-- 环境信息按钮 -->\n <button class=\"gt-control-btn gt-env-info-btn\" @click=\"toggleEnvPanel\" :title=\"showEnvPanel ? '隐藏信息' : '显示信息'\">\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <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\"/>\n </svg>\n </button>\n </div>\n\n <!-- 大播放按钮(居中) -->\n <div\n class=\"gt-center-play-btn\"\n v-if=\"player.state.isLoaded && !player.state.isPlaying\"\n @click=\"togglePlayback\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\"/>\n </svg>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { usePlayer } from '../composables/usePlayer'\nimport { useControls } from '../composables/useControls'\nimport { useEnvInfo } from '../composables/useEnvInfo'\nimport type { EcPlayerProps, EcPlayerExpose } from '../types'\nimport { DEFAULT_EC_PLAYER_PROPS } from '../types'\n\n// Props\nconst props = withDefaults(defineProps<EcPlayerProps>(), DEFAULT_EC_PLAYER_PROPS)\n\n// Emits\nconst emit = defineEmits<{\n (e: 'play'): void\n (e: 'pause'): void\n (e: 'loaded'): void\n (e: 'error', error: Error): void\n (e: 'format-detected', format: string): void\n}>()\n\n// Canvas ref(本地)\nconst canvasRef = ref<HTMLCanvasElement | null>(null)\n\n// 环境信息逻辑\nconst { envInfo, showEnvPanel, envTypeText, toggleEnvPanel } = useEnvInfo(props.showEnvPanel)\n\n// 播放器逻辑\nconst player = usePlayer(props, emit)\n\n// 同步 canvas ref 到 player\nwatch(canvasRef, (el) => {\n player.canvasRef.value = el\n}, { immediate: true })\n\n// isLive 计算属性(用于模板)\nconst isLive = computed(() => player.isLive.value)\n\n// 控制条逻辑\nconst isPlayingRef = computed(() => player.state.isPlaying)\nconst isLoadedRef = computed(() => player.state.isLoaded)\nconst currentTimeRef = computed(() => player.state.currentTime)\nconst durationRef = computed(() => player.state.duration)\nconst segmentIndexRef = computed(() => player.state.segmentIndex)\nconst totalSegmentsRef = computed(() => player.state.totalSegments)\n\nconst controls = useControls({\n isPlaying: isPlayingRef,\n isLoaded: isLoadedRef,\n currentTime: currentTimeRef,\n duration: durationRef,\n segmentIndex: segmentIndexRef,\n totalSegments: totalSegmentsRef,\n isLive,\n seek: player.seek\n})\n\n// 视频包装器引用\nconst videoWrapperRef = ref<HTMLElement | null>(null)\n\n// 显示控制条属性(用于条件渲染)\nconst showControlsProp = computed(() => props.showControls)\n\n// 切换播放/暂停\nfunction togglePlayback(): void {\n if (player.state.isPlaying) {\n player.pause()\n } else {\n player.resume()\n }\n}\n\n// Expose 方法\ndefineExpose<EcPlayerExpose>({\n play: player.play,\n setOptions: player.setOptions,\n setLogLevel: player.setLogLevel,\n pause: player.pause,\n seek: player.seek,\n getPlayer: player.getPlayer,\n getState: player.getState,\n getCurrentTime: player.getCurrentTime,\n getDuration: player.getDuration\n})\n</script>\n\n<style scoped>\n.gt-player-container {\n width: 100%;\n max-width: 800px;\n margin: 0 auto;\n}\n\n.gt-video-wrapper {\n position: relative;\n background: #000;\n border-radius: 4px;\n overflow: hidden;\n width: 100%;\n}\n\n.gt-player-canvas {\n width: 100%;\n height: auto;\n display: block;\n}\n\n/* 加载中动画 */\n.gt-loading-spinner {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10;\n}\n\n.gt-spinner {\n width: 8vmin;\n height: 8vmin;\n border: 0.5vmin solid rgba(255, 255, 255, 0.3);\n border-top-color: #fff;\n border-radius: 50%;\n animation: gt-spin 1s linear infinite;\n}\n\n@keyframes gt-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* 视频控制条 */\n.gt-video-controls {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n padding: 10px 16px;\n background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));\n opacity: 0;\n transition: opacity 0.3s ease;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.gt-flex-spacer {\n flex: 1;\n}\n\n.gt-video-controls.visible {\n opacity: 1;\n}\n\n.gt-control-btn {\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n background: transparent;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.gt-control-btn:hover {\n background: rgba(255, 255, 255, 0.2);\n}\n\n.gt-control-btn svg {\n width: 14px;\n height: 14px;\n}\n\n.gt-progress-container {\n flex: 1;\n position: relative;\n cursor: pointer;\n height: 20px;\n display: flex;\n align-items: center;\n}\n\n.gt-progress-bar {\n width: 100%;\n height: 4px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n position: relative;\n overflow: hidden;\n transition: height 0.2s ease;\n}\n\n.gt-progress-container:hover .gt-progress-bar {\n height: 6px;\n}\n\n.gt-progress-buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.4);\n border-radius: 2px;\n transition: width 0.1s;\n}\n\n.gt-progress-played {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: #ff2d55;\n border-radius: 2px;\n transition: width 0.1s;\n}\n\n.gt-progress-handle {\n position: absolute;\n right: -6px;\n top: 50%;\n transform: translateY(-50%);\n width: 14px;\n height: 14px;\n background: #ff2d55;\n border-radius: 50%;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n opacity: 0;\n transition: opacity 0.2s, transform 0.2s;\n}\n\n.gt-progress-container:hover .gt-progress-handle {\n opacity: 1;\n transform: translateY(-50%) scale(1.2);\n}\n\n.gt-progress-tooltip {\n position: absolute;\n bottom: calc(100% + 8px);\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.85);\n color: white;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 11px;\n white-space: nowrap;\n pointer-events: none;\n}\n\n.gt-time-display {\n color: white;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.gt-time-separator {\n margin: 0 4px;\n opacity: 0.6;\n}\n\n.gt-info-badge {\n background: rgba(255, 255, 255, 0.2);\n color: white;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n/* 直播指示器 */\n.gt-live-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n color: white;\n font-size: 12px;\n font-weight: 500;\n}\n\n.gt-live-dot {\n width: 8px;\n height: 8px;\n background: #ff2d55;\n border-radius: 50%;\n animation: gt-live-pulse 1.5s ease-in-out infinite;\n}\n\n.gt-live-text {\n color: #ff2d55;\n}\n\n@keyframes gt-live-pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.4;\n }\n}\n\n/* 居中播放按钮 */\n.gt-center-play-btn {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 56px;\n height: 56px;\n background: rgba(0, 0, 0, 0.5);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.gt-center-play-btn:hover {\n background: rgba(0, 0, 0, 0.7);\n transform: translate(-50%, -50%) scale(1.05);\n}\n\n.gt-center-play-btn svg {\n width: 24px;\n height: 24px;\n color: white;\n margin-left: 3px;\n}\n\n/* 环境信息面板 */\n.gt-env-panel {\n position: absolute;\n top: 12px;\n left: 12px;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 6px;\n padding: 8px 10px;\n font-size: 11px;\n font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;\n min-width: 160px;\n max-width: 200px;\n max-height: calc(100% - 24px);\n overflow-y: auto;\n backdrop-filter: blur(10px);\n animation: gt-env-fade-in 0.15s ease;\n z-index: 15;\n}\n\n.gt-env-panel::-webkit-scrollbar {\n width: 4px;\n}\n\n.gt-env-panel::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.gt-env-panel::-webkit-scrollbar-thumb {\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n}\n\n@keyframes gt-env-fade-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.gt-env-panel .gt-env-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 2px 0;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.gt-env-panel .gt-env-row span:first-child {\n color: rgba(255, 255, 255, 0.5);\n margin-right: 16px;\n}\n\n.gt-env-panel .gt-env-row span:last-child {\n font-variant-numeric: tabular-nums;\n}\n\n.gt-env-panel .gt-env-row .ok { color: #4caf50; }\n.gt-env-panel .gt-env-row .warn { color: #ff9800; }\n.gt-env-panel .gt-env-row .err { color: #f44336; }\n\n.gt-env-divider {\n height: 1px;\n background: rgba(255, 255, 255, 0.1);\n margin: 4px 0;\n}\n</style>\n"],"names":["globalConfig","setLogLevel","coreSetLogLevel","_openBlock","_createElementBlock","_createElementVNode","_unref","_normalizeClass","_Fragment","_toDisplayString","_normalizeStyle"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -92,8 +92,6 @@ export interface EcPlayerEmits {
|
|
|
92
92
|
(e: 'loaded'): void;
|
|
93
93
|
/** 错误时触发 */
|
|
94
94
|
(e: 'error', error: Error): void;
|
|
95
|
-
/** 状态更新时触发 */
|
|
96
|
-
(e: 'state-change', state: Partial<EcPlayerState>): void;
|
|
97
95
|
/** 格式检测完成时触发 */
|
|
98
96
|
(e: 'format-detected', format: string): void;
|
|
99
97
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,gBAAgB;IAChB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,eAAe;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,sBAAsB;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iBAAiB;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc;IACd,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjB,qBAAqB;IACrB,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAClB,cAAc;IACd,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IACnB,YAAY;IACZ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAChC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|