senza-sdk 4.4.4-86e7d7a.0 → 4.4.4
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/bundle.js +1 -1
- package/dist/implementation.bundle.js +2 -0
- package/dist/implementation.bundle.js.LICENSE.txt +82 -0
- package/package.json +1 -1
- package/src/api.js +16 -2
- package/src/implementation/api.js +7 -5
- package/src/implementation/deviceManager.js +6 -177
- package/src/implementation/displayManager.js +181 -0
- package/src/implementation/edidParser.js +125 -0
- package/src/implementation/remotePlayer.js +5 -2
- package/src/interface/api.js +1 -0
- package/src/interface/deviceManager.js +0 -33
- package/src/interface/displayManager.js +126 -0
- package/src/interface/version.js +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const MANUFACTURER_MAP = {
|
|
2
|
+
// Major PC & Display Brands
|
|
3
|
+
ACR: "Acer",
|
|
4
|
+
APP: "Apple",
|
|
5
|
+
AOC: "AOC",
|
|
6
|
+
AUO: "AU Optronics",
|
|
7
|
+
BNQ: "BenQ",
|
|
8
|
+
BOE: "BOE Technology",
|
|
9
|
+
CMN: "Innolux (Chimei Innolux)",
|
|
10
|
+
CMO: "Chi Mei Optoelectronics",
|
|
11
|
+
CPQ: "Compaq",
|
|
12
|
+
DELL: "Dell", // some EDIDs use DEL
|
|
13
|
+
DEL: "Dell",
|
|
14
|
+
EIZ: "EIZO",
|
|
15
|
+
FUS: "Fujitsu",
|
|
16
|
+
HPN: "HP",
|
|
17
|
+
HWP: "HP",
|
|
18
|
+
IVM: "Iiyama",
|
|
19
|
+
LEN: "Lenovo",
|
|
20
|
+
LPL: "LG Philips LCD",
|
|
21
|
+
LGE: "LG Electronics",
|
|
22
|
+
GSM: "LG Electronics (GoldStar)",
|
|
23
|
+
MEI: "Panasonic (Matsushita)",
|
|
24
|
+
NEC: "NEC",
|
|
25
|
+
NVD: "Nvidia",
|
|
26
|
+
PHL: "Philips",
|
|
27
|
+
PHI: "Philips",
|
|
28
|
+
SAM: "Samsung",
|
|
29
|
+
SNY: "Sony",
|
|
30
|
+
TOS: "Toshiba",
|
|
31
|
+
VSC: "ViewSonic",
|
|
32
|
+
VIZ: "Vizio",
|
|
33
|
+
|
|
34
|
+
// Panel Makers / ODMs
|
|
35
|
+
CPT: "Chunghwa Picture Tubes",
|
|
36
|
+
HSD: "HannStar Display",
|
|
37
|
+
QDS: "Quanta Display",
|
|
38
|
+
SEC: "Samsung Electronics Display",
|
|
39
|
+
SHP: "Sharp",
|
|
40
|
+
TMX: "Tianma",
|
|
41
|
+
CMI: "Chi Mei Innolux",
|
|
42
|
+
|
|
43
|
+
// Other common consumer brands
|
|
44
|
+
JVC: "JVC (Victor Company of Japan)",
|
|
45
|
+
PIO: "Pioneer",
|
|
46
|
+
FUN: "Funai",
|
|
47
|
+
GRN: "Grundig",
|
|
48
|
+
MAG: "MAG Innovision",
|
|
49
|
+
TCL: "TCL",
|
|
50
|
+
HAI: "Haier",
|
|
51
|
+
HIT: "Hitachi",
|
|
52
|
+
SMC: "Sumitomo",
|
|
53
|
+
WAC: "Wacom",
|
|
54
|
+
ASUS: "ASUSTek", // often ASU
|
|
55
|
+
ASU: "ASUS",
|
|
56
|
+
GIG: "Gigabyte",
|
|
57
|
+
MSI: "Micro-Star International",
|
|
58
|
+
|
|
59
|
+
// Catch-alls / misc seen in monitors
|
|
60
|
+
ENC: "Energizer",
|
|
61
|
+
ZOW: "Zowie",
|
|
62
|
+
TTX: "Tatung",
|
|
63
|
+
KDS: "KDS",
|
|
64
|
+
HIS: "HIS",
|
|
65
|
+
XXX: "TCL",
|
|
66
|
+
XMD: "Xiaomi"
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// --- helpers ---
|
|
70
|
+
function hexToBytes(hex) {
|
|
71
|
+
const clean = hex.replace(/[^0-9a-fA-F]/g, "");
|
|
72
|
+
if (clean.length % 2 !== 0) throw new Error("Hex length must be even");
|
|
73
|
+
const out = new Uint8Array(clean.length / 2);
|
|
74
|
+
for (let i = 0; i < clean.length; i += 2) {
|
|
75
|
+
out[i / 2] = parseInt(clean.slice(i, i + 2), 16);
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function decodeEisaId(word) {
|
|
81
|
+
const a = (word >> 10 & 0x1f) + 64;
|
|
82
|
+
const b = (word >> 5 & 0x1f) + 64;
|
|
83
|
+
const c = (word & 0x1f) + 64;
|
|
84
|
+
return [a, b, c].map(n => n >= 65 && n <= 90 ? String.fromCharCode(n) : "?").join("");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sanitizeEdidString(bytes) {
|
|
88
|
+
let out = "";
|
|
89
|
+
for (const b of bytes) {
|
|
90
|
+
if (b === 0x00 || b === 0x0a) break;
|
|
91
|
+
if (b >= 0x20 && b <= 0x7e) out += String.fromCharCode(b);
|
|
92
|
+
}
|
|
93
|
+
return out.trim();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
export function parseEdid(input) {
|
|
98
|
+
const edid = input instanceof Uint8Array ? input : hexToBytes(input);
|
|
99
|
+
|
|
100
|
+
// Manufacturer ID (bytes 8–9)
|
|
101
|
+
const mfgWord = edid[8] << 8 | edid[9];
|
|
102
|
+
const manufacturerId = decodeEisaId(mfgWord);
|
|
103
|
+
const manufacturerName = MANUFACTURER_MAP[manufacturerId] || manufacturerId;
|
|
104
|
+
|
|
105
|
+
// Product code (bytes 10–11)
|
|
106
|
+
const productCode = (edid[10] | edid[11] << 8) >>> 0;
|
|
107
|
+
const modelNumber = String(productCode);
|
|
108
|
+
|
|
109
|
+
// Monitor name descriptor (0xFC) and serial number descriptor (0xFF) in base block
|
|
110
|
+
let modelName;
|
|
111
|
+
let serialNumber;
|
|
112
|
+
for (let off = 0x36; off <= 0x7e - 18; off += 18) {
|
|
113
|
+
const d = edid.slice(off, off + 18);
|
|
114
|
+
if (d[0] === 0x00 && d[1] === 0x00 && d[2] === 0x00) {
|
|
115
|
+
if (d[3] === 0xFC) {
|
|
116
|
+
modelName = sanitizeEdidString(d.slice(5, 18));
|
|
117
|
+
} else if (d[3] === 0xFF) {
|
|
118
|
+
serialNumber = sanitizeEdidString(d.slice(5, 18));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return { manufacturerName, modelName, modelNumber, serialNumber };
|
|
124
|
+
}
|
|
125
|
+
|
|
@@ -246,6 +246,7 @@ class RemotePlayer extends RemotePlayerInterface {
|
|
|
246
246
|
|
|
247
247
|
typeof document !== "undefined" && document.addEventListener("hs/EOS", () => {
|
|
248
248
|
sdkLogger.info("Got hs/EOS event");
|
|
249
|
+
this._changePlayMode(false);
|
|
249
250
|
this.dispatchEvent(new Event("ended"));
|
|
250
251
|
});
|
|
251
252
|
|
|
@@ -790,10 +791,12 @@ class RemotePlayer extends RemotePlayerInterface {
|
|
|
790
791
|
fcid: FCID
|
|
791
792
|
};
|
|
792
793
|
if (this._uiAvSyncIntervalMs !== undefined) {
|
|
793
|
-
message.
|
|
794
|
+
message.connectorSettings = message.connectorSettings || {};
|
|
795
|
+
message.connectorSettings.uiAvSyncIntervalMs = this._uiAvSyncIntervalMs;
|
|
794
796
|
}
|
|
795
797
|
if (this._abrAvSyncIntervalMs !== undefined) {
|
|
796
|
-
message.
|
|
798
|
+
message.connectorSettings = message.connectorSettings || {};
|
|
799
|
+
message.connectorSettings.abrAvSyncIntervalMs = this._abrAvSyncIntervalMs;
|
|
797
800
|
}
|
|
798
801
|
if (this._remotePlayerApiVersion >= 2) {
|
|
799
802
|
message.type = "remotePlayer.load";
|
package/src/interface/api.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { Lifecycle } from "./lifecycle.js";
|
|
2
2
|
export { DeviceManager } from "./deviceManager.js";
|
|
3
|
+
export { DisplayManager } from "./displayManager.js";
|
|
3
4
|
export { PlatformManager } from "./platformManager.js";
|
|
4
5
|
export { AlarmManager } from "./alarmManager.js";
|
|
5
6
|
export { MessageManager } from "./messageManager.js";
|
|
@@ -1,32 +1,9 @@
|
|
|
1
1
|
import { sdkLogger, noop } from "./utils.js";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @event DeviceManager#hdmistatuschanged
|
|
5
|
-
* @description Fired when the HDMI connection status changes.<br>
|
|
6
|
-
* @property {HdmiStatus} hdmiStatus - the status of the HDMI connection.
|
|
7
|
-
* @example
|
|
8
|
-
* deviceManager.addEventListener("hdmistatuschanged", (e) => {
|
|
9
|
-
* console.info("HDMI status changed:", e.detail.hdmiStatus);
|
|
10
|
-
* });
|
|
11
|
-
* @private
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
3
|
/**
|
|
15
4
|
* DeviceManager is a singleton class that manages the device.<br>
|
|
16
|
-
* @fires hdmistatuschanged
|
|
17
5
|
*/
|
|
18
6
|
export class DeviceManager extends EventTarget {
|
|
19
|
-
/**
|
|
20
|
-
* @typedef {Object} HdmiStatus - The HDMI status of the device
|
|
21
|
-
* @property {string} ACTIVE - The device is connected to the active HDMI source.
|
|
22
|
-
* @property {string} INACTIVE - The active HDMI source is different than the one connected to the device or the TV is in standby.
|
|
23
|
-
* @property {string} UNKNOWN - The status is unknown. This can happen if the TV does not support HDMI status detection.
|
|
24
|
-
*/
|
|
25
|
-
HdmiStatus = Object.freeze({
|
|
26
|
-
ACTIVE: "active",
|
|
27
|
-
INACTIVE: "inactive",
|
|
28
|
-
UNKNOWN: "unknown"
|
|
29
|
-
});
|
|
30
7
|
|
|
31
8
|
/**
|
|
32
9
|
* @property {object} DeviceInfo
|
|
@@ -54,16 +31,6 @@ export class DeviceManager extends EventTarget {
|
|
|
54
31
|
|
|
55
32
|
}
|
|
56
33
|
|
|
57
|
-
/**
|
|
58
|
-
* Get the current HDMI status from the connector
|
|
59
|
-
* @return {Promise<HdmiStatus>} Promise which is resolved when getHdmiStatus has been successfully performed
|
|
60
|
-
* Failure to getHdmiStatus for any reason, results in the promise being rejected.
|
|
61
|
-
* @private
|
|
62
|
-
*/
|
|
63
|
-
getHdmiStatus() {
|
|
64
|
-
return noop("DeviceManager.getHdmiStatus");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
34
|
/**
|
|
68
35
|
* Reboot the device
|
|
69
36
|
* @return {Promise} Promise which is resolved when the reboot command has been successfully processed.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @event DisplayManager#displayinfochanged
|
|
3
|
+
* @description Fired when the display information changes.
|
|
4
|
+
* @property {DisplayInfoChanged} [detail.displayInfo] - the updated display information.
|
|
5
|
+
* @example
|
|
6
|
+
* @private
|
|
7
|
+
* displayManager.addEventListener("displayinfochanged", (e) => {
|
|
8
|
+
* console.info("Display information changed:", e.detail.displayInfo);
|
|
9
|
+
* });
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {Object} DisplayInfoChanged
|
|
14
|
+
* @property {DisplayConnectionStatus | undefined} connection Display connection status.
|
|
15
|
+
* @property {DisplaySelectedStatus | undefined} selected Display selected status.
|
|
16
|
+
* @property {DisplayResolution | undefined} resolution Display resolution information.
|
|
17
|
+
* @property {number | undefined} framerate Display frame rate.
|
|
18
|
+
* @property {string | undefined} security Display HDCP / security level.
|
|
19
|
+
* @property {string | undefined} make Display vendor (make) information.
|
|
20
|
+
* @property {string | undefined} model Display model information.
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* DisplayManager exposes information about the connected display / sink device.
|
|
26
|
+
* It allows querying several negotiated HDMI parameters and (for a subset) receiving change notifications.
|
|
27
|
+
* @private
|
|
28
|
+
* @fires displayinfochanged
|
|
29
|
+
*/
|
|
30
|
+
export class DisplayManager extends EventTarget {
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {Object} DisplayConnectionStatus
|
|
33
|
+
* @property {string} CONNECTED Display is connected and communication established.
|
|
34
|
+
* @property {string} DISCONNECTED Display cable removed / not detected.
|
|
35
|
+
* @property {string} UNKNOWN The platform cannot determine (e.g. unsupported).
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
DisplayConnectionStatus = Object.freeze({
|
|
39
|
+
CONNECTED: "connected",
|
|
40
|
+
DISCONNECTED: "disconnected",
|
|
41
|
+
UNKNOWN: "unknown"
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {Object} DisplaySelectedStatus
|
|
46
|
+
* @property {string} ACTIVE The display input where the device is connected is currently active.
|
|
47
|
+
* @property {string} INACTIVE The device is connected but another source is active / TV in standby.
|
|
48
|
+
* @property {string} UNKNOWN The platform cannot determine (e.g. unsupported).
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
DisplaySelectedStatus = Object.freeze({
|
|
52
|
+
ACTIVE: "active",
|
|
53
|
+
INACTIVE: "inactive",
|
|
54
|
+
UNKNOWN: "unknown"
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {Object} DisplayResolution
|
|
59
|
+
* @property {number} width Negotiated active horizontal pixels
|
|
60
|
+
* @property {number} height Negotiated active vertical pixels
|
|
61
|
+
* @property {boolean} interlace True if the negotiated mode is interlaced
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Display connection status.
|
|
67
|
+
* @property {DisplayConnectionStatus} connection
|
|
68
|
+
*/
|
|
69
|
+
connection = this.DisplayConnectionStatus.DISCONNECTED;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether the display input this device is connected to is currently active.
|
|
73
|
+
* undefined when the display is not connected.
|
|
74
|
+
* @property {DisplaySelectedStatus} selected
|
|
75
|
+
*/
|
|
76
|
+
selected;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Negotiated resolution information.
|
|
80
|
+
* undefined when the display is not connected.
|
|
81
|
+
* @property {DisplayResolution} resolution
|
|
82
|
+
*/
|
|
83
|
+
resolution;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Negotiated frame rate (frames per second).
|
|
87
|
+
* undefined when the display is not connected.
|
|
88
|
+
* @property {number} framerate
|
|
89
|
+
*/
|
|
90
|
+
framerate;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Negotiated HDCP / security level.
|
|
94
|
+
* undefined when the display is not connected.
|
|
95
|
+
* @property {string} security
|
|
96
|
+
*/
|
|
97
|
+
security;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Vendor (make) information parsed from EDID.
|
|
101
|
+
* undefined when the display is not connected.
|
|
102
|
+
* @property {string} make
|
|
103
|
+
*/
|
|
104
|
+
make;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Model information parsed from EDID.
|
|
108
|
+
* undefined when the display is not connected.
|
|
109
|
+
* @property {string} model
|
|
110
|
+
*/
|
|
111
|
+
model;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @module
|
|
117
|
+
* @type {DisplayManager}
|
|
118
|
+
* @private
|
|
119
|
+
* @example
|
|
120
|
+
* import { displayManager } from "senza-sdk";
|
|
121
|
+
* const connection = await displayManager.connection;
|
|
122
|
+
* console.info(connection);
|
|
123
|
+
*
|
|
124
|
+
* @return {DisplayManager} pointer to the DisplayManager singleton
|
|
125
|
+
*/
|
|
126
|
+
"needed for the module doc comment to be recognized";
|
package/src/interface/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "4.4.4
|
|
1
|
+
export const version = "4.4.4";
|