@ceeblue/web-utils 5.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codecov.yml +21 -0
- package/dist/web-utils.d.ts +74 -12
- package/dist/web-utils.js +176 -65
- package/dist/web-utils.js.map +1 -1
- package/dist/web-utils.min.js +1 -1
- package/dist/web-utils.min.js.map +1 -1
- package/package.json +8 -3
- package/vitest.config.ts +21 -0
package/.codecov.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
coverage:
|
|
2
|
+
status:
|
|
3
|
+
project:
|
|
4
|
+
default:
|
|
5
|
+
target: 90%
|
|
6
|
+
threshold: 10%
|
|
7
|
+
patch:
|
|
8
|
+
default:
|
|
9
|
+
target: 90%
|
|
10
|
+
threshold: 10%
|
|
11
|
+
|
|
12
|
+
comment:
|
|
13
|
+
layout: "reach, diff, flags, files"
|
|
14
|
+
behavior: default
|
|
15
|
+
require_changes: true
|
|
16
|
+
|
|
17
|
+
ignore:
|
|
18
|
+
- "**/*.test.ts"
|
|
19
|
+
- "**/*.spec.ts"
|
|
20
|
+
- "**/__tests__/**"
|
|
21
|
+
- "**/__mocks__/**"
|
package/dist/web-utils.d.ts
CHANGED
|
@@ -273,6 +273,41 @@ declare class ByteRate {
|
|
|
273
273
|
private updateSamples;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Parameters of a key system for encrypted streams (DRM)
|
|
278
|
+
*
|
|
279
|
+
* If the key system is a string, it's the URL of the license server.
|
|
280
|
+
*
|
|
281
|
+
* If the key system is an object, it's a key system configuration with more parameters.
|
|
282
|
+
*/
|
|
283
|
+
type KeySystem = string | {
|
|
284
|
+
/**
|
|
285
|
+
* The license server URL
|
|
286
|
+
*/
|
|
287
|
+
licenseUrl: string;
|
|
288
|
+
/**
|
|
289
|
+
* The certificate URL if needed (for FairPlay)
|
|
290
|
+
*
|
|
291
|
+
* Or directly the certificate
|
|
292
|
+
*/
|
|
293
|
+
certificate?: string | Uint8Array;
|
|
294
|
+
/**
|
|
295
|
+
* The additional HTTP headers to send to the license server
|
|
296
|
+
*/
|
|
297
|
+
headers?: Record<string, string>;
|
|
298
|
+
/**
|
|
299
|
+
* Audio robustness level
|
|
300
|
+
*
|
|
301
|
+
* A list of robustness levels, prioritized by the order of the array.
|
|
302
|
+
*/
|
|
303
|
+
audioRobustness?: string[];
|
|
304
|
+
/**
|
|
305
|
+
* Video robustness level
|
|
306
|
+
*
|
|
307
|
+
* A list of robustness levels, prioritized by the order of the array.
|
|
308
|
+
*/
|
|
309
|
+
videoRobustness?: string[];
|
|
310
|
+
};
|
|
276
311
|
/**
|
|
277
312
|
* Parameters of connections
|
|
278
313
|
*/
|
|
@@ -287,7 +322,7 @@ type Params = {
|
|
|
287
322
|
* If `endPoint` is a complete URL and `streamName` is not provided, {@link buildURL} will set this parameter automatically
|
|
288
323
|
* using the second part of the URL's path (the first part being the protocol name), or the first path if no other part exists.
|
|
289
324
|
*/
|
|
290
|
-
streamName
|
|
325
|
+
streamName?: string;
|
|
291
326
|
/**
|
|
292
327
|
* Optional access token to use to join a private stream
|
|
293
328
|
*/
|
|
@@ -296,6 +331,11 @@ type Params = {
|
|
|
296
331
|
* iceServer to use while connecting to a WebRTC stream
|
|
297
332
|
*/
|
|
298
333
|
iceServer?: RTCIceServer;
|
|
334
|
+
/**
|
|
335
|
+
* Map of keys to content protection settings for encrypted streams
|
|
336
|
+
* The key can be "com.apple.fps" for example for FairPlay
|
|
337
|
+
*/
|
|
338
|
+
contentProtection?: Record<string, KeySystem>;
|
|
299
339
|
/**
|
|
300
340
|
* Optional media extension (mp4, flv, ts, rts), usefull for protocol like WebRTS which supports different container type.
|
|
301
341
|
* When not set, it's also an output parameter for {@link defineMediaExt} to indicate what is the media type selected
|
|
@@ -337,13 +377,14 @@ declare function defineMediaExt(type: Type, params: Params): void;
|
|
|
337
377
|
*/
|
|
338
378
|
declare function buildURL(type: Type, params: Params, protocol?: string): URL;
|
|
339
379
|
|
|
380
|
+
type Connect_KeySystem = KeySystem;
|
|
340
381
|
type Connect_Params = Params;
|
|
341
382
|
type Connect_Type = Type;
|
|
342
383
|
declare const Connect_Type: typeof Type;
|
|
343
384
|
declare const Connect_buildURL: typeof buildURL;
|
|
344
385
|
declare const Connect_defineMediaExt: typeof defineMediaExt;
|
|
345
386
|
declare namespace Connect {
|
|
346
|
-
export { type Connect_Params as Params, Connect_Type as Type, Connect_buildURL as buildURL, Connect_defineMediaExt as defineMediaExt };
|
|
387
|
+
export { type Connect_KeySystem as KeySystem, type Connect_Params as Params, Connect_Type as Type, Connect_buildURL as buildURL, Connect_defineMediaExt as defineMediaExt };
|
|
347
388
|
}
|
|
348
389
|
|
|
349
390
|
/**
|
|
@@ -776,13 +817,22 @@ declare const SDP: {
|
|
|
776
817
|
*/
|
|
777
818
|
declare const EMPTY_FUNCTION: () => void;
|
|
778
819
|
/**
|
|
779
|
-
*
|
|
820
|
+
* Returns an efficient timestamp in milliseconds elapsed since {@link performance.timeOrigin},
|
|
821
|
+
* representing the start of the current JavaScript execution context.
|
|
822
|
+
*
|
|
823
|
+
* Note: Each Web Worker runs in a separate JS context, so timestamps
|
|
824
|
+
* are not directly comparable between different workers. Use {@link unixTime}
|
|
825
|
+
* for comparable timestamps across different Web Workers.
|
|
780
826
|
*/
|
|
781
827
|
declare function time(): number;
|
|
782
828
|
/**
|
|
783
|
-
*
|
|
829
|
+
* Returns an efficient Unix timestamp in milliseconds.
|
|
830
|
+
*
|
|
831
|
+
* Unix timestamps are universally comparable across different JavaScript
|
|
832
|
+
* contexts (e.g., Web Workers), as they reference the number of milliseconds
|
|
833
|
+
* elapsed since January 1, 1970 (UNIX epoch).
|
|
784
834
|
*/
|
|
785
|
-
declare function
|
|
835
|
+
declare function unixTime(): number;
|
|
786
836
|
/**
|
|
787
837
|
* Parse query and returns it in an easy-to-use Javascript object form
|
|
788
838
|
* @param urlOrQueryOrSearch string, url, or searchParams containing query. If not set it uses `location.search` to determinate query.
|
|
@@ -841,14 +891,24 @@ declare function safePromise<T>(timeout: number, promise: Promise<T>): Promise<u
|
|
|
841
891
|
*/
|
|
842
892
|
declare function sleep(ms: number): Promise<unknown>;
|
|
843
893
|
/**
|
|
844
|
-
* Test equality between two value whatever their type, array included
|
|
894
|
+
* Test equality between two value whatever their type, object and array included
|
|
895
|
+
*/
|
|
896
|
+
declare function equal(a: any, b: any, seen?: WeakMap<WeakKey, any>): boolean;
|
|
897
|
+
/**
|
|
898
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
845
899
|
*/
|
|
846
|
-
declare function
|
|
900
|
+
declare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response & {
|
|
901
|
+
error?: string;
|
|
902
|
+
}>;
|
|
847
903
|
/**
|
|
848
|
-
*
|
|
849
|
-
*
|
|
904
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
905
|
+
* Also measure the rtt of fetching and returns it in the property Response.rtt (guaranteed to be ≥ 1),
|
|
906
|
+
* supports subtracting server processing time using either the Response-Delay or CMSD-rd header when available
|
|
850
907
|
*/
|
|
851
|
-
declare function
|
|
908
|
+
declare function fetchWithRTT(input: RequestInfo | URL, init?: RequestInit): Promise<Response & {
|
|
909
|
+
rtt: number;
|
|
910
|
+
error?: string;
|
|
911
|
+
}>;
|
|
852
912
|
/**
|
|
853
913
|
* Get Extension part from path
|
|
854
914
|
* @param path path to parse
|
|
@@ -892,6 +952,7 @@ declare function trimEnd(value: string, chars?: string): string;
|
|
|
892
952
|
declare const Util_EMPTY_FUNCTION: typeof EMPTY_FUNCTION;
|
|
893
953
|
declare const Util_equal: typeof equal;
|
|
894
954
|
declare const Util_fetch: typeof fetch;
|
|
955
|
+
declare const Util_fetchWithRTT: typeof fetchWithRTT;
|
|
895
956
|
declare const Util_getBaseFile: typeof getBaseFile;
|
|
896
957
|
declare const Util_getExtension: typeof getExtension;
|
|
897
958
|
declare const Util_getFile: typeof getFile;
|
|
@@ -902,13 +963,13 @@ declare const Util_safePromise: typeof safePromise;
|
|
|
902
963
|
declare const Util_sleep: typeof sleep;
|
|
903
964
|
declare const Util_stringify: typeof stringify;
|
|
904
965
|
declare const Util_time: typeof time;
|
|
905
|
-
declare const Util_timeOrigin: typeof timeOrigin;
|
|
906
966
|
declare const Util_toBin: typeof toBin;
|
|
907
967
|
declare const Util_trim: typeof trim;
|
|
908
968
|
declare const Util_trimEnd: typeof trimEnd;
|
|
909
969
|
declare const Util_trimStart: typeof trimStart;
|
|
970
|
+
declare const Util_unixTime: typeof unixTime;
|
|
910
971
|
declare namespace Util {
|
|
911
|
-
export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_getBaseFile as getBaseFile, Util_getExtension as getExtension, Util_getFile as getFile, Util_iterableEntries as iterableEntries, Util_objectFrom as objectFrom, Util_options as options, Util_safePromise as safePromise, Util_sleep as sleep, Util_stringify as stringify, Util_time as time,
|
|
972
|
+
export { Util_EMPTY_FUNCTION as EMPTY_FUNCTION, Util_equal as equal, Util_fetch as fetch, Util_fetchWithRTT as fetchWithRTT, Util_getBaseFile as getBaseFile, Util_getExtension as getExtension, Util_getFile as getFile, Util_iterableEntries as iterableEntries, Util_objectFrom as objectFrom, Util_options as options, Util_safePromise as safePromise, Util_sleep as sleep, Util_stringify as stringify, Util_time as time, Util_toBin as toBin, Util_trim as trim, Util_trimEnd as trimEnd, Util_trimStart as trimStart, Util_unixTime as unixTime };
|
|
912
973
|
}
|
|
913
974
|
|
|
914
975
|
/**
|
|
@@ -1183,6 +1244,7 @@ declare class UIMetrics {
|
|
|
1183
1244
|
private _legendFontSize;
|
|
1184
1245
|
private _stepSize;
|
|
1185
1246
|
private _ranges;
|
|
1247
|
+
private _mouseX?;
|
|
1186
1248
|
constructor(ui: HTMLElement);
|
|
1187
1249
|
/**
|
|
1188
1250
|
* Reset metrics stats, essentially rescaling the metrics
|
package/dist/web-utils.js
CHANGED
|
@@ -164,16 +164,25 @@ const _perf = performance; // to increase x10 now performance!
|
|
|
164
164
|
*/
|
|
165
165
|
const EMPTY_FUNCTION = () => { };
|
|
166
166
|
/**
|
|
167
|
-
*
|
|
167
|
+
* Returns an efficient timestamp in milliseconds elapsed since {@link performance.timeOrigin},
|
|
168
|
+
* representing the start of the current JavaScript execution context.
|
|
169
|
+
*
|
|
170
|
+
* Note: Each Web Worker runs in a separate JS context, so timestamps
|
|
171
|
+
* are not directly comparable between different workers. Use {@link unixTime}
|
|
172
|
+
* for comparable timestamps across different Web Workers.
|
|
168
173
|
*/
|
|
169
174
|
function time() {
|
|
170
175
|
return Math.floor(_perf.now());
|
|
171
176
|
}
|
|
172
177
|
/**
|
|
173
|
-
*
|
|
178
|
+
* Returns an efficient Unix timestamp in milliseconds.
|
|
179
|
+
*
|
|
180
|
+
* Unix timestamps are universally comparable across different JavaScript
|
|
181
|
+
* contexts (e.g., Web Workers), as they reference the number of milliseconds
|
|
182
|
+
* elapsed since January 1, 1970 (UNIX epoch).
|
|
174
183
|
*/
|
|
175
|
-
function
|
|
176
|
-
return Math.floor(_perf.
|
|
184
|
+
function unixTime() {
|
|
185
|
+
return Math.floor(_perf.timeOrigin + _perf.now());
|
|
177
186
|
}
|
|
178
187
|
/**
|
|
179
188
|
* Parse query and returns it in an easy-to-use Javascript object form
|
|
@@ -362,52 +371,136 @@ function safePromise(timeout, promise) {
|
|
|
362
371
|
* Wait in milliseconds, requires a call with await keyword!
|
|
363
372
|
*/
|
|
364
373
|
function sleep(ms) {
|
|
365
|
-
return
|
|
366
|
-
|
|
374
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
375
|
+
return new Promise(resolve => {
|
|
376
|
+
setTimeout(resolve, ms);
|
|
377
|
+
});
|
|
367
378
|
});
|
|
368
379
|
}
|
|
369
380
|
/**
|
|
370
|
-
* Test equality between two value whatever their type, array included
|
|
381
|
+
* Test equality between two value whatever their type, object and array included
|
|
371
382
|
*/
|
|
372
|
-
function equal(a, b) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
// both primitive (null and undefined included)
|
|
378
|
-
return a === b;
|
|
383
|
+
function equal(a, b, seen = new WeakMap()) {
|
|
384
|
+
// 1. Check primitve identiy or NaN
|
|
385
|
+
if (a === b) {
|
|
386
|
+
return true;
|
|
379
387
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
388
|
+
if (Number.isNaN(a) && Number.isNaN(b)) {
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
// 2. Check the both are complexe object
|
|
392
|
+
if (Object(a) !== a || Object(b) !== b) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
// 3. Catch circular reference
|
|
396
|
+
if (seen.has(a)) {
|
|
397
|
+
return seen.get(a) === b;
|
|
398
|
+
}
|
|
399
|
+
seen.set(a, b);
|
|
400
|
+
// 4. Check « toStringTag » (Date, RegExp, Map, Set…)
|
|
401
|
+
const tagA = Object.prototype.toString.call(a);
|
|
402
|
+
if (tagA !== Object.prototype.toString.call(b)) {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
// 5. Special Case
|
|
406
|
+
switch (tagA) {
|
|
407
|
+
case '[object Date]':
|
|
408
|
+
return a.getTime() === b.getTime();
|
|
409
|
+
case '[object RegExp]':
|
|
410
|
+
return a.source === b.source && a.flags === b.flags;
|
|
411
|
+
case '[object Set]':
|
|
412
|
+
case '[object Map]': {
|
|
413
|
+
if (a.size !== b.size) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
const aKeys = a.keys();
|
|
417
|
+
const bKeys = a.keys();
|
|
418
|
+
const aValues = a.values();
|
|
419
|
+
const bValues = b.values();
|
|
420
|
+
let aKey;
|
|
421
|
+
while (!(aKey = aKeys.next()).done) {
|
|
422
|
+
if (!equal(aKey.value, bKeys.next().value)) {
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
const aValue = aValues.next().value;
|
|
426
|
+
const bValue = bValues.next().value;
|
|
427
|
+
if (aValue !== aKey && !equal(aValue, bValue)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return true;
|
|
384
432
|
}
|
|
385
|
-
|
|
433
|
+
}
|
|
434
|
+
// 6. Arrays
|
|
435
|
+
if (Array.isArray(a)) {
|
|
436
|
+
if (!Array.isArray(b) || a.length !== b.length) {
|
|
386
437
|
return false;
|
|
387
438
|
}
|
|
388
|
-
for (let i = 0; i
|
|
389
|
-
if (a[i]
|
|
439
|
+
for (let i = 0; i < a.length; i++) {
|
|
440
|
+
if (!equal(a[i], b[i], seen)) {
|
|
390
441
|
return false;
|
|
391
442
|
}
|
|
392
443
|
}
|
|
393
444
|
return true;
|
|
394
445
|
}
|
|
395
|
-
|
|
446
|
+
// 7. Generic object : keys + symbols
|
|
447
|
+
const keysA = [...Object.keys(a), ...Object.getOwnPropertySymbols(a)];
|
|
448
|
+
if (keysA.length !== Object.keys(b).length + Object.getOwnPropertySymbols(b).length) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
for (const key of keysA) {
|
|
452
|
+
if (!equal(a[key], b[key], seen)) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return true;
|
|
396
457
|
}
|
|
397
458
|
/**
|
|
398
|
-
*
|
|
399
|
-
* - throw an string exception if response code is not 200 with the text of the response or uses statusText
|
|
459
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
400
460
|
*/
|
|
401
461
|
function fetch(input, init) {
|
|
402
462
|
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
-
const response = yield self.fetch(input, init);
|
|
404
|
-
if (response.
|
|
405
|
-
let error;
|
|
463
|
+
const response = (yield self.fetch(input, init));
|
|
464
|
+
if (!response.ok) {
|
|
406
465
|
if (response.body) {
|
|
407
|
-
error = yield response.text();
|
|
466
|
+
response.error = yield response.text();
|
|
467
|
+
}
|
|
468
|
+
if (!response.error) {
|
|
469
|
+
response.error = response.statusText || response.status.toString() || 'Unknown error';
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return response;
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Fetch help method adding an explicit error property when Response is NOK, with the more accurate textual error inside
|
|
477
|
+
* Also measure the rtt of fetching and returns it in the property Response.rtt (guaranteed to be ≥ 1),
|
|
478
|
+
* supports subtracting server processing time using either the Response-Delay or CMSD-rd header when available
|
|
479
|
+
*/
|
|
480
|
+
function fetchWithRTT(input, init) {
|
|
481
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
482
|
+
// a first HEAD request to try to ensure a connection
|
|
483
|
+
yield fetch(input, Object.assign(Object.assign({}, init), { method: 'HEAD' }));
|
|
484
|
+
// the true request
|
|
485
|
+
const startTime = time();
|
|
486
|
+
const response = (yield fetch(input, init));
|
|
487
|
+
response.rtt = time() - startTime;
|
|
488
|
+
// remove the ResponseDelay if indicated by the server
|
|
489
|
+
let responseDelay = Number(response.headers.get('Response-Delay')) || 0;
|
|
490
|
+
if (!responseDelay) {
|
|
491
|
+
// search if we have a CMSD info?
|
|
492
|
+
// cmsd-dynamic "fly";rd=1
|
|
493
|
+
const cmsd = response.headers.get('cmsd-dynamic');
|
|
494
|
+
if (cmsd) {
|
|
495
|
+
for (const param of cmsd.split(';')) {
|
|
496
|
+
const [name, value] = param.split('=');
|
|
497
|
+
if (name.trim().toLowerCase() === 'rd') {
|
|
498
|
+
responseDelay = Number(value) || responseDelay;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
408
501
|
}
|
|
409
|
-
throw (error || response.statusText || response.status).toString();
|
|
410
502
|
}
|
|
503
|
+
response.rtt = Math.max(1, response.rtt - responseDelay);
|
|
411
504
|
return response;
|
|
412
505
|
});
|
|
413
506
|
}
|
|
@@ -491,7 +584,7 @@ function trimEnd(value, chars = ' ') {
|
|
|
491
584
|
--i;
|
|
492
585
|
}
|
|
493
586
|
return value.substring(0, i);
|
|
494
|
-
}var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,getBaseFile:getBaseFile,getExtension:getExtension,getFile:getFile,iterableEntries:iterableEntries,objectFrom:objectFrom,options:options,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,
|
|
587
|
+
}var Util=/*#__PURE__*/Object.freeze({__proto__:null,EMPTY_FUNCTION:EMPTY_FUNCTION,equal:equal,fetch:fetch,fetchWithRTT:fetchWithRTT,getBaseFile:getBaseFile,getExtension:getExtension,getFile:getFile,iterableEntries:iterableEntries,objectFrom:objectFrom,options:options,safePromise:safePromise,sleep:sleep,stringify:stringify,time:time,toBin:toBin,trim:trim,trimEnd:trimEnd,trimStart:trimStart,unixTime:unixTime});/**
|
|
495
588
|
* Copyright 2024 Ceeblue B.V.
|
|
496
589
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
497
590
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
@@ -1032,6 +1125,8 @@ class NetAddress {
|
|
|
1032
1125
|
* console.log(NetAddress.fixProtocol('wss','http://domain/path')) // 'ws://domain/path'
|
|
1033
1126
|
*/
|
|
1034
1127
|
static fixProtocol(protocol, address) {
|
|
1128
|
+
// Remove leading slashes for absolute pathes!
|
|
1129
|
+
address = address.replace(/^[\/]+/, '');
|
|
1035
1130
|
const found = address.indexOf('://');
|
|
1036
1131
|
// isolate protocol is present in address
|
|
1037
1132
|
if (found >= 0) {
|
|
@@ -1118,14 +1213,14 @@ class NetAddress {
|
|
|
1118
1213
|
this._host = address;
|
|
1119
1214
|
this._domain = address;
|
|
1120
1215
|
this._port = defaultPort;
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1216
|
+
const domainPortMatch = this._host.match(/^(?:\[([0-9a-fA-F:]+)\]|([^:/?#]+))(?::(\d+))?(?=[/#?]|$)/);
|
|
1217
|
+
if (domainPortMatch) {
|
|
1218
|
+
this._domain = domainPortMatch[1] || domainPortMatch[2];
|
|
1219
|
+
if (domainPortMatch[3]) {
|
|
1220
|
+
const port = parseInt(domainPortMatch[3]);
|
|
1221
|
+
if (port >= 0 && port <= 0xffff) {
|
|
1222
|
+
this._port = port;
|
|
1223
|
+
}
|
|
1129
1224
|
}
|
|
1130
1225
|
}
|
|
1131
1226
|
}
|
|
@@ -1156,7 +1251,21 @@ var Type;
|
|
|
1156
1251
|
* @param params The parameters for which the media extension is to be defined
|
|
1157
1252
|
*/
|
|
1158
1253
|
function defineMediaExt(type, params) {
|
|
1254
|
+
var _a;
|
|
1159
1255
|
// Compute appropriate mediaExt out parameter
|
|
1256
|
+
if (!params.mediaExt) {
|
|
1257
|
+
try {
|
|
1258
|
+
const url = new URL(params.endPoint);
|
|
1259
|
+
// Set mediaExt with ?ext= param when set OR url extension
|
|
1260
|
+
params.mediaExt = (_a = url.searchParams.get('ext')) !== null && _a !== void 0 ? _a : getExtension(getFile(url.pathname));
|
|
1261
|
+
}
|
|
1262
|
+
catch (_) {
|
|
1263
|
+
// not an URL, it's only a host
|
|
1264
|
+
params.mediaExt = '';
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
// Normalize mediaExt in removing the possible '.' prefix and change it to lower case
|
|
1268
|
+
params.mediaExt = trimStart(params.mediaExt, '.').toLowerCase();
|
|
1160
1269
|
switch (type) {
|
|
1161
1270
|
case Type.HESP:
|
|
1162
1271
|
params.mediaExt = 'mp4';
|
|
@@ -1165,19 +1274,8 @@ function defineMediaExt(type, params) {
|
|
|
1165
1274
|
params.mediaExt = 'rtp';
|
|
1166
1275
|
break;
|
|
1167
1276
|
case Type.WRTS: {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const ext = getExtension(getFile(url.pathname));
|
|
1171
|
-
// set extension just if not json, json means a manifest file endPoint
|
|
1172
|
-
if (ext && ext.toLowerCase() !== '.json') {
|
|
1173
|
-
params.mediaExt = ext;
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
catch (_) {
|
|
1177
|
-
// not an URL, it's only a host => keep mediaExt unchanged to build the URL
|
|
1178
|
-
}
|
|
1179
|
-
if (!params.mediaExt) {
|
|
1180
|
-
// set to its default rts value => always set for WRTS!
|
|
1277
|
+
// json means a manifest file endPoint, replace with default rts media extension
|
|
1278
|
+
if (!params.mediaExt || params.mediaExt === 'json') {
|
|
1181
1279
|
params.mediaExt = 'rts';
|
|
1182
1280
|
}
|
|
1183
1281
|
break;
|
|
@@ -1189,12 +1287,9 @@ function defineMediaExt(type, params) {
|
|
|
1189
1287
|
params.mediaExt = 'json';
|
|
1190
1288
|
break;
|
|
1191
1289
|
default:
|
|
1192
|
-
params
|
|
1193
|
-
console.warn('Unknown params type ' + type);
|
|
1290
|
+
log('Unknown params type ' + type).warn();
|
|
1194
1291
|
break;
|
|
1195
1292
|
}
|
|
1196
|
-
// Fix mediaExt in removing the possible '.' prefix
|
|
1197
|
-
params.mediaExt = trimStart(params.mediaExt, '.');
|
|
1198
1293
|
}
|
|
1199
1294
|
/**
|
|
1200
1295
|
* Build an URL from {@link Type | type} and {@link Params | params}
|
|
@@ -1227,7 +1322,7 @@ function buildURL(type, params, protocol = 'wss') {
|
|
|
1227
1322
|
url.pathname = '/' + params.streamName + '.json';
|
|
1228
1323
|
break;
|
|
1229
1324
|
default:
|
|
1230
|
-
|
|
1325
|
+
log('Unknown url type ' + type).warn();
|
|
1231
1326
|
break;
|
|
1232
1327
|
}
|
|
1233
1328
|
}
|
|
@@ -1360,11 +1455,12 @@ class EventEmitter extends Loggable {
|
|
|
1360
1455
|
throw Error('event callback must be a function');
|
|
1361
1456
|
}
|
|
1362
1457
|
const events = this._event(name);
|
|
1363
|
-
|
|
1364
|
-
events.delete(
|
|
1458
|
+
const wrapper = (...args) => {
|
|
1459
|
+
events.delete(wrapper); // delete the wrapper from events
|
|
1365
1460
|
event(...args); // execute event
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1461
|
+
};
|
|
1462
|
+
events.add(wrapper);
|
|
1463
|
+
(_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.addEventListener('abort', () => events.delete(wrapper), { once: true });
|
|
1368
1464
|
}
|
|
1369
1465
|
/**
|
|
1370
1466
|
* Event unsubscription
|
|
@@ -2288,6 +2384,12 @@ class UIMetrics {
|
|
|
2288
2384
|
}
|
|
2289
2385
|
constructor(ui) {
|
|
2290
2386
|
this._ui = ui;
|
|
2387
|
+
ui.addEventListener('mousemove', (event) => {
|
|
2388
|
+
this._mouseX = event.offsetX;
|
|
2389
|
+
});
|
|
2390
|
+
ui.addEventListener('mouseleave', (event) => {
|
|
2391
|
+
this._mouseX = undefined;
|
|
2392
|
+
});
|
|
2291
2393
|
// default values in pixels
|
|
2292
2394
|
this._lineHeight = 40;
|
|
2293
2395
|
this._labelWidth = 170;
|
|
@@ -2371,6 +2473,7 @@ class UIMetrics {
|
|
|
2371
2473
|
const delta = range.max - range.min;
|
|
2372
2474
|
let minCircle = '';
|
|
2373
2475
|
let maxCircle = '';
|
|
2476
|
+
let mouseCircle = this._mouseX == null || this._mouseX > x ? null : '';
|
|
2374
2477
|
for (let i = 0; i < values.length; ++i) {
|
|
2375
2478
|
x -= this._stepSize;
|
|
2376
2479
|
const value = parseFloat(values[i].toString());
|
|
@@ -2382,6 +2485,9 @@ class UIMetrics {
|
|
|
2382
2485
|
else if (value === max) {
|
|
2383
2486
|
minCircle = minCircle || this._drawCircle(x, y, value);
|
|
2384
2487
|
}
|
|
2488
|
+
if (mouseCircle === '' && x <= (this._mouseX || 0)) {
|
|
2489
|
+
mouseCircle = this._drawCircle(x, y, value, 'blue', '');
|
|
2490
|
+
}
|
|
2385
2491
|
}
|
|
2386
2492
|
this._html += '" />'; // end path
|
|
2387
2493
|
// Average
|
|
@@ -2396,7 +2502,10 @@ class UIMetrics {
|
|
|
2396
2502
|
'</tspan>';
|
|
2397
2503
|
this._html += '<tspan x="' + (width + averageCenter) + '" dy="1em">±' + average + '</tspan>';
|
|
2398
2504
|
this._html += '</text>';
|
|
2399
|
-
this._html += minCircle + maxCircle;
|
|
2505
|
+
this._html += minCircle + maxCircle + (mouseCircle !== null && mouseCircle !== void 0 ? mouseCircle : '');
|
|
2506
|
+
if (mouseCircle) {
|
|
2507
|
+
this._html += mouseCircle;
|
|
2508
|
+
}
|
|
2400
2509
|
this._html += '</svg>';
|
|
2401
2510
|
}
|
|
2402
2511
|
requestAnimationFrame(() => {
|
|
@@ -2406,8 +2515,8 @@ class UIMetrics {
|
|
|
2406
2515
|
}
|
|
2407
2516
|
});
|
|
2408
2517
|
}
|
|
2409
|
-
_drawCircle(x, y, value) {
|
|
2410
|
-
let circle = '<circle cx="' + x + '" cy="' + y + '" r="2" fill="
|
|
2518
|
+
_drawCircle(x, y, value, color = 'green', fontStyle = 'italic') {
|
|
2519
|
+
let circle = '<circle cx="' + x + '" cy="' + y + '" r="2" fill="' + color + '" />';
|
|
2411
2520
|
const legendFontHeight = 0.7 * this._legendFontSize;
|
|
2412
2521
|
const graphMiddle = Math.round(this._lineHeight / 2);
|
|
2413
2522
|
if (y < graphMiddle) {
|
|
@@ -2419,7 +2528,9 @@ class UIMetrics {
|
|
|
2419
2528
|
y -= this.textMargin;
|
|
2420
2529
|
}
|
|
2421
2530
|
circle +=
|
|
2422
|
-
'<text font-style="
|
|
2531
|
+
'<text font-style="' +
|
|
2532
|
+
fontStyle +
|
|
2533
|
+
'" font-size="' +
|
|
2423
2534
|
this._legendFontSize +
|
|
2424
2535
|
'" x="' +
|
|
2425
2536
|
(x - this._legendFontSize) +
|
|
@@ -2435,4 +2546,4 @@ class UIMetrics {
|
|
|
2435
2546
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
2436
2547
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
2437
2548
|
*/
|
|
2438
|
-
const VERSION = '
|
|
2549
|
+
const VERSION = '7.0.0';export{BinaryReader,BinaryWriter,BitReader,ByteRate,Connect,EpochTime,EventEmitter,FixMap,Log,LogLevel,Loggable,NetAddress,Numbers,Queue,SDP,UIMetrics,Util,VERSION,WebSocketReliable,log};//# sourceMappingURL=web-utils.js.map
|