coda-player 0.0.0-stage → 2.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/README.md +154 -3
- package/index.d.ts +5 -0
- package/index.d.ts.map +1 -0
- package/index.js +3 -0
- package/main.js +2 -0
- package/main.js.gz +0 -0
- package/main.js.map +1 -0
- package/package.json +8 -4
- package/player/base.player.d.ts +128 -0
- package/player/base.player.d.ts.map +1 -0
- package/player/base.player.js +195 -0
- package/player/coda.player.d.ts +115 -0
- package/player/coda.player.d.ts.map +1 -0
- package/player/coda.player.js +452 -0
- package/types/index.d.ts +87 -0
- package/types/index.d.ts.map +1 -0
- package/types/index.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coda-player",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "coda-player是一款轻量级HTML5视频播放器SDK,开箱即用,支持主流视频格式和HLS直播流,UI和功能高度可定制。",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"hls.js": "^1.7.4"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { PlaybackRate, PlayerOptions, PlayerState, IPlayer, PlayerEventTypes, PlayerEventCallback } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* 抽象类:负责通用的生命周期管理、DOM 骨架初始化、基础状态维护及标准事件总线(Event Bus)
|
|
4
|
+
*/
|
|
5
|
+
export declare abstract class BasePlayer implements IPlayer {
|
|
6
|
+
/**DOM元素或CSS选择器 */
|
|
7
|
+
protected container: HTMLElement;
|
|
8
|
+
/**播放器属性 */
|
|
9
|
+
protected options: PlayerOptions;
|
|
10
|
+
/**video元素对象 */
|
|
11
|
+
protected videoElement: HTMLVideoElement;
|
|
12
|
+
/**播放器状态 */
|
|
13
|
+
protected _state: PlayerState;
|
|
14
|
+
/**是否是全屏 */
|
|
15
|
+
protected _isFullScreen: boolean;
|
|
16
|
+
/**播放速率 */
|
|
17
|
+
protected _playbackRate: PlaybackRate;
|
|
18
|
+
/** 内部事件监听器注册表:用于实现类似 player.on('event', callback) 的订阅机制 */
|
|
19
|
+
private eventListeners;
|
|
20
|
+
constructor(options: PlayerOptions);
|
|
21
|
+
/**
|
|
22
|
+
* 解析并校验挂载容器(支持 DOM 元素或 CSS 选择器字符串)
|
|
23
|
+
* @param container DOM元素或CSS选择器
|
|
24
|
+
* @returns 返回容器对象
|
|
25
|
+
*/
|
|
26
|
+
private resolveContainer;
|
|
27
|
+
/**
|
|
28
|
+
* 初始化基础 DOM 结构与视频核心标签
|
|
29
|
+
*/
|
|
30
|
+
private initBaseDOM;
|
|
31
|
+
/**
|
|
32
|
+
* 绑定底层视频原生状态事件,并统一桥接到事件总线中
|
|
33
|
+
* 原生video对象事件
|
|
34
|
+
*/
|
|
35
|
+
private bindBaseEvents;
|
|
36
|
+
/**
|
|
37
|
+
* 更新播放器内部状态并触发状态变更事件
|
|
38
|
+
* @param state 播放器状态
|
|
39
|
+
*/
|
|
40
|
+
protected setState(state: PlayerState): void;
|
|
41
|
+
/**
|
|
42
|
+
* 播放器状态变更事件
|
|
43
|
+
* @param state 播放器状态
|
|
44
|
+
*/
|
|
45
|
+
protected abstract onStateChange(state: PlayerState): void;
|
|
46
|
+
/**
|
|
47
|
+
* 订阅播放器事件(支持链式调用)
|
|
48
|
+
* @param event 事件名称
|
|
49
|
+
* @param callback 回调函数
|
|
50
|
+
* @returns 返回播放器对象
|
|
51
|
+
*/
|
|
52
|
+
on<K extends PlayerEventTypes>(event: K, callback: PlayerEventCallback<K>): this;
|
|
53
|
+
/**
|
|
54
|
+
* 取消订阅播放器事件
|
|
55
|
+
* @param event 事件名称
|
|
56
|
+
* @param callback 回调函数
|
|
57
|
+
* @returns 返回播放器对象
|
|
58
|
+
*/
|
|
59
|
+
off<K extends PlayerEventTypes>(event: K, callback: PlayerEventCallback<K>): this;
|
|
60
|
+
/**
|
|
61
|
+
* 触发内部事件分发
|
|
62
|
+
* @param event 事件名称
|
|
63
|
+
* @param args 任意数据
|
|
64
|
+
*/
|
|
65
|
+
protected emit<K extends PlayerEventTypes>(event: K, ...args: any[]): void;
|
|
66
|
+
/**
|
|
67
|
+
* 获取播放器当前时间
|
|
68
|
+
*/
|
|
69
|
+
get currentTime(): number;
|
|
70
|
+
get duration(): number;
|
|
71
|
+
/**
|
|
72
|
+
* 获取播放器当前音量
|
|
73
|
+
*/
|
|
74
|
+
get volume(): number;
|
|
75
|
+
/**
|
|
76
|
+
* 获取播放器是否静音
|
|
77
|
+
*/
|
|
78
|
+
get muted(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* 获取播放器状态
|
|
81
|
+
*/
|
|
82
|
+
get state(): PlayerState;
|
|
83
|
+
/**
|
|
84
|
+
* 获取播放器是否全屏
|
|
85
|
+
*/
|
|
86
|
+
get isFullScreen(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* 获取播放器播放速率
|
|
89
|
+
*/
|
|
90
|
+
get playbackRate(): PlaybackRate;
|
|
91
|
+
/**
|
|
92
|
+
* 播放器播放方法
|
|
93
|
+
*/
|
|
94
|
+
abstract play(): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* 播放器暂停方法
|
|
97
|
+
*/
|
|
98
|
+
abstract pause(): void;
|
|
99
|
+
/**
|
|
100
|
+
* 播放器播放方法 播放器快进方法
|
|
101
|
+
* @param time 时间
|
|
102
|
+
*/
|
|
103
|
+
abstract seek(time: number): void;
|
|
104
|
+
/**
|
|
105
|
+
* 播放器音量设置方法
|
|
106
|
+
* @param volume 音量
|
|
107
|
+
*/
|
|
108
|
+
abstract setVolume(volume: number): void;
|
|
109
|
+
/**
|
|
110
|
+
* 播放器设置静音方法
|
|
111
|
+
* @param muted 是否静音
|
|
112
|
+
*/
|
|
113
|
+
abstract setMuted(muted: boolean): void;
|
|
114
|
+
/**
|
|
115
|
+
* 播放器设置速率方法
|
|
116
|
+
* @param rate 播放速率
|
|
117
|
+
*/
|
|
118
|
+
abstract setPlaybackRate(rate: PlaybackRate): void;
|
|
119
|
+
/**
|
|
120
|
+
* 播放器切换全屏方法
|
|
121
|
+
*/
|
|
122
|
+
abstract toggleFullScreen(): void;
|
|
123
|
+
/**
|
|
124
|
+
* 播放器注销方法
|
|
125
|
+
*/
|
|
126
|
+
abstract destroy(): void;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=base.player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.player.d.ts","sourceRoot":"","sources":["../../src/player/base.player.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,8BAAsB,UAAW,YAAW,OAAO;IACjD,kBAAkB;IAClB,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC;IACjC,WAAW;IACX,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC;IACjC,eAAe;IACf,SAAS,CAAC,YAAY,EAAG,gBAAgB,CAAC;IAC1C,WAAW;IACX,SAAS,CAAC,MAAM,EAAE,WAAW,CAAU;IACvC,WAAW;IACX,SAAS,CAAC,aAAa,EAAE,OAAO,CAAS;IACzC,UAAU;IACV,SAAS,CAAC,aAAa,EAAE,YAAY,CAAO;IAE5C,2DAA2D;IAC3D,OAAO,CAAC,cAAc,CAAyC;gBAEnD,OAAO,EAAE,aAAa;IAOlC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkCnB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAgCtB;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAM5C;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAE1D;;;;;OAKG;IACI,EAAE,CAAC,CAAC,SAAS,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI;IAcvF;;;;;OAKG;IACI,GAAG,CAAC,CAAC,SAAS,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI;IAQxF;;;;OAIG;IACH,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAO1E;;OAEG;IACH,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,OAAO,CAE1B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,WAAW,CAE9B;IAED;;OAEG;IACH,IAAW,YAAY,IAAI,OAAO,CAEjC;IAED;;OAEG;IACH,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED;;OAEG;aACa,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErC;;OAEG;aACa,KAAK,IAAI,IAAI;IAE7B;;;OAGG;aACa,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAExC;;;OAGG;aACa,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAE/C;;;OAGG;aACa,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAE9C;;;OAGG;aACa,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAEzD;;OAEG;aACa,gBAAgB,IAAI,IAAI;IAExC;;OAEG;aACa,OAAO,IAAI,IAAI;CAChC"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 抽象类:负责通用的生命周期管理、DOM 骨架初始化、基础状态维护及标准事件总线(Event Bus)
|
|
3
|
+
*/
|
|
4
|
+
export class BasePlayer {
|
|
5
|
+
/**DOM元素或CSS选择器 */
|
|
6
|
+
container;
|
|
7
|
+
/**播放器属性 */
|
|
8
|
+
options;
|
|
9
|
+
/**video元素对象 */
|
|
10
|
+
videoElement;
|
|
11
|
+
/**播放器状态 */
|
|
12
|
+
_state = 'idle';
|
|
13
|
+
/**是否是全屏 */
|
|
14
|
+
_isFullScreen = false;
|
|
15
|
+
/**播放速率 */
|
|
16
|
+
_playbackRate = 1.0;
|
|
17
|
+
/** 内部事件监听器注册表:用于实现类似 player.on('event', callback) 的订阅机制 */
|
|
18
|
+
eventListeners = new Map();
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.options = options;
|
|
21
|
+
this.container = this.resolveContainer(options.container);
|
|
22
|
+
this.initBaseDOM();
|
|
23
|
+
this.bindBaseEvents();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 解析并校验挂载容器(支持 DOM 元素或 CSS 选择器字符串)
|
|
27
|
+
* @param container DOM元素或CSS选择器
|
|
28
|
+
* @returns 返回容器对象
|
|
29
|
+
*/
|
|
30
|
+
resolveContainer(container) {
|
|
31
|
+
if (typeof container === 'string') {
|
|
32
|
+
const el = document.querySelector(container);
|
|
33
|
+
if (!el) {
|
|
34
|
+
throw new Error(`CodaPlayer: Container element "${container}" not found.`);
|
|
35
|
+
}
|
|
36
|
+
return el;
|
|
37
|
+
}
|
|
38
|
+
return container;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 初始化基础 DOM 结构与视频核心标签
|
|
42
|
+
*/
|
|
43
|
+
initBaseDOM() {
|
|
44
|
+
/**1. 初始化容器内容/样式 */
|
|
45
|
+
this.container.innerHTML = '';
|
|
46
|
+
this.container.classList.add('coda-player-container');
|
|
47
|
+
/**
|
|
48
|
+
* 2. 使用外部参数设置容器属性
|
|
49
|
+
* 宽度/高度/主题色
|
|
50
|
+
*/
|
|
51
|
+
if (this.options.width) {
|
|
52
|
+
this.container.style.width =
|
|
53
|
+
typeof this.options.width === 'number' ? `${this.options.width}px` : this.options.width;
|
|
54
|
+
}
|
|
55
|
+
if (this.options.height) {
|
|
56
|
+
this.container.style.height =
|
|
57
|
+
typeof this.options.height === 'number' ? `${this.options.height}px` : this.options.height;
|
|
58
|
+
}
|
|
59
|
+
if (this.options.themeColor) {
|
|
60
|
+
this.container.style.setProperty('--coda-theme-color', this.options.themeColor);
|
|
61
|
+
}
|
|
62
|
+
/**3. 创建和设置video元素 */
|
|
63
|
+
this.videoElement = document.createElement('video');
|
|
64
|
+
this.videoElement.className = 'coda-player-video';
|
|
65
|
+
this.videoElement.playsInline = true;
|
|
66
|
+
if (this.options.poster)
|
|
67
|
+
this.videoElement.poster = this.options.poster;
|
|
68
|
+
if (this.options.muted)
|
|
69
|
+
this.videoElement.muted = true;
|
|
70
|
+
if (this.options.loop)
|
|
71
|
+
this.videoElement.loop = true;
|
|
72
|
+
if (this.options.autoplay)
|
|
73
|
+
this.videoElement.autoplay = true;
|
|
74
|
+
/**4. video元素加入容器 */
|
|
75
|
+
this.container.appendChild(this.videoElement);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 绑定底层视频原生状态事件,并统一桥接到事件总线中
|
|
79
|
+
* 原生video对象事件
|
|
80
|
+
*/
|
|
81
|
+
bindBaseEvents() {
|
|
82
|
+
this.videoElement.addEventListener('loadstart', () => this.setState('loading'));
|
|
83
|
+
this.videoElement.addEventListener('playing', () => {
|
|
84
|
+
this.setState('playing');
|
|
85
|
+
this.emit('play');
|
|
86
|
+
});
|
|
87
|
+
this.videoElement.addEventListener('pause', () => {
|
|
88
|
+
this.setState('paused');
|
|
89
|
+
this.emit('pause');
|
|
90
|
+
});
|
|
91
|
+
this.videoElement.addEventListener('ended', () => {
|
|
92
|
+
this.setState('ended');
|
|
93
|
+
this.emit('ended');
|
|
94
|
+
});
|
|
95
|
+
this.videoElement.addEventListener('error', e => {
|
|
96
|
+
this.setState('error');
|
|
97
|
+
this.emit('error', e);
|
|
98
|
+
});
|
|
99
|
+
this.videoElement.addEventListener('timeupdate', () => {
|
|
100
|
+
this.emit('timeupdate', this.currentTime);
|
|
101
|
+
});
|
|
102
|
+
this.videoElement.addEventListener('volumechange', () => {
|
|
103
|
+
this.emit('volumechange', { volume: this.volume, muted: this.muted });
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 更新播放器内部状态并触发状态变更事件
|
|
108
|
+
* @param state 播放器状态
|
|
109
|
+
*/
|
|
110
|
+
setState(state) {
|
|
111
|
+
this._state = state;
|
|
112
|
+
this.onStateChange(state);
|
|
113
|
+
this.emit('statechange', state); // 统一分发状态变更事件
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 订阅播放器事件(支持链式调用)
|
|
117
|
+
* @param event 事件名称
|
|
118
|
+
* @param callback 回调函数
|
|
119
|
+
* @returns 返回播放器对象
|
|
120
|
+
*/
|
|
121
|
+
on(event, callback) {
|
|
122
|
+
if (!this.eventListeners.has(event)) {
|
|
123
|
+
this.eventListeners.set(event, new Set());
|
|
124
|
+
}
|
|
125
|
+
this.eventListeners.get(event).add(callback);
|
|
126
|
+
// 如果订阅的是原生事件且不在我们自定义映射内,可以直接桥接到 videoElement 上
|
|
127
|
+
if (!(event in this.eventListeners) && event in HTMLVideoElement.prototype) {
|
|
128
|
+
this.videoElement.addEventListener(event, callback);
|
|
129
|
+
}
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 取消订阅播放器事件
|
|
134
|
+
* @param event 事件名称
|
|
135
|
+
* @param callback 回调函数
|
|
136
|
+
* @returns 返回播放器对象
|
|
137
|
+
*/
|
|
138
|
+
off(event, callback) {
|
|
139
|
+
const listeners = this.eventListeners.get(event);
|
|
140
|
+
if (listeners) {
|
|
141
|
+
listeners.delete(callback);
|
|
142
|
+
}
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 触发内部事件分发
|
|
147
|
+
* @param event 事件名称
|
|
148
|
+
* @param args 任意数据
|
|
149
|
+
*/
|
|
150
|
+
emit(event, ...args) {
|
|
151
|
+
const listeners = this.eventListeners.get(event);
|
|
152
|
+
if (listeners) {
|
|
153
|
+
listeners.forEach(callback => callback(...args));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 获取播放器当前时间
|
|
158
|
+
*/
|
|
159
|
+
get currentTime() {
|
|
160
|
+
return this.videoElement.currentTime;
|
|
161
|
+
}
|
|
162
|
+
get duration() {
|
|
163
|
+
return isNaN(this.videoElement.duration) ? 0 : this.videoElement.duration;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 获取播放器当前音量
|
|
167
|
+
*/
|
|
168
|
+
get volume() {
|
|
169
|
+
return this.videoElement.volume;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 获取播放器是否静音
|
|
173
|
+
*/
|
|
174
|
+
get muted() {
|
|
175
|
+
return this.videoElement.muted;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 获取播放器状态
|
|
179
|
+
*/
|
|
180
|
+
get state() {
|
|
181
|
+
return this._state;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 获取播放器是否全屏
|
|
185
|
+
*/
|
|
186
|
+
get isFullScreen() {
|
|
187
|
+
return this._isFullScreen;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* 获取播放器播放速率
|
|
191
|
+
*/
|
|
192
|
+
get playbackRate() {
|
|
193
|
+
return this._playbackRate;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { PlaybackRate, PlayerOptions, PlayerState } from '../types';
|
|
2
|
+
import { BasePlayer } from './base.player';
|
|
3
|
+
/**
|
|
4
|
+
* 实现类:负责具体 UI 渲染、控制栏交互、换肤、快捷键与 HLS 切片流式传输支持
|
|
5
|
+
*/
|
|
6
|
+
export declare class CodaPlayer extends BasePlayer {
|
|
7
|
+
/**hls对象实例 */
|
|
8
|
+
private hlsInstance;
|
|
9
|
+
/**播放器控制栏DOM元素 */
|
|
10
|
+
private controlsElement;
|
|
11
|
+
/**播放器中心暂停/播放按钮 */
|
|
12
|
+
private centerPlayBtn;
|
|
13
|
+
/**控制栏播放按钮 */
|
|
14
|
+
private playBtn;
|
|
15
|
+
/**控制栏播放进度条 */
|
|
16
|
+
private progressBar;
|
|
17
|
+
private progressFilled;
|
|
18
|
+
/**视频时间 */
|
|
19
|
+
private timeDisplay;
|
|
20
|
+
/**进度条时间提示 */
|
|
21
|
+
private timeTooltip;
|
|
22
|
+
/**音量进度条 */
|
|
23
|
+
private volumeBar;
|
|
24
|
+
/**音量按钮 */
|
|
25
|
+
private volumeBtn;
|
|
26
|
+
/**播放倍速按钮 */
|
|
27
|
+
private speedBtn;
|
|
28
|
+
/**播放倍速菜单 */
|
|
29
|
+
private speedMenu;
|
|
30
|
+
/**全屏按钮 */
|
|
31
|
+
private fullscreenBtn;
|
|
32
|
+
/**鼠标是否悬浮在播放器容器上 */
|
|
33
|
+
private isHoveringContainer;
|
|
34
|
+
/**播放器中心暂停/播放按钮显示时间 */
|
|
35
|
+
private centerIconTimer;
|
|
36
|
+
constructor(options: PlayerOptions);
|
|
37
|
+
/**
|
|
38
|
+
* 初始化视频源
|
|
39
|
+
* 智能判断视频格式进行视频源初始化:
|
|
40
|
+
* 1. .m3u8格式启用HLS播放
|
|
41
|
+
* 2. 其他格式直接使用video原生播放
|
|
42
|
+
* @param url 视频源地址
|
|
43
|
+
*/
|
|
44
|
+
private initSource;
|
|
45
|
+
/**
|
|
46
|
+
* 初始化完整控制栏 UI 组件
|
|
47
|
+
*/
|
|
48
|
+
private initControlUI;
|
|
49
|
+
/**
|
|
50
|
+
* 中心图标的控制显示
|
|
51
|
+
* @param icon 图标类型:播放/暂停
|
|
52
|
+
* @param autoHide 是否自动隐藏图标
|
|
53
|
+
*/
|
|
54
|
+
private showCenterIcon;
|
|
55
|
+
/**
|
|
56
|
+
* 绑定控制栏所有交互逻辑
|
|
57
|
+
*/
|
|
58
|
+
private bindControlEvents;
|
|
59
|
+
/**
|
|
60
|
+
* 绑定快捷键(感知悬停焦点,防多实例冲突)
|
|
61
|
+
*/
|
|
62
|
+
private bindKeyboardShortcuts;
|
|
63
|
+
/**
|
|
64
|
+
* 更新播放进度条
|
|
65
|
+
*/
|
|
66
|
+
private updateProgressUI;
|
|
67
|
+
/**
|
|
68
|
+
* 格式化播放时间显示
|
|
69
|
+
* @param seconds 秒
|
|
70
|
+
* @returns 时间格式字符串
|
|
71
|
+
*/
|
|
72
|
+
private formatTime;
|
|
73
|
+
/**
|
|
74
|
+
* 响应状态变化,控制中心图标的显隐和形态
|
|
75
|
+
* @param state 播放器状态
|
|
76
|
+
*/
|
|
77
|
+
protected onStateChange(state: PlayerState): void;
|
|
78
|
+
/**
|
|
79
|
+
* 实现播放方法
|
|
80
|
+
*/
|
|
81
|
+
play(): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* 实现暂停方法
|
|
84
|
+
*/
|
|
85
|
+
pause(): void;
|
|
86
|
+
/**
|
|
87
|
+
* 实现进度条快进方法
|
|
88
|
+
* @param time
|
|
89
|
+
*/
|
|
90
|
+
seek(time: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* 实现音量设置方法
|
|
93
|
+
* @param volume 音量
|
|
94
|
+
*/
|
|
95
|
+
setVolume(volume: number): void;
|
|
96
|
+
/**
|
|
97
|
+
* 实现静音控制方法
|
|
98
|
+
* @param muted 是否静音
|
|
99
|
+
*/
|
|
100
|
+
setMuted(muted: boolean): void;
|
|
101
|
+
/**
|
|
102
|
+
* 实现播放倍速设置方法
|
|
103
|
+
* @param rate 播放倍速
|
|
104
|
+
*/
|
|
105
|
+
setPlaybackRate(rate: PlaybackRate): void;
|
|
106
|
+
/**
|
|
107
|
+
* 实现播放器全屏切换方法
|
|
108
|
+
*/
|
|
109
|
+
toggleFullScreen(): void;
|
|
110
|
+
/**
|
|
111
|
+
* 实现播放器对象注销方法
|
|
112
|
+
*/
|
|
113
|
+
destroy(): void;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=coda.player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coda.player.d.ts","sourceRoot":"","sources":["../../src/player/coda.player.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,UAAU,CAAC;AAClE,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,aAAa;IACb,OAAO,CAAC,WAAW,CAAoB;IACvC,iBAAiB;IACjB,OAAO,CAAC,eAAe,CAAkB;IACzC,kBAAkB;IAClB,OAAO,CAAC,aAAa,CAAkB;IACvC,aAAa;IACb,OAAO,CAAC,OAAO,CAAqB;IACpC,cAAc;IACd,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,cAAc,CAAkB;IACxC,UAAU;IACV,OAAO,CAAC,WAAW,CAAmB;IACtC,aAAa;IACb,OAAO,CAAC,WAAW,CAAkB;IACrC,WAAW;IACX,OAAO,CAAC,SAAS,CAAoB;IACrC,UAAU;IACV,OAAO,CAAC,SAAS,CAAqB;IACtC,YAAY;IACZ,OAAO,CAAC,QAAQ,CAAqB;IACrC,YAAY;IACZ,OAAO,CAAC,SAAS,CAAkB;IACnC,UAAU;IACV,OAAO,CAAC,aAAa,CAAqB;IAC1C,mBAAmB;IACnB,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,sBAAsB;IACtB,OAAO,CAAC,eAAe,CAAuB;gBAElC,OAAO,EAAE,aAAa;IAQlC;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAmBlB;;OAEG;IACH,OAAO,CAAC,aAAa;IA2DrB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA+HzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiC7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAOlB;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IA2BjD;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQlC;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;;OAGG;IACI,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B;;;OAGG;IACI,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYtC;;;OAGG;IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAMrC;;;OAGG;IACI,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAKhD;;OAEG;IACI,gBAAgB,IAAI,IAAI;IAY/B;;OAEG;IACI,OAAO,IAAI,IAAI;CAQvB"}
|