tiny-essentials 1.28.6 → 1.28.8

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.
Files changed (54) hide show
  1. package/changelog/1/28/6.md +3 -0
  2. package/changelog/1/28/7.md +7 -0
  3. package/changelog/1/28/8.md +17 -0
  4. package/dist/v1/TinyBasicsEs.min.js +1 -1
  5. package/dist/v1/TinyDebugger.min.js +1 -0
  6. package/dist/v1/TinyEssentials.min.js +1 -1
  7. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  8. package/dist/v1/TinyRadioFm.min.js +1 -1
  9. package/dist/v1/TinyUploadClicker.min.js +1 -1
  10. package/dist/v1/basics/browserDetector.cjs +228 -0
  11. package/dist/v1/basics/browserDetector.d.mts +66 -0
  12. package/dist/v1/basics/browserDetector.mjs +207 -0
  13. package/dist/v1/basics/index.cjs +6 -0
  14. package/dist/v1/basics/index.d.mts +2 -1
  15. package/dist/v1/basics/index.mjs +2 -1
  16. package/dist/v1/build/TinyDebugger.cjs +7 -0
  17. package/dist/v1/build/TinyDebugger.d.mts +3 -0
  18. package/dist/v1/build/TinyDebugger.mjs +2 -0
  19. package/dist/v1/index.cjs +8 -0
  20. package/dist/v1/index.d.mts +3 -1
  21. package/dist/v1/index.mjs +4 -2
  22. package/dist/v1/libs/TinyDebugger.cjs +380 -0
  23. package/dist/v1/libs/TinyDebugger.d.mts +132 -0
  24. package/dist/v1/libs/TinyDebugger.mjs +351 -0
  25. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.cjs +66 -3
  26. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.d.mts +25 -0
  27. package/dist/v1/libs/TinyMediaPlayer/HtmlAudio.mjs +59 -3
  28. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.cjs +66 -3
  29. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.d.mts +25 -0
  30. package/dist/v1/libs/TinyMediaPlayer/HtmlVideo.mjs +59 -3
  31. package/dist/v1/libs/TinyMediaPlayer/Mock.cjs +333 -0
  32. package/dist/v1/libs/TinyMediaPlayer/Mock.d.mts +154 -0
  33. package/dist/v1/libs/TinyMediaPlayer/Mock.mjs +296 -0
  34. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.cjs +85 -1
  35. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.d.mts +25 -0
  36. package/dist/v1/libs/TinyMediaPlayer/SoundCloud.mjs +75 -1
  37. package/dist/v1/libs/TinyMediaPlayer/Youtube.cjs +66 -3
  38. package/dist/v1/libs/TinyMediaPlayer/Youtube.d.mts +25 -0
  39. package/dist/v1/libs/TinyMediaPlayer/Youtube.mjs +56 -3
  40. package/dist/v1/libs/TinyMediaPlayer/index.cjs +45 -0
  41. package/dist/v1/libs/TinyMediaPlayer/index.d.mts +25 -0
  42. package/dist/v1/libs/TinyMediaPlayer/index.mjs +40 -0
  43. package/dist/v1/libs/TinyMediaPlayer.cjs +172 -10
  44. package/dist/v1/libs/TinyMediaPlayer.d.mts +47 -2
  45. package/dist/v1/libs/TinyMediaPlayer.mjs +160 -10
  46. package/dist/v1/libs/TinyPromiseQueue.cjs +6 -4
  47. package/dist/v1/libs/TinyPromiseQueue.d.mts +8 -6
  48. package/dist/v1/libs/TinyPromiseQueue.mjs +6 -4
  49. package/dist/v1/libs/TinyRadioFm.cjs +271 -138
  50. package/dist/v1/libs/TinyRadioFm.d.mts +67 -3
  51. package/dist/v1/libs/TinyRadioFm.mjs +239 -123
  52. package/docs/v1/libs/TinyMediaPlayer.md +52 -54
  53. package/docs/v1/libs/TinyRadioFm.md +25 -3
  54. package/package.json +13 -1
