@ceeblue/web-utils 2.5.0 → 2.6.1
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/web-utils.d.ts +95 -17
- package/dist/web-utils.js +98 -1
- 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 +1 -1
package/dist/web-utils.d.ts
CHANGED
|
@@ -184,6 +184,55 @@ declare namespace Connect {
|
|
|
184
184
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
185
185
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
186
186
|
*/
|
|
187
|
+
/**
|
|
188
|
+
* Log interface to deal with log everywhere:
|
|
189
|
+
* - subscribe logs: listen logs to effectuate some specific job related logs
|
|
190
|
+
* - intercept logs: intercept logs to change the default behavior
|
|
191
|
+
* - redirect logs: redirect logs to one other logger engine
|
|
192
|
+
* - redefine logs: change log text like adding a prefix
|
|
193
|
+
*
|
|
194
|
+
* You have 4 {@link LogType} 'error', 'warn', 'info', and 'debug', as commonly managed by browsers.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* // Intercept and redirect all the logs to the console (default behavior)
|
|
198
|
+
* import { log } from '@ceeblue/web-utils';
|
|
199
|
+
* log.on(type:LogType, args:uknown[]) => {
|
|
200
|
+
* console[type](...args.splice(0)); // args is empty after this call = final interception
|
|
201
|
+
* }
|
|
202
|
+
*
|
|
203
|
+
* // Intercept and redirect the logs from Player compoment to the console
|
|
204
|
+
* player.log.on(type:LogType, args:uknown[]) => {
|
|
205
|
+
* console[type](...args.splice(0)); // args is empty after this call = final interception
|
|
206
|
+
* }
|
|
207
|
+
*
|
|
208
|
+
* // Subscribe and redirect all the logs to a file logger
|
|
209
|
+
* log.on(type:LogType, args:uknown[]) => {
|
|
210
|
+
* fileLogger[type](...args); // args stays unchanged to let's continue the default behavior
|
|
211
|
+
* }
|
|
212
|
+
*
|
|
213
|
+
* // Redefine the log to add some prefix indication
|
|
214
|
+
* class Player {
|
|
215
|
+
* connector = new Connector();
|
|
216
|
+
* constructor() {
|
|
217
|
+
* connector.log = this.log.bind(this, "Connector log:");
|
|
218
|
+
* }
|
|
219
|
+
* }
|
|
220
|
+
*
|
|
221
|
+
*/
|
|
222
|
+
interface ILog {
|
|
223
|
+
/**
|
|
224
|
+
* Build a log
|
|
225
|
+
*/
|
|
226
|
+
(...args: unknown[]): Log;
|
|
227
|
+
/**
|
|
228
|
+
* Intercept, redefine or redirect any log
|
|
229
|
+
* If you clear args you intercept the log and nothing happen more after this call.
|
|
230
|
+
* @param type log level
|
|
231
|
+
* @param args args
|
|
232
|
+
* @returns
|
|
233
|
+
*/
|
|
234
|
+
on: (type: LogType, args: unknown[]) => void;
|
|
235
|
+
}
|
|
187
236
|
/**
|
|
188
237
|
* Log types
|
|
189
238
|
*/
|
|
@@ -207,22 +256,6 @@ declare class Log {
|
|
|
207
256
|
constructor(onLog: Function, ...args: unknown[]);
|
|
208
257
|
private _bind;
|
|
209
258
|
}
|
|
210
|
-
/**
|
|
211
|
-
* ILog interface used by log methods
|
|
212
|
-
*/
|
|
213
|
-
interface ILog {
|
|
214
|
-
/**
|
|
215
|
-
* Build a log
|
|
216
|
-
*/
|
|
217
|
-
(...args: unknown[]): Log;
|
|
218
|
-
/**
|
|
219
|
-
* Intercept or redefine any log
|
|
220
|
-
* @param type log level
|
|
221
|
-
* @param args args
|
|
222
|
-
* @returns
|
|
223
|
-
*/
|
|
224
|
-
on: (type: LogType, args: unknown[]) => void;
|
|
225
|
-
}
|
|
226
259
|
/**
|
|
227
260
|
* Inherits from this class to use logs
|
|
228
261
|
*/
|
|
@@ -934,6 +967,51 @@ declare class WebSocketReliable extends EventEmitter {
|
|
|
934
967
|
private _send;
|
|
935
968
|
}
|
|
936
969
|
|
|
970
|
+
/**
|
|
971
|
+
* Copyright 2024 Ceeblue B.V.
|
|
972
|
+
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
973
|
+
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
974
|
+
*/
|
|
975
|
+
/**
|
|
976
|
+
* Decode the timestamp from a video element and compute the latency between the timestamp and the current date.
|
|
977
|
+
*
|
|
978
|
+
* @param {HTMLVideoElement} sourceEl the video element to get the image from
|
|
979
|
+
* @param {HTMLCanvasElement} canvas
|
|
980
|
+
* @param {CanvasRenderingContext2D} context
|
|
981
|
+
* @param {Date} now current date, new Date() by default
|
|
982
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
983
|
+
* @param {Number} tolerance percentage of tolerance for the black and white threshold, 0.2 by default
|
|
984
|
+
* @returns {Number} The latency in millisecond between 'now' and the decoded timestamp, 0 if the timestamp cannot be decoded
|
|
985
|
+
*/
|
|
986
|
+
declare function getLatency(sourceEl: HTMLVideoElement, canvas: HTMLCanvasElement, context: CanvasRenderingContext2D, now?: Date, blocksPerRow?: number, tolerance?: number): number;
|
|
987
|
+
/**
|
|
988
|
+
* Decode a previously encoded timestamp from a canvas
|
|
989
|
+
*
|
|
990
|
+
* @param {CanvasRenderingContext2D} context
|
|
991
|
+
* @param {Number} lineWidth width of the line in pixels
|
|
992
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
993
|
+
* @param {Number} tolerance percentage of tolerance for the black and white threshold, 0.2 by default
|
|
994
|
+
* @returns {Date|null} The Date object representing the timestamp or null if the timestamp cannot be decoded
|
|
995
|
+
*/
|
|
996
|
+
declare function decodeTimestamp(context: CanvasRenderingContext2D, lineWidth: number, blocksPerRow?: number, tolerance?: number): Date | undefined;
|
|
997
|
+
/**
|
|
998
|
+
* Encode the current timestamp into a line composed of blocks of black and white pixels
|
|
999
|
+
* written on the top of the canvas.
|
|
1000
|
+
*
|
|
1001
|
+
* @param {CanvasRenderingContext2D} context
|
|
1002
|
+
* @param {Number} lineWidth width of the line in pixels
|
|
1003
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
1004
|
+
* @param {Date} now current date, new Date() by default
|
|
1005
|
+
*/
|
|
1006
|
+
declare function encodeTimestamp(context: CanvasRenderingContext2D, lineWidth: number, blocksPerRow?: number, now?: Date): void;
|
|
1007
|
+
|
|
1008
|
+
declare const EpochTime_decodeTimestamp: typeof decodeTimestamp;
|
|
1009
|
+
declare const EpochTime_encodeTimestamp: typeof encodeTimestamp;
|
|
1010
|
+
declare const EpochTime_getLatency: typeof getLatency;
|
|
1011
|
+
declare namespace EpochTime {
|
|
1012
|
+
export { EpochTime_decodeTimestamp as decodeTimestamp, EpochTime_encodeTimestamp as encodeTimestamp, EpochTime_getLatency as getLatency };
|
|
1013
|
+
}
|
|
1014
|
+
|
|
937
1015
|
/**
|
|
938
1016
|
* Copyright 2024 Ceeblue B.V.
|
|
939
1017
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
@@ -942,4 +1020,4 @@ declare class WebSocketReliable extends EventEmitter {
|
|
|
942
1020
|
|
|
943
1021
|
declare const VERSION: string;
|
|
944
1022
|
|
|
945
|
-
export { BinaryReader, BinaryWriter, BitReader, ByteRate, Connect, EventEmitter, FixMap, type ILog, Log, LogType, Loggable, NetAddress, Numbers, Queue, SDP, Util, VERSION, WebSocketReliable, type WebSocketReliableError, log };
|
|
1023
|
+
export { BinaryReader, BinaryWriter, BitReader, ByteRate, Connect, EpochTime, EventEmitter, FixMap, type ILog, Log, LogType, Loggable, NetAddress, Numbers, Queue, SDP, Util, VERSION, WebSocketReliable, type WebSocketReliableError, log };
|
package/dist/web-utils.js
CHANGED
|
@@ -1928,4 +1928,101 @@ class WebSocketReliable extends EventEmitter {
|
|
|
1928
1928
|
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
1929
1929
|
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
1930
1930
|
*/
|
|
1931
|
-
|
|
1931
|
+
/**
|
|
1932
|
+
* Decode the timestamp from a video element and compute the latency between the timestamp and the current date.
|
|
1933
|
+
*
|
|
1934
|
+
* @param {HTMLVideoElement} sourceEl the video element to get the image from
|
|
1935
|
+
* @param {HTMLCanvasElement} canvas
|
|
1936
|
+
* @param {CanvasRenderingContext2D} context
|
|
1937
|
+
* @param {Date} now current date, new Date() by default
|
|
1938
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
1939
|
+
* @param {Number} tolerance percentage of tolerance for the black and white threshold, 0.2 by default
|
|
1940
|
+
* @returns {Number} The latency in millisecond between 'now' and the decoded timestamp, 0 if the timestamp cannot be decoded
|
|
1941
|
+
*/
|
|
1942
|
+
function getLatency(sourceEl, canvas, context, now = new Date(), blocksPerRow = 32, tolerance = 0.2) {
|
|
1943
|
+
canvas.width = sourceEl.videoWidth;
|
|
1944
|
+
canvas.height = Math.floor(canvas.width / blocksPerRow);
|
|
1945
|
+
if (!canvas.width || !canvas.height) {
|
|
1946
|
+
// No pixel to parse!
|
|
1947
|
+
return 0;
|
|
1948
|
+
}
|
|
1949
|
+
context.drawImage(sourceEl, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
|
|
1950
|
+
const timestamp = decodeTimestamp(context, canvas.width, blocksPerRow, tolerance);
|
|
1951
|
+
return timestamp == null ? 0 : now.getTime() - timestamp.getTime();
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Decode a previously encoded timestamp from a canvas
|
|
1955
|
+
*
|
|
1956
|
+
* @param {CanvasRenderingContext2D} context
|
|
1957
|
+
* @param {Number} lineWidth width of the line in pixels
|
|
1958
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
1959
|
+
* @param {Number} tolerance percentage of tolerance for the black and white threshold, 0.2 by default
|
|
1960
|
+
* @returns {Date|null} The Date object representing the timestamp or null if the timestamp cannot be decoded
|
|
1961
|
+
*/
|
|
1962
|
+
function decodeTimestamp(context, lineWidth, blocksPerRow = 32, tolerance = 0.2) {
|
|
1963
|
+
const blockSize = lineWidth / blocksPerRow;
|
|
1964
|
+
let binaryTime = '';
|
|
1965
|
+
let i = blockSize / 2;
|
|
1966
|
+
const data = context.getImageData(0, Math.round(i), lineWidth, 1).data;
|
|
1967
|
+
const pixels = new Uint32Array(data.buffer);
|
|
1968
|
+
const blackThreshold = 0xff * tolerance;
|
|
1969
|
+
const whiteThreshold = 0xff * (1 - tolerance);
|
|
1970
|
+
while (i < pixels.length) {
|
|
1971
|
+
const pixel = pixels[Math.round(i)] & 0xffffff;
|
|
1972
|
+
// Extract luminance from RGB
|
|
1973
|
+
const Y = 0.299 * ((pixel >> 16) & 0xff) + 0.587 * ((pixel >> 8) & 0xff) + 0.114 * (pixel & 0xff);
|
|
1974
|
+
if (Y < blackThreshold) {
|
|
1975
|
+
// Black
|
|
1976
|
+
binaryTime += '1';
|
|
1977
|
+
}
|
|
1978
|
+
else if (Y > whiteThreshold) {
|
|
1979
|
+
// White
|
|
1980
|
+
binaryTime += '0';
|
|
1981
|
+
}
|
|
1982
|
+
else {
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
i += blockSize;
|
|
1986
|
+
}
|
|
1987
|
+
const day = parseInt(binaryTime.slice(0, 5), 2);
|
|
1988
|
+
const hour = parseInt(binaryTime.slice(5, 10), 2);
|
|
1989
|
+
const minute = parseInt(binaryTime.slice(10, 16), 2);
|
|
1990
|
+
const second = parseInt(binaryTime.slice(16, 22), 2);
|
|
1991
|
+
const millisecond = parseInt(binaryTime.slice(22, 32), 2);
|
|
1992
|
+
const now = new Date();
|
|
1993
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute, second, millisecond));
|
|
1994
|
+
}
|
|
1995
|
+
/**
|
|
1996
|
+
* Encode the current timestamp into a line composed of blocks of black and white pixels
|
|
1997
|
+
* written on the top of the canvas.
|
|
1998
|
+
*
|
|
1999
|
+
* @param {CanvasRenderingContext2D} context
|
|
2000
|
+
* @param {Number} lineWidth width of the line in pixels
|
|
2001
|
+
* @param {Number} blocksPerRow number of blocks in the line, 32 by default
|
|
2002
|
+
* @param {Date} now current date, new Date() by default
|
|
2003
|
+
*/
|
|
2004
|
+
function encodeTimestamp(context, lineWidth, blocksPerRow = 32, now = new Date()) {
|
|
2005
|
+
const blockSize = Math.floor(lineWidth / blocksPerRow);
|
|
2006
|
+
const day = now.getUTCDate();
|
|
2007
|
+
const hour = now.getUTCHours();
|
|
2008
|
+
const minute = now.getUTCMinutes();
|
|
2009
|
+
const second = now.getUTCSeconds();
|
|
2010
|
+
const millisecond = now.getUTCMilliseconds();
|
|
2011
|
+
const binaryDay = day.toString(2).padStart(5, '0');
|
|
2012
|
+
const binaryHour = hour.toString(2).padStart(5, '0');
|
|
2013
|
+
const binaryMinute = minute.toString(2).padStart(6, '0');
|
|
2014
|
+
const binarySecond = second.toString(2).padStart(6, '0');
|
|
2015
|
+
const binaryMillisecond = millisecond.toString(2).padStart(10, '0');
|
|
2016
|
+
const binaryTime = binaryDay + binaryHour + binaryMinute + binarySecond + binaryMillisecond;
|
|
2017
|
+
for (let i = 0; i < binaryTime.length; i++) {
|
|
2018
|
+
const x = (i % blocksPerRow) * blockSize;
|
|
2019
|
+
const y = Math.floor(i / blocksPerRow) * blockSize;
|
|
2020
|
+
context.fillStyle = binaryTime[i] === '1' ? 'black' : 'white';
|
|
2021
|
+
context.fillRect(x, y, blockSize, blockSize);
|
|
2022
|
+
}
|
|
2023
|
+
}var EpochTime=/*#__PURE__*/Object.freeze({__proto__:null,decodeTimestamp:decodeTimestamp,encodeTimestamp:encodeTimestamp,getLatency:getLatency});/**
|
|
2024
|
+
* Copyright 2024 Ceeblue B.V.
|
|
2025
|
+
* This file is part of https://github.com/CeeblueTV/web-utils which is released under GNU Affero General Public License.
|
|
2026
|
+
* See file LICENSE or go to https://spdx.org/licenses/AGPL-3.0-or-later.html for full license details.
|
|
2027
|
+
*/
|
|
2028
|
+
const VERSION = '2.6.1';export{BinaryReader,BinaryWriter,BitReader,ByteRate,Connect,EpochTime,EventEmitter,FixMap,Log,LogType,Loggable,NetAddress,Numbers,Queue,SDP,Util,VERSION,WebSocketReliable,log};//# sourceMappingURL=web-utils.js.map
|