@@ -0,0 +1,351 @@
1
+ import { EventEmitter } from 'events';
2
+ import { isValidObj } from '../basics/objChecker.mjs';
3
+ import { browserIs } from '../basics/browserDetector.mjs';
4
+ /**
5
+ * A lightweight debugging utility that wraps console methods and provides event emission.
6
+ * @extends EventEmitter
7
+ */
8
+ class TinyDebugger extends EventEmitter {
9
+ /** @type {Partial<Console>} */
10
+ #logger;
11
+ /** @type {string} */
12
+ #logId;
13
+ /** @type {boolean} */
14
+ #canEmitLogs;
15
+ /** @type {boolean} */
16
+ #debugMode;
17
+ /** @type {boolean} */
18
+ #useLogColors;
19
+ /**
20
+ * Colors (ANSI Escape Codes)
21
+ * @type {Map<string, string>}
22
+ */
23
+ #colorMap = new Map([
24
+ // Log types mapping (for automatic usage)
25
+ ['log', '\x1b[37m'], // White
26
+ ['info', '\x1b[36m'], // Cyan
27
+ ['warn', '\x1b[33m'], // Yellow
28
+ ['error', '\x1b[31m'], // Red
29
+ ['debug', '\x1b[35m'], // Magenta
30
+ ['reset', '\x1b[0m'], // Reset
31
+ // Color names mapping (for manual usage via _color_)
32
+ ['black', '\x1b[30m'],
33
+ ['red', '\x1b[31m'],
34
+ ['green', '\x1b[32m'],
35
+ ['yellow', '\x1b[33m'],
36
+ ['blue', '\x1b[34m'],
37
+ ['magenta', '\x1b[35m'],
38
+ ['cyan', '\x1b[36m'],
39
+ ['white', '\x1b[37m'],
40
+ ['gray', '\x1b[90m'],
41
+ ]);
42
+ /**
43
+ * Prefixes
44
+ * @type {Map<string, string>}
45
+ */
46
+ #prefixMap = new Map([
47
+ ['log', '[_log_LOG_reset_]'],
48
+ ['info', '[_info_INFO_reset_]'],
49
+ ['warn', '[_warn_WARN_reset_]'],
50
+ ['error', '[_error_ERROR_reset_]'],
51
+ ['debug', '[_debug_DEBUG_reset_]'],
52
+ ]);
53
+ /**
54
+ * Creates an instance of TinyDebugger.
55
+ * @param {Object} config - The configuration object.
56
+ * @param {Partial<Console>} config.logger - A custom logger (must implement Console methods).
57
+ * @param {string} config.id - The unique identifier for this debugger instance.
58
+ * @param {boolean} config.debugMode - Whether to enable internal debug logging.
59
+ * @param {boolean} [config.canEmitLogs=false] - Whether to emit debug events to listeners.
60
+ * @param {boolean} [config.useLogColors=false] - Whether to enable log color support.
61
+ * @throws {TypeError} If parameters do not match the required types.
62
+ */
63
+ constructor({ logger, id, debugMode, canEmitLogs = false, useLogColors = false }) {
64
+ super();
65
+ if (!isValidObj(logger)) {
66
+ throw new TypeError('Logger must be an object that implements the Console interface.');
67
+ }
68
+ if (typeof id !== 'string') {
69
+ throw new TypeError('Logger instance id must be a string.');
70
+ }
71
+ if (typeof debugMode !== 'boolean') {
72
+ throw new TypeError('debugMode must be a boolean.');
73
+ }
74
+ if (typeof canEmitLogs !== 'boolean') {
75
+ throw new TypeError('canEmitLogs must be a boolean.');
76
+ }
77
+ if (typeof useLogColors !== 'boolean') {
78
+ throw new TypeError('useLogColors must be a boolean.');
79
+ }
80
+ this.#logId = id;
81
+ this.#logger = logger;
82
+ this.#debugMode = debugMode;
83
+ this.#canEmitLogs = canEmitLogs;
84
+ this.#useLogColors = browserIs() !== 'firefox' ? useLogColors : false;
85
+ this.log('info', `Emit logs of debug mode set to: ${this.#debugMode ? 'ON' : 'OFF'}`);
86
+ this.log('info', 'Custom logger assigned.');
87
+ }
88
+ /**
89
+ * @returns {string} The instance debug id.
90
+ */
91
+ get logId() {
92
+ return this.#logId;
93
+ }
94
+ /**
95
+ * @returns {boolean} Whether event emission is enabled.
96
+ */
97
+ get canEmitLogs() {
98
+ return this.#canEmitLogs;
99
+ }
100
+ /**
101
+ * @returns {boolean} True if log colors mode is enabled.
102
+ */
103
+ get useLogColors() {
104
+ return this.#useLogColors;
105
+ }
106
+ /**
107
+ * @param {boolean} value - Enables or disables log colors mode.
108
+ * @throws {TypeError} If the value is not a boolean.
109
+ */
110
+ set useLogColors(value) {
111
+ if (typeof value !== 'boolean') {
112
+ throw new TypeError('useLogColors must be a boolean.');
113
+ }
114
+ this.#useLogColors = value;
115
+ this.log('info', `Log Colors usage mode set to: ${this.#useLogColors ? 'ON' : 'OFF'}`);
116
+ this.emit('setDebugMode', value);
117
+ }
118
+ /**
119
+ * @returns {boolean} True if debug mode is enabled.
120
+ */
121
+ get debugMode() {
122
+ return this.#debugMode;
123
+ }
124
+ /**
125
+ * @param {boolean} value - Enables or disables debug mode.
126
+ * @throws {TypeError} If the value is not a boolean.
127
+ */
128
+ set debugMode(value) {
129
+ if (typeof value !== 'boolean') {
130
+ throw new TypeError('debugMode must be a boolean.');
131
+ }
132
+ this.#debugMode = value;
133
+ this.log('info', `Debug mode set to: ${this.#debugMode ? 'ON' : 'OFF'}`);
134
+ this.emit('setDebugMode', value);
135
+ }
136
+ /**
137
+ * Adds a new color shortcut.
138
+ * @param {string} id - The shortcut ID (e.g., 'red').
139
+ * @param {string} code - The replacement string (e.g., ANSI code).
140
+ */
141
+ _addLogColor(id, code) {
142
+ this.#colorMap.set(id, code);
143
+ }
144
+ /**
145
+ * Removes a color shortcut.
146
+ * @param {string} id - The shortcut ID to remove.
147
+ */
148
+ _removeLogColor(id) {
149
+ this.#colorMap.delete(id);
150
+ }
151
+ /**
152
+ * Adds a new prefix shortcut.
153
+ * @param {string} id - The shortcut ID (e.g., 'info').
154
+ * @param {string} text - The text to insert (e.g., '[INFO]').
155
+ */
156
+ _addLogPrefix(id, text) {
157
+ this.#prefixMap.set(id, text);
158
+ }
159
+ /**
160
+ * Removes a prefix shortcut.
161
+ * @param {string} id - The shortcut ID to remove.
162
+ */
163
+ _removeLogPrefix(id) {
164
+ this.#prefixMap.delete(id);
165
+ }
166
+ /**
167
+ * Internal method to apply prefix and color replacements.
168
+ * @param {string} text - The text to format.
169
+ * @returns {string} The formatted text.
170
+ */
171
+ #applyFormatting(text) {
172
+ if (typeof text !== 'string')
173
+ return text;
174
+ let result = text;
175
+ // 1. Apply Prefixes first
176
+ for (const [id, value] of this.#prefixMap) {
177
+ const regex = new RegExp(`\\:${id}\\:`, 'g');
178
+ result = result.replace(regex, value);
179
+ }
180
+ // 2. Apply Color shortcuts second
181
+ for (const [id, value] of this.#colorMap) {
182
+ const regex = new RegExp(`\\_${id}\\_`, 'g');
183
+ result = result.replace(regex, this.#useLogColors ? value : '');
184
+ }
185
+ return result;
186
+ }
187
+ /**
188
+ * Clears the console.
189
+ * @returns {void|undefined}
190
+ */
191
+ logClear() {
192
+ if (!this.#debugMode)
193
+ return;
194
+ if (this.#canEmitLogs)
195
+ this.emit('debug:clear');
196
+ return this.#logger.clear ? this.#logger.clear() : console.clear();
197
+ }
198
+ /**
199
+ * Ends the current console group.
200
+ * @returns {void|undefined}
201
+ */
202
+ logGroupEnd() {
203
+ if (!this.#debugMode)
204
+ return;
205
+ if (this.#canEmitLogs)
206
+ this.emit('debug:groupEnd');
207
+ return this.#logger.groupEnd ? this.#logger.groupEnd() : console.groupEnd();
208
+ }
209
+ /**
210
+ * Logs a specific console type with an optional label.
211
+ * @param {'count' | 'countReset' | 'time' | 'timeEnd' | 'profile' | 'profileEnd' | 'timeStamp'} logType - The console method to use.
212
+ * @param {string} [label] - The label to associate with the log.
213
+ * @throws {TypeError} If the specified logType is not supported or label is not a string.
214
+ * @returns {void}
215
+ */
216
+ logLabel(logType, label) {
217
+ if (!this.#debugMode)
218
+ return;
219
+ const validTypes = [
220
+ 'count',
221
+ 'countReset',
222
+ 'time',
223
+ 'timeEnd',
224
+ 'profile',
225
+ 'profileEnd',
226
+ 'timeStamp',
227
+ ];
228
+ if (!validTypes.includes(logType)) {
229
+ throw new TypeError(`Invalid logType. Expected one of: ${validTypes.join(', ')}`);
230
+ }
231
+ if (label !== undefined && typeof label !== 'string') {
232
+ throw new TypeError('The label must be a string.');
233
+ }
234
+ const log = this.#logger[logType] ? this.#logger[logType] : console[logType];
235
+ if (!log)
236
+ throw new TypeError(`The log type "${logType}" is not supported by the provided logger or console.`);
237
+ if (this.#canEmitLogs)
238
+ this.emit('debug:logLabel', logType, label);
239
+ return log(label);
240
+ }
241
+ /**
242
+ * Starts a timer with a label.
243
+ * @param {string} label - The label for the timer.
244
+ * @param {...any} args - Additional arguments for the timer.
245
+ * @throws {TypeError} If label is not a string.
246
+ * @returns {void}
247
+ */
248
+ logTimeLabel(label, ...args) {
249
+ if (!this.#debugMode)
250
+ return;
251
+ if (this.#canEmitLogs)
252
+ this.emit('debug:timeLog', label, ...args);
253
+ return this.#logger.timeLog
254
+ ? this.#logger.timeLog(label, ...args)
255
+ : console.timeLog(label, ...args);
256
+ }
257
+ /**
258
+ * Asserts a condition and logs a message if the condition is false.
259
+ * @param {boolean} condition - The condition to evaluate.
260
+ * @param {...any} args - Arguments to log if the condition is false.
261
+ * @returns {void}
262
+ */
263
+ logAssert(condition, ...args) {
264
+ if (!this.#debugMode)
265
+ return;
266
+ if (this.#canEmitLogs)
267
+ this.emit('debug:assert', condition, ...args);
268
+ return this.#logger.assert
269
+ ? this.#logger.assert(condition, ...args)
270
+ : console.assert(condition, ...args);
271
+ }
272
+ /**
273
+ * Logs an element as a JavaScript object.
274
+ * @param {any} item - The object to inspect.
275
+ * @param {import('util').InspectOptions} [options] - Inspection options.
276
+ * @returns {void}
277
+ */
278
+ logDir(item, options) {
279
+ if (!this.#debugMode)
280
+ return;
281
+ if (this.#canEmitLogs)
282
+ this.emit('debug:dir', item, options);
283
+ return this.#logger.dir ? this.#logger.dir(item, options) : console.dir(item, options);
284
+ }
285
+ /**
286
+ * Displays a table of objects.
287
+ * @param {any} tabularData - The data to be displayed in a table.
288
+ * @param {string[]} [properties] - The properties (columns) to display.
289
+ * @throws {TypeError} If properties is provided but is not an array of strings.
290
+ * @returns {void}
291
+ */
292
+ logTable(tabularData, properties) {
293
+ if (!this.#debugMode)
294
+ return;
295
+ if (properties !== undefined) {
296
+ if (!Array.isArray(properties) || !properties.every((p) => typeof p === 'string')) {
297
+ throw new TypeError('Properties must be an array of strings.');
298
+ }
299
+ }
300
+ if (this.#canEmitLogs)
301
+ this.emit('debug:table', tabularData, properties);
302
+ return this.#logger.table
303
+ ? this.#logger.table(tabularData, properties)
304
+ : console.table(tabularData, properties);
305
+ }
306
+ /**
307
+ * Internal helper to handle debug logging.
308
+ * @param {'log' | 'info' | 'warn' | 'error' | 'debug' | 'dirxml' | 'group' | 'groupCollapsed' | 'trace'} logType - The console method to use.
309
+ * @param {string} message - The message to log.
310
+ * @param {...any} args - Additional arguments to pass to the logger.
311
+ * @throws {TypeError} If logType is invalid or message is not a string.
312
+ * @returns {void}
313
+ */
314
+ log(logType, message, ...args) {
315
+ if (!this.#debugMode)
316
+ return;
317
+ const validTypes = [
318
+ 'log',
319
+ 'info',
320
+ 'warn',
321
+ 'error',
322
+ 'debug',
323
+ 'dirxml',
324
+ 'group',
325
+ 'groupCollapsed',
326
+ 'trace',
327
+ ];
328
+ if (!validTypes.includes(logType)) {
329
+ throw new TypeError(`Invalid logType. Expected one of: ${validTypes.join(', ')}`);
330
+ }
331
+ if (typeof message !== 'string') {
332
+ throw new TypeError('The message must be a string.');
333
+ }
334
+ let prefix = this.#logId;
335
+ let formattedMessage = message;
336
+ prefix = this.#applyFormatting(prefix);
337
+ formattedMessage = this.#applyFormatting(formattedMessage);
338
+ const logFunc = this.#logger[logType] ? this.#logger[logType] : console[logType];
339
+ if (logFunc) {
340
+ if (this.#canEmitLogs)
341
+ this.emit('debug:log', prefix, formattedMessage, ...args);
342
+ return logFunc(prefix, formattedMessage, ...args);
343
+ }
344
+ else {
345
+ if (this.#canEmitLogs)
346
+ this.emit('debug:log', prefix, formattedMessage, ...args);
347
+ return console.log(prefix, formattedMessage, ...args);
348
+ }
349
+ }
350
+ }
351
+ export default TinyDebugger;
@@ -22,6 +22,12 @@ class HtmlAudioAdapter extends index.BaseMediaAdapter {
22
22
  /** @type {boolean} */
23
23
  #destroyed = false;
24
24
 
25
+ /** @type {boolean} */
26
+ #isPaused = false;
27
+
28
+ /** @type {boolean} */
29
+ #isEnded = false;
30
+
25
31
  get id() {
26
32
  return 'html5Audio';
27
33
  }
@@ -63,9 +69,21 @@ class HtmlAudioAdapter extends index.BaseMediaAdapter {
63
69
  constructor() {
64
70
  super();
65
71
 
66
- this.#audioElement.addEventListener('play', () => this.emit('play'));
67
- this.#audioElement.addEventListener('pause', () => this.emit('pause'));
68
- this.#audioElement.addEventListener('ended', () => this.emit('ended'));
72
+ this.#audioElement.addEventListener('play', () => {
73
+ this.#isPaused = false;
74
+ this.#isEnded = false;
75
+ this.emit('play');
76
+ });
77
+ this.#audioElement.addEventListener('pause', () => {
78
+ this.#isPaused = true;
79
+ this.#isEnded = false;
80
+ this.emit('pause');
81
+ });
82
+ this.#audioElement.addEventListener('ended', () => {
83
+ this.#isPaused = false;
84
+ this.#isEnded = true;
85
+ this.emit('ended');
86
+ });
69
87
  this.#audioElement.addEventListener('timeupdate', () => {
70
88
  this.emit('timeupdate', this.getTimeData());
71
89
  });
@@ -86,6 +104,24 @@ class HtmlAudioAdapter extends index.BaseMediaAdapter {
86
104
  return true;
87
105
  }
88
106
 
107
+ /**
108
+ * Checks whether the media adapter is paused.
109
+ * @returns {boolean} True if the adapter is ready, false otherwise.
110
+ */
111
+ isPaused() {
112
+ checkDestroy(this.#destroyed);
113
+ return this.#isPaused;
114
+ }
115
+
116
+ /**
117
+ * Checks whether the media adapter is ended.
118
+ * @returns {boolean} True if the adapter is ready, false otherwise.
119
+ */
120
+ isEnded() {
121
+ checkDestroy(this.#destroyed);
122
+ return this.#isEnded;
123
+ }
124
+
89
125
  /**
90
126
  * Asynchronously waits until the content media adapter is fully initialized and ready.
91
127
  * @returns {Promise<void>} A promise that resolves once the adapter is ready.
@@ -192,6 +228,33 @@ class HtmlAudioAdapter extends index.BaseMediaAdapter {
192
228
  this.#audioElement.currentTime = currentTime;
193
229
  }
194
230
 
231
+ /**
232
+ * Checks whether the player is currently muted.
233
+ * @returns {boolean} True if muted, false otherwise.
234
+ */
235
+ isMuted() {
236
+ checkDestroy(this.#destroyed);
237
+ return this.#audioElement.muted;
238
+ }
239
+
240
+ /**
241
+ * Mutes the current playback.
242
+ * @returns {Promise<void>}
243
+ */
244
+ async mute() {
245
+ checkDestroy(this.#destroyed);
246
+ this.#audioElement.muted = true;
247
+ }
248
+
249
+ /**
250
+ * Unmutes the current playback.
251
+ * @returns {Promise<void>}
252
+ */
253
+ async unMute() {
254
+ checkDestroy(this.#destroyed);
255
+ this.#audioElement.muted = false;
256
+ }
257
+
195
258
  /**
196
259
  * Gets the current playback time.
197
260
  * @returns {number} The current time in milliseconds.
@@ -37,6 +37,16 @@ declare class HtmlAudioAdapter extends BaseMediaAdapter {
37
37
  * @returns {boolean} True if the adapter is ready, false otherwise.
38
38
  */
39
39
  isReady(): boolean;
40
+ /**
41
+ * Checks whether the media adapter is paused.
42
+ * @returns {boolean} True if the adapter is ready, false otherwise.
43
+ */
44
+ isPaused(): boolean;
45
+ /**
46
+ * Checks whether the media adapter is ended.
47
+ * @returns {boolean} True if the adapter is ready, false otherwise.
48
+ */
49
+ isEnded(): boolean;
40
50
  /**
41
51
  * Asynchronously waits until the content media adapter is fully initialized and ready.
42
52
  * @returns {Promise<void>} A promise that resolves once the adapter is ready.
@@ -85,6 +95,21 @@ declare class HtmlAudioAdapter extends BaseMediaAdapter {
85
95
  * @throws {TypeError} If timeMs is not a number.
86
96
  */
87
97
  seek(timeMs: number): Promise<void>;
98
+ /**
99
+ * Checks whether the player is currently muted.
100
+ * @returns {boolean} True if muted, false otherwise.
101
+ */
102
+ isMuted(): boolean;
103
+ /**
104
+ * Mutes the current playback.
105
+ * @returns {Promise<void>}
106
+ */
107
+ mute(): Promise<void>;
108
+ /**
109
+ * Unmutes the current playback.
110
+ * @returns {Promise<void>}
111
+ */
112
+ unMute(): Promise<void>;
88
113
  /**
89
114
  * Gets the current playback time.
90
115
  * @returns {number} The current time in milliseconds.
@@ -15,6 +15,10 @@ const checkDestroy = createCheckDestroyed('HtmlAudioAdapter');
15
15
  class HtmlAudioAdapter extends BaseMediaAdapter {
16
16
  /** @type {boolean} */
17
17
  #destroyed = false;
18
+ /** @type {boolean} */
19
+ #isPaused = false;
20
+ /** @type {boolean} */
21
+ #isEnded = false;
18
22
  get id() {
19
23
  return 'html5Audio';
20
24
  }
@@ -49,9 +53,21 @@ class HtmlAudioAdapter extends BaseMediaAdapter {
49
53
  */
50
54
  constructor() {
51
55
  super();
52
- this.#audioElement.addEventListener('play', () => this.emit('play'));
53
- this.#audioElement.addEventListener('pause', () => this.emit('pause'));
54
- this.#audioElement.addEventListener('ended', () => this.emit('ended'));
56
+ this.#audioElement.addEventListener('play', () => {
57
+ this.#isPaused = false;
58
+ this.#isEnded = false;
59
+ this.emit('play');
60
+ });
61
+ this.#audioElement.addEventListener('pause', () => {
62
+ this.#isPaused = true;
63
+ this.#isEnded = false;
64
+ this.emit('pause');
65
+ });
66
+ this.#audioElement.addEventListener('ended', () => {
67
+ this.#isPaused = false;
68
+ this.#isEnded = true;
69
+ this.emit('ended');
70
+ });
55
71
  this.#audioElement.addEventListener('timeupdate', () => {
56
72
  this.emit('timeupdate', this.getTimeData());
57
73
  });
@@ -70,6 +86,22 @@ class HtmlAudioAdapter extends BaseMediaAdapter {
70
86
  checkDestroy(this.#destroyed);
71
87
  return true;
72
88
  }
89
+ /**
90
+ * Checks whether the media adapter is paused.
91
+ * @returns {boolean} True if the adapter is ready, false otherwise.
92
+ */
93
+ isPaused() {
94
+ checkDestroy(this.#destroyed);
95
+ return this.#isPaused;
96
+ }
97
+ /**
98
+ * Checks whether the media adapter is ended.
99
+ * @returns {boolean} True if the adapter is ready, false otherwise.
100
+ */
101
+ isEnded() {
102
+ checkDestroy(this.#destroyed);
103
+ return this.#isEnded;
104
+ }
73
105
  /**
74
106
  * Asynchronously waits until the content media adapter is fully initialized and ready.
75
107
  * @returns {Promise<void>} A promise that resolves once the adapter is ready.
@@ -165,6 +197,30 @@ class HtmlAudioAdapter extends BaseMediaAdapter {
165
197
  const currentTime = timeMs / 1000;
166
198
  this.#audioElement.currentTime = currentTime;
167
199
  }
200
+ /**
201
+ * Checks whether the player is currently muted.
202
+ * @returns {boolean} True if muted, false otherwise.
203
+ */
204
+ isMuted() {
205
+ checkDestroy(this.#destroyed);
206
+ return this.#audioElement.muted;
207
+ }
208
+ /**
209
+ * Mutes the current playback.
210
+ * @returns {Promise<void>}
211
+ */
212
+ async mute() {
213
+ checkDestroy(this.#destroyed);
214
+ this.#audioElement.muted = true;
215
+ }
216
+ /**
217
+ * Unmutes the current playback.
218
+ * @returns {Promise<void>}
219
+ */
220
+ async unMute() {
221
+ checkDestroy(this.#destroyed);
222
+ this.#audioElement.muted = false;
223
+ }
168
224
  /**
169
225
  * Gets the current playback time.
170
226
  * @returns {number} The current time in milliseconds.
@@ -22,6 +22,12 @@ class HtmlVideoAdapter extends index.BaseMediaAdapter {
22
22
  /** @type {boolean} */
23
23
  #destroyed = false;
24
24
 
25
+ /** @type {boolean} */
26
+ #isPaused = false;
27
+
28
+ /** @type {boolean} */
29
+ #isEnded = false;
30
+
25
31
  get id() {
26
32
  return 'html5Video';
27
33
  }
@@ -60,9 +66,21 @@ class HtmlVideoAdapter extends index.BaseMediaAdapter {
60
66
  constructor() {
61
67
  super();
62
68
 
63
- this.#videoElement.addEventListener('play', () => this.emit('play'));
64
- this.#videoElement.addEventListener('pause', () => this.emit('pause'));
65
- this.#videoElement.addEventListener('ended', () => this.emit('ended'));
69
+ this.#videoElement.addEventListener('play', () => {
70
+ this.#isPaused = false;
71
+ this.#isEnded = false;
72
+ this.emit('play');
73
+ });
74
+ this.#videoElement.addEventListener('pause', () => {
75
+ this.#isPaused = true;
76
+ this.#isEnded = false;
77
+ this.emit('pause');
78
+ });
79
+ this.#videoElement.addEventListener('ended', () => {
80
+ this.#isPaused = false;
81
+ this.#isEnded = true;
82
+ this.emit('ended');
83
+ });
66
84
  this.#videoElement.addEventListener('timeupdate', () => {
67
85
  this.emit('timeupdate', this.getTimeData());
68
86
  });
@@ -83,6 +101,24 @@ class HtmlVideoAdapter extends index.BaseMediaAdapter {
83
101
  return true;
84
102
  }
85
103
 
104
+ /**
105
+ * Checks whether the media adapter is paused.
106
+ * @returns {boolean} True if the adapter is ready, false otherwise.
107
+ */
108
+ isPaused() {
109
+ checkDestroy(this.#destroyed);
110
+ return this.#isPaused;
111
+ }
112
+
113
+ /**
114
+ * Checks whether the media adapter is ended.
115
+ * @returns {boolean} True if the adapter is ready, false otherwise.
116
+ */
117
+ isEnded() {
118
+ checkDestroy(this.#destroyed);
119
+ return this.#isEnded;
120
+ }
121
+
86
122
  /**
87
123
  * Asynchronously waits until the content media adapter is fully initialized and ready.
88
124
  * @returns {Promise<void>} A promise that resolves once the adapter is ready.
@@ -189,6 +225,33 @@ class HtmlVideoAdapter extends index.BaseMediaAdapter {
189
225
  this.#videoElement.currentTime = currentTime;
190
226
  }
191
227
 
228
+ /**
229
+ * Checks whether the player is currently muted.
230
+ * @returns {boolean} True if muted, false otherwise.
231
+ */
232
+ isMuted() {
233
+ checkDestroy(this.#destroyed);
234
+ return this.#videoElement.muted;
235
+ }
236
+
237
+ /**
238
+ * Mutes the current playback.
239
+ * @returns {Promise<void>}
240
+ */
241
+ async mute() {
242
+ checkDestroy(this.#destroyed);
243
+ this.#videoElement.muted = true;
244
+ }
245
+
246
+ /**
247
+ * Unmutes the current playback.
248
+ * @returns {Promise<void>}
249
+ */
250
+ async unMute() {
251
+ checkDestroy(this.#destroyed);
252
+ this.#videoElement.muted = false;
253
+ }
254
+
192
255
  /**
193
256
  * Gets the current playback time.
194
257
  * @returns {number} The current time in milliseconds.