elgato-stream-deck
Advanced tools
Comparing version 3.3.5 to 4.0.0
@@ -5,2 +5,17 @@ # Changelog | ||
## [4.0.0](https://github.com/julusian/node-elgato-stream-deck/compare/v3.3.5...v4.0.0) (2020-12-23) | ||
### BREAKING CHANGES | ||
- Drop support for node 8 or older | ||
### Features | ||
- support for buffers in any of rgb, rgba, bgr or bgra ([088d979](https://github.com/julusian/node-elgato-stream-deck/commit/088d979821d5614c0a751cfb594f7da936238552)) | ||
### Bug Fixes | ||
- broken text-generation example ([364f6de](https://github.com/julusian/node-elgato-stream-deck/commit/364f6de8ca83bfa89138f65bea31a01af42cd108)) | ||
- dependencies too new for node8 ([875f5bd](https://github.com/julusian/node-elgato-stream-deck/commit/875f5bd9a215310610ad3a8b06173a4aa8b3f7ff)) | ||
### [3.3.5](https://github.com/julusian/node-elgato-stream-deck/compare/v3.3.3...v3.3.5) (2020-12-08) | ||
@@ -7,0 +22,0 @@ |
import { OpenStreamDeckOptions, StreamDeck, StreamDeckDeviceInfo } from './models'; | ||
export { DeviceModelId, KeyIndex, StreamDeck, StreamDeckDeviceInfo, OpenStreamDeckOptions } from './models'; | ||
export { DeviceModelId, KeyIndex, StreamDeck, StreamDeckDeviceInfo, OpenStreamDeckOptions, FillImageOptions, FillPanelOptions, } from './models'; | ||
export { JPEGEncodeOptions } from './jpeg'; | ||
@@ -4,0 +4,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.openStreamDeck = exports.getStreamDeckInfo = exports.listStreamDecks = exports.DeviceModelId = void 0; | ||
const HID = require("node-hid"); | ||
const models_1 = require("./models"); | ||
var models_2 = require("./models"); | ||
exports.DeviceModelId = models_2.DeviceModelId; | ||
Object.defineProperty(exports, "DeviceModelId", { enumerable: true, get: function () { return models_2.DeviceModelId; } }); | ||
/* | ||
@@ -18,3 +19,3 @@ * The original StreamDeck uses packet sizes too large for the hidraw driver which is | ||
for (const dev of HID.devices()) { | ||
const model = models.find(m => m.productId === dev.productId); | ||
const model = models.find((m) => m.productId === dev.productId); | ||
if (model && dev.vendorId === 0x0fd9 && dev.path) { | ||
@@ -24,3 +25,3 @@ devices.push({ | ||
path: dev.path, | ||
serialNumber: dev.serialNumber | ||
serialNumber: dev.serialNumber, | ||
}); | ||
@@ -36,3 +37,3 @@ } | ||
function getStreamDeckInfo(path) { | ||
return listStreamDecks().find(dev => dev.path === path); | ||
return listStreamDecks().find((dev) => dev.path === path); | ||
} | ||
@@ -44,3 +45,3 @@ exports.getStreamDeckInfo = getStreamDeckInfo; | ||
productId: 0x0060, | ||
class: models_1.StreamDeckOriginal | ||
class: models_1.StreamDeckOriginal, | ||
}, | ||
@@ -50,3 +51,3 @@ { | ||
productId: 0x0063, | ||
class: models_1.StreamDeckMini | ||
class: models_1.StreamDeckMini, | ||
}, | ||
@@ -56,3 +57,3 @@ { | ||
productId: 0x006c, | ||
class: models_1.StreamDeckXL | ||
class: models_1.StreamDeckXL, | ||
}, | ||
@@ -62,4 +63,4 @@ { | ||
productId: 0x006d, | ||
class: models_1.StreamDeckOriginalV2 | ||
} | ||
class: models_1.StreamDeckOriginalV2, | ||
}, | ||
]; | ||
@@ -69,3 +70,3 @@ function openStreamDeck(devicePath, userOptions) { | ||
if (devicePath) { | ||
foundDevices = foundDevices.filter(d => d.path === devicePath); | ||
foundDevices = foundDevices.filter((d) => d.path === devicePath); | ||
} | ||
@@ -81,4 +82,4 @@ if (foundDevices.length === 0) { | ||
// Clone the options, to ensure they dont get changed | ||
const options = Object.assign({}, userOptions); | ||
const model = models.find(m => m.id === foundDevices[0].model); | ||
const options = { ...userOptions }; | ||
const model = models.find((m) => m.id === foundDevices[0].model); | ||
if (!model) { | ||
@@ -90,1 +91,2 @@ throw new Error('Stream Deck is of unexpected type.'); | ||
exports.openStreamDeck = openStreamDeck; | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.encodeJPEG = void 0; | ||
const jpegJS = require("jpeg-js"); | ||
@@ -17,4 +18,9 @@ let jpegTurbo; | ||
if (jpegTurbo && jpegTurbo.bufferSize && jpegTurbo.compressSync) { | ||
const encodeOptions = Object.assign({ format: jpegTurbo.FORMAT_RGBA, width, | ||
height, quality: DEFAULT_QUALITY }, options); | ||
const encodeOptions = { | ||
format: jpegTurbo.FORMAT_RGBA, | ||
width, | ||
height, | ||
quality: DEFAULT_QUALITY, | ||
...options, | ||
}; | ||
if (buffer.length === width * height * 4) { | ||
@@ -34,3 +40,3 @@ const tmpBuffer = Buffer.alloc(jpegTurbo.bufferSize(encodeOptions)); | ||
height, | ||
data: buffer | ||
data: buffer, | ||
}, options ? options.quality : DEFAULT_QUALITY); | ||
@@ -40,1 +46,2 @@ return jpegBuffer2.data; | ||
exports.encodeJPEG = encodeJPEG; | ||
//# sourceMappingURL=jpeg.js.map |
/// <reference types="node" /> | ||
import { StreamDeckBase } from './base'; | ||
import { StreamDeckBase, InternalFillImageOptions } from './base'; | ||
import { KeyIndex } from './id'; | ||
@@ -21,4 +21,4 @@ /** | ||
protected getFillImagePacketLength(): number; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOffset: number, sourceStride: number): Buffer; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOptions: InternalFillImageOptions): Buffer; | ||
private transformCoordinates; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckGen2Base = void 0; | ||
const jpeg_1 = require("../jpeg"); | ||
@@ -62,4 +63,4 @@ const util_1 = require("../util"); | ||
} | ||
convertFillImage(sourceBuffer, sourceOffset, sourceStride) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOffset, sourceStride, 0, this.transformCoordinates.bind(this), 'rgba', this.ICON_SIZE); | ||
convertFillImage(sourceBuffer, sourceOptions) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOptions, 0, this.transformCoordinates.bind(this), 'rgba', this.ICON_SIZE); | ||
return jpeg_1.encodeJPEG(byteBuffer, this.ICON_SIZE, this.ICON_SIZE, this.options.jpegOptions); | ||
@@ -72,1 +73,2 @@ } | ||
exports.StreamDeckGen2Base = StreamDeckGen2Base; | ||
//# sourceMappingURL=base-gen2.js.map |
@@ -19,2 +19,10 @@ /// <reference types="node" /> | ||
} | ||
export interface FillImageOptions { | ||
format: 'rgb' | 'rgba' | 'bgr' | 'bgra'; | ||
} | ||
export declare type FillPanelOptions = FillImageOptions; | ||
export interface InternalFillImageOptions extends FillImageOptions { | ||
offset: number; | ||
stride: number; | ||
} | ||
export interface StreamDeck { | ||
@@ -25,2 +33,3 @@ readonly NUM_KEYS: number; | ||
readonly ICON_SIZE: number; | ||
readonly ICON_PIXELS: number; | ||
readonly ICON_BYTES: number; | ||
@@ -42,4 +51,5 @@ readonly MODEL: DeviceModelId; | ||
* @param {Buffer} imageBuffer | ||
* @param {Object} options | ||
*/ | ||
fillImage(keyIndex: KeyIndex, imageBuffer: Buffer): void; | ||
fillImage(keyIndex: KeyIndex, imageBuffer: Buffer, options?: FillImageOptions): void; | ||
/** | ||
@@ -50,3 +60,3 @@ * Fills the whole panel with an image in a Buffer. | ||
*/ | ||
fillPanel(imageBuffer: Buffer): void; | ||
fillPanel(imageBuffer: Buffer, options?: FillPanelOptions): void; | ||
/** | ||
@@ -88,8 +98,9 @@ * Clears the given key. | ||
export declare abstract class StreamDeckBase extends EventEmitter implements StreamDeck { | ||
readonly NUM_KEYS: number; | ||
readonly KEY_COLUMNS: number; | ||
readonly KEY_ROWS: number; | ||
readonly ICON_SIZE: number; | ||
readonly ICON_BYTES: number; | ||
readonly MODEL: DeviceModelId; | ||
get NUM_KEYS(): number; | ||
get KEY_COLUMNS(): number; | ||
get KEY_ROWS(): number; | ||
get ICON_SIZE(): number; | ||
get ICON_BYTES(): number; | ||
get ICON_PIXELS(): number; | ||
get MODEL(): DeviceModelId; | ||
protected readonly options: Readonly<OpenStreamDeckOptions>; | ||
@@ -102,4 +113,4 @@ private readonly device; | ||
fillColor(keyIndex: KeyIndex, r: number, g: number, b: number): void; | ||
fillImage(keyIndex: KeyIndex, imageBuffer: Buffer): void; | ||
fillPanel(imageBuffer: Buffer): void; | ||
fillImage(keyIndex: KeyIndex, imageBuffer: Buffer, options?: FillImageOptions): void; | ||
fillPanel(imageBuffer: Buffer, options?: FillPanelOptions): void; | ||
clearKey(keyIndex: KeyIndex): void; | ||
@@ -113,3 +124,3 @@ clearAllKeys(): void; | ||
protected abstract transformKeyIndex(keyIndex: KeyIndex): KeyIndex; | ||
protected abstract convertFillImage(imageBuffer: Buffer, sourceOffset: number, sourceStride: number): Buffer; | ||
protected abstract convertFillImage(imageBuffer: Buffer, sourceOptions: InternalFillImageOptions): Buffer; | ||
protected getFillImageCommandHeaderLength(): number; | ||
@@ -124,2 +135,3 @@ protected writeFillImageCommandHeader(buffer: Buffer, keyIndex: number, partIndex: number, isLast: boolean, _bodyLength: number): void; | ||
private checkRGBValue; | ||
private checkSourceFormat; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckBase = void 0; | ||
const events_1 = require("events"); | ||
@@ -22,3 +23,3 @@ const exitHook = require("exit-hook"); | ||
this.keyState = new Array(this.NUM_KEYS).fill(false); | ||
this.device.on('data', data => { | ||
this.device.on('data', (data) => { | ||
// The first byte is a report ID, the last byte appears to be padding. | ||
@@ -42,3 +43,3 @@ // We strip these out for now. | ||
}); | ||
this.device.on('error', err => { | ||
this.device.on('error', (err) => { | ||
this.emit('error', err); | ||
@@ -60,4 +61,7 @@ }); | ||
get ICON_BYTES() { | ||
return this.ICON_SIZE * this.ICON_SIZE * 3; | ||
return this.ICON_PIXELS * 3; | ||
} | ||
get ICON_PIXELS() { | ||
return this.ICON_SIZE * this.ICON_SIZE; | ||
} | ||
get MODEL() { | ||
@@ -73,17 +77,37 @@ return this.deviceProperties.MODEL; | ||
const keyIndex2 = this.transformKeyIndex(keyIndex); | ||
this.fillImageRange(keyIndex2, pixels, 0, this.ICON_SIZE * 3); | ||
// TODO - this could be cleverer and skip all the transform logic, but I dont expect it to be used enough to justify that | ||
this.fillImageRange(keyIndex2, pixels, { | ||
format: 'rgb', | ||
offset: 0, | ||
stride: this.ICON_SIZE * 3, | ||
}); | ||
} | ||
fillImage(keyIndex, imageBuffer) { | ||
fillImage(keyIndex, imageBuffer, options) { | ||
var _a; | ||
this.checkValidKeyIndex(keyIndex); | ||
if (imageBuffer.length !== this.ICON_BYTES) { | ||
throw new RangeError(`Expected image buffer of length ${this.ICON_BYTES}, got length ${imageBuffer.length}`); | ||
const sourceFormat = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : 'rgb'; | ||
this.checkSourceFormat(sourceFormat); | ||
const imageSize = this.ICON_PIXELS * sourceFormat.length; | ||
if (imageBuffer.length !== imageSize) { | ||
throw new RangeError(`Expected image buffer of length ${imageSize}, got length ${imageBuffer.length}`); | ||
} | ||
const keyIndex2 = this.transformKeyIndex(keyIndex); | ||
this.fillImageRange(keyIndex2, imageBuffer, 0, this.ICON_SIZE * 3); | ||
this.fillImageRange(keyIndex2, imageBuffer, { | ||
format: sourceFormat, | ||
offset: 0, | ||
stride: this.ICON_SIZE * sourceFormat.length, | ||
}); | ||
} | ||
fillPanel(imageBuffer) { | ||
if (imageBuffer.length !== this.ICON_BYTES * this.NUM_KEYS) { | ||
throw new RangeError(`Expected image buffer of length ${this.ICON_BYTES * this.NUM_KEYS}, got length ${imageBuffer.length}`); | ||
fillPanel(imageBuffer, options) { | ||
var _a; | ||
const sourceFormat = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : 'rgb'; | ||
this.checkSourceFormat(sourceFormat); | ||
const imageSize = this.ICON_PIXELS * sourceFormat.length * this.NUM_KEYS; | ||
if (imageBuffer.length !== imageSize) { | ||
throw new RangeError(`Expected image buffer of length ${imageSize}, got length ${imageBuffer.length}`); | ||
} | ||
const iconSize = this.ICON_SIZE * sourceFormat.length; | ||
const stride = iconSize * this.KEY_COLUMNS; | ||
for (let row = 0; row < this.KEY_ROWS; row++) { | ||
const rowOffset = stride * row * this.ICON_SIZE; | ||
for (let column = 0; column < this.KEY_COLUMNS; column++) { | ||
@@ -97,6 +121,8 @@ let index = row * this.KEY_COLUMNS; | ||
} | ||
const stride = this.ICON_SIZE * 3 * this.KEY_COLUMNS; | ||
const rowOffset = stride * row * this.ICON_SIZE; | ||
const colOffset = column * this.ICON_SIZE * 3; | ||
this.fillImageRange(index, imageBuffer, rowOffset + colOffset, stride); | ||
const colOffset = column * iconSize; | ||
this.fillImageRange(index, imageBuffer, { | ||
format: sourceFormat, | ||
offset: rowOffset + colOffset, | ||
stride, | ||
}); | ||
} | ||
@@ -184,5 +210,5 @@ } | ||
} | ||
fillImageRange(keyIndex, imageBuffer, sourceOffset, sourceStride) { | ||
fillImageRange(keyIndex, imageBuffer, sourceOptions) { | ||
this.checkValidKeyIndex(keyIndex); | ||
const byteBuffer = this.convertFillImage(imageBuffer, sourceOffset, sourceStride); | ||
const byteBuffer = this.convertFillImage(imageBuffer, sourceOptions); | ||
const packets = this.generateFillImageWrites(keyIndex, byteBuffer); | ||
@@ -203,3 +229,17 @@ for (const packet of packets) { | ||
} | ||
checkSourceFormat(format) { | ||
switch (format) { | ||
case 'rgb': | ||
case 'rgba': | ||
case 'bgr': | ||
case 'bgra': | ||
break; | ||
default: { | ||
const fmt = format; | ||
throw new TypeError(`Expected a known color format not "${fmt}"`); | ||
} | ||
} | ||
} | ||
} | ||
exports.StreamDeckBase = StreamDeckBase; | ||
//# sourceMappingURL=base.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DeviceModelId = void 0; | ||
var DeviceModelId; | ||
@@ -10,1 +11,2 @@ (function (DeviceModelId) { | ||
})(DeviceModelId = exports.DeviceModelId || (exports.DeviceModelId = {})); | ||
//# sourceMappingURL=id.js.map |
export * from './id'; | ||
export { OpenStreamDeckOptions, StreamDeck } from './base'; | ||
export { OpenStreamDeckOptions, StreamDeck, FillImageOptions, FillPanelOptions } from './base'; | ||
export { StreamDeckOriginal } from './original'; | ||
@@ -4,0 +4,0 @@ export { StreamDeckMini } from './mini'; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./id")); | ||
exports.StreamDeckOriginalV2 = exports.StreamDeckXL = exports.StreamDeckMini = exports.StreamDeckOriginal = void 0; | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./id"), exports); | ||
var original_1 = require("./original"); | ||
exports.StreamDeckOriginal = original_1.StreamDeckOriginal; | ||
Object.defineProperty(exports, "StreamDeckOriginal", { enumerable: true, get: function () { return original_1.StreamDeckOriginal; } }); | ||
var mini_1 = require("./mini"); | ||
exports.StreamDeckMini = mini_1.StreamDeckMini; | ||
Object.defineProperty(exports, "StreamDeckMini", { enumerable: true, get: function () { return mini_1.StreamDeckMini; } }); | ||
var xl_1 = require("./xl"); | ||
exports.StreamDeckXL = xl_1.StreamDeckXL; | ||
Object.defineProperty(exports, "StreamDeckXL", { enumerable: true, get: function () { return xl_1.StreamDeckXL; } }); | ||
var originalv2_1 = require("./originalv2"); | ||
exports.StreamDeckOriginalV2 = originalv2_1.StreamDeckOriginalV2; | ||
Object.defineProperty(exports, "StreamDeckOriginalV2", { enumerable: true, get: function () { return originalv2_1.StreamDeckOriginalV2; } }); | ||
//# sourceMappingURL=index.js.map |
/// <reference types="node" /> | ||
import { OpenStreamDeckOptions, StreamDeckBase } from './base'; | ||
import { OpenStreamDeckOptions, StreamDeckBase, InternalFillImageOptions } from './base'; | ||
import { KeyIndex, StreamDeckDeviceInfo } from './id'; | ||
@@ -7,5 +7,5 @@ export declare class StreamDeckMini extends StreamDeckBase { | ||
protected transformKeyIndex(keyIndex: KeyIndex): KeyIndex; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOffset: number, sourceStride: number): Buffer; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOptions: InternalFillImageOptions): Buffer; | ||
protected getFillImagePacketLength(): number; | ||
private rotateCoordinates; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckMini = void 0; | ||
const util_1 = require("../util"); | ||
@@ -12,3 +13,3 @@ const base_1 = require("./base"); | ||
KEY_DIRECTION: 'ltr', | ||
KEY_DATA_OFFSET: 1 | ||
KEY_DATA_OFFSET: 1, | ||
}; | ||
@@ -22,4 +23,4 @@ class StreamDeckMini extends base_1.StreamDeckBase { | ||
} | ||
convertFillImage(sourceBuffer, sourceOffset, sourceStride) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOffset, sourceStride, util_1.BMP_HEADER_LENGTH, this.rotateCoordinates.bind(this), 'bgr', this.ICON_SIZE); | ||
convertFillImage(sourceBuffer, sourceOptions) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOptions, util_1.BMP_HEADER_LENGTH, this.rotateCoordinates.bind(this), 'bgr', this.ICON_SIZE); | ||
util_1.writeBMPHeader(byteBuffer, this.ICON_SIZE, this.ICON_BYTES, 2835); | ||
@@ -36,1 +37,2 @@ return byteBuffer; | ||
exports.StreamDeckMini = StreamDeckMini; | ||
//# sourceMappingURL=mini.js.map |
/// <reference types="node" /> | ||
import { OpenStreamDeckOptions, StreamDeckBase } from './base'; | ||
import { OpenStreamDeckOptions, StreamDeckBase, InternalFillImageOptions } from './base'; | ||
import { KeyIndex, StreamDeckDeviceInfo } from './id'; | ||
@@ -9,5 +9,5 @@ export declare class StreamDeckOriginal extends StreamDeckBase { | ||
protected getFillImagePacketLength(): number; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOffset: number, sourceStride: number): Buffer; | ||
protected convertFillImage(sourceBuffer: Buffer, sourceOptions: InternalFillImageOptions): Buffer; | ||
protected generateFillImageWrites(keyIndex: KeyIndex, byteBuffer: Buffer): Buffer[]; | ||
private flipCoordinates; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckOriginal = void 0; | ||
const util_1 = require("../util"); | ||
@@ -12,3 +13,3 @@ const base_1 = require("./base"); | ||
KEY_DIRECTION: 'rtl', | ||
KEY_DATA_OFFSET: 1 | ||
KEY_DATA_OFFSET: 1, | ||
}; | ||
@@ -34,4 +35,4 @@ class StreamDeckOriginal extends base_1.StreamDeckBase { | ||
} | ||
convertFillImage(sourceBuffer, sourceOffset, sourceStride) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOffset, sourceStride, util_1.BMP_HEADER_LENGTH, this.flipCoordinates.bind(this), 'bgr', this.ICON_SIZE); | ||
convertFillImage(sourceBuffer, sourceOptions) { | ||
const byteBuffer = util_1.imageToByteArray(sourceBuffer, sourceOptions, util_1.BMP_HEADER_LENGTH, this.flipCoordinates.bind(this), 'bgr', this.ICON_SIZE); | ||
util_1.writeBMPHeader(byteBuffer, this.ICON_SIZE, this.ICON_BYTES, 3780); | ||
@@ -58,1 +59,2 @@ return byteBuffer; | ||
exports.StreamDeckOriginal = StreamDeckOriginal; | ||
//# sourceMappingURL=original.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckOriginalV2 = void 0; | ||
const base_gen2_1 = require("./base-gen2"); | ||
@@ -11,3 +12,3 @@ const id_1 = require("./id"); | ||
KEY_DIRECTION: 'ltr', | ||
KEY_DATA_OFFSET: 4 | ||
KEY_DATA_OFFSET: 4, | ||
}; | ||
@@ -20,1 +21,2 @@ class StreamDeckOriginalV2 extends base_gen2_1.StreamDeckGen2Base { | ||
exports.StreamDeckOriginalV2 = StreamDeckOriginalV2; | ||
//# sourceMappingURL=originalv2.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.StreamDeckXL = void 0; | ||
const base_gen2_1 = require("./base-gen2"); | ||
@@ -11,3 +12,3 @@ const id_1 = require("./id"); | ||
KEY_DIRECTION: 'ltr', | ||
KEY_DATA_OFFSET: 4 | ||
KEY_DATA_OFFSET: 4, | ||
}; | ||
@@ -20,1 +21,2 @@ class StreamDeckXL extends base_gen2_1.StreamDeckGen2Base { | ||
exports.StreamDeckXL = StreamDeckXL; | ||
//# sourceMappingURL=xl.js.map |
/// <reference types="node" /> | ||
import { InternalFillImageOptions } from './models/base'; | ||
export declare function numberArrayToString(array: number[]): string; | ||
export declare function imageToByteArray(imageBuffer: Buffer, sourceOffset: number, sourceStride: number, destOffset: number, transformCoordinates: (x: number, y: number) => { | ||
export declare function imageToByteArray(imageBuffer: Buffer, sourceOptions: InternalFillImageOptions, destPadding: number, transformCoordinates: (x: number, y: number) => { | ||
x: number; | ||
@@ -5,0 +6,0 @@ y: number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.writeBMPHeader = exports.BMP_HEADER_LENGTH = exports.imageToByteArray = exports.numberArrayToString = void 0; | ||
function numberArrayToString(array) { | ||
@@ -8,27 +9,30 @@ const end = array.indexOf(0); | ||
} | ||
return array.map(val => String.fromCharCode(val)).join(''); | ||
return array.map((val) => String.fromCharCode(val)).join(''); | ||
} | ||
exports.numberArrayToString = numberArrayToString; | ||
function imageToByteArray(imageBuffer, sourceOffset, sourceStride, destOffset, transformCoordinates, colorMode, imageSize) { | ||
const byteBuffer = Buffer.alloc(destOffset + imageSize * imageSize * colorMode.length); | ||
function imageToByteArray(imageBuffer, sourceOptions, destPadding, transformCoordinates, colorMode, imageSize) { | ||
const byteBuffer = Buffer.alloc(destPadding + imageSize * imageSize * colorMode.length); | ||
const flipColours = sourceOptions.format.substring(0, 3) !== colorMode.substring(0, 3); | ||
for (let y = 0; y < imageSize; y++) { | ||
const rowOffset = destOffset + imageSize * colorMode.length * y; | ||
const rowOffset = destPadding + imageSize * colorMode.length * y; | ||
for (let x = 0; x < imageSize; x++) { | ||
const { x: x2, y: y2 } = transformCoordinates(x, y); | ||
const i = y2 * sourceStride + sourceOffset + x2 * 3; | ||
const red = imageBuffer.readUInt8(i); | ||
const green = imageBuffer.readUInt8(i + 1); | ||
const blue = imageBuffer.readUInt8(i + 2); | ||
const offset = rowOffset + x * colorMode.length; | ||
if (colorMode === 'bgr') { | ||
byteBuffer.writeUInt8(blue, offset); | ||
byteBuffer.writeUInt8(green, offset + 1); | ||
byteBuffer.writeUInt8(red, offset + 2); | ||
const srcOffset = y2 * sourceOptions.stride + sourceOptions.offset + x2 * sourceOptions.format.length; | ||
const red = imageBuffer.readUInt8(srcOffset); | ||
const green = imageBuffer.readUInt8(srcOffset + 1); | ||
const blue = imageBuffer.readUInt8(srcOffset + 2); | ||
const targetOffset = rowOffset + x * colorMode.length; | ||
if (flipColours) { | ||
byteBuffer.writeUInt8(blue, targetOffset); | ||
byteBuffer.writeUInt8(green, targetOffset + 1); | ||
byteBuffer.writeUInt8(red, targetOffset + 2); | ||
} | ||
else { | ||
byteBuffer.writeUInt8(red, offset); | ||
byteBuffer.writeUInt8(green, offset + 1); | ||
byteBuffer.writeUInt8(blue, offset + 2); | ||
byteBuffer.writeUInt8(255, offset + 3); | ||
byteBuffer.writeUInt8(red, targetOffset); | ||
byteBuffer.writeUInt8(green, targetOffset + 1); | ||
byteBuffer.writeUInt8(blue, targetOffset + 2); | ||
} | ||
if (colorMode.length === 4) { | ||
byteBuffer.writeUInt8(255, targetOffset + 3); | ||
} | ||
} | ||
@@ -62,1 +66,2 @@ } | ||
exports.writeBMPHeader = writeBMPHeader; | ||
//# sourceMappingURL=util.js.map |
{ | ||
"name": "elgato-stream-deck", | ||
"version": "3.3.5", | ||
"version": "4.0.0", | ||
"description": "An npm module for interfacing with the Elgato Stream Deck", | ||
@@ -48,6 +48,6 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"build": "trash dist && yarn build:main", | ||
"build": "rimraf dist && yarn build:main", | ||
"build:main": "tsc -p tsconfig.build.json", | ||
"release": "standard-version", | ||
"test": "yarn lint && yarn build && yarn unit", | ||
"test": "yarn lint && yarn unit", | ||
"watch": "jest --watch", | ||
@@ -57,7 +57,7 @@ "cov": "jest --coverage; open-cli coverage/lcov-report/index.html", | ||
"testci": "yarn lint && jest --coverage", | ||
"send-coverage": "cat ./coverage/lcov.info | coveralls", | ||
"send-coverage": "codecov", | ||
"unit": "jest", | ||
"lint": "eslint . --ext .ts", | ||
"lint": "eslint . --ext .ts --ext .js --ignore-pattern dist", | ||
"validate:dependencies": "yarn audit --groups dependencies && yarn license-validate", | ||
"license-validate": "node-license-validator -p -d --allow-licenses MIT 0BSD BSD BSD-3-Clause ISC Apache Unlicense WTFPL" | ||
"license-validate": "yarn sofie-licensecheck --allowPackages buffers@0.1.1" | ||
}, | ||
@@ -68,3 +68,3 @@ "files": [ | ||
"engines": { | ||
"node": ">=7.6" | ||
"node": ">=10.10" | ||
}, | ||
@@ -74,49 +74,42 @@ "dependencies": { | ||
"jpeg-js": "^0.4.2", | ||
"node-hid": "^1.2.0" | ||
"node-hid": "^2.1.1" | ||
}, | ||
"prettier": "@sofie-automation/code-standard-preset/.prettierrc.json", | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.{js,css,json,md,scss}": [ | ||
"prettier --write" | ||
], | ||
"*.{ts,tsx}": [ | ||
"yarn lint --fix" | ||
] | ||
}, | ||
"devDependencies": { | ||
"@julusian/jpeg-turbo": "^0.5.3", | ||
"@types/jest": "^25.1.4", | ||
"@julusian/jpeg-turbo": "^1.0.0", | ||
"@sofie-automation/code-standard-preset": "^0.2.1", | ||
"@types/jest": "^26.0.19", | ||
"@types/jpeg-js": "^0.3.0", | ||
"@types/node": "^12.0.4", | ||
"@types/node-hid": "^1.2.0", | ||
"@types/sharp": "^0.24.0", | ||
"@typescript-eslint/eslint-plugin": "^2.30.0", | ||
"@typescript-eslint/parser": "^2.30.0", | ||
"coveralls": "^3.0.3", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-prettier": "^3.1.3", | ||
"jest": "^25.1.0", | ||
"jest-haste-map": "^25.1.0", | ||
"jest-resolve": "^25.1.0", | ||
"node-license-validator": "^1.3.0", | ||
"open-cli": "^5.0.0", | ||
"prettier": "^1.17.1", | ||
"@types/node": "^14.14.14", | ||
"@types/node-hid": "^1.3.0", | ||
"@types/sharp": "^0.26.1", | ||
"codecov": "^3.8.1", | ||
"jest": "^26.6.3", | ||
"jest-haste-map": "^26.6.2", | ||
"jest-resolve": "^26.6.2", | ||
"jimp": "^0.16.1", | ||
"open-cli": "^6.0.1", | ||
"pureimage": "^0.2.5", | ||
"sharp": "~0.23.3", | ||
"standard-version": "^7.0.0", | ||
"rimraf": "^3.0.2", | ||
"sharp": "~0.27.0", | ||
"standard-version": "^9.0.0", | ||
"stream-buffers": "^3.0.1", | ||
"trash-cli": "^3.0.0", | ||
"ts-jest": "^25.2.1", | ||
"ts-loader": "^6.0.0", | ||
"ts-node": "^8.1.0", | ||
"typescript": "~3.6.4", | ||
"usb-detection": "^4.3.0" | ||
}, | ||
"resolutions": { | ||
"**/conventional-changelog-angular": "5.0.6", | ||
"**/conventional-changelog-atom": "2.0.3", | ||
"**/conventional-changelog-codemirror": "2.0.3", | ||
"**/conventional-changelog-core": "4.1.3", | ||
"**/conventional-changelog-conventionalcommits": "4.2.3", | ||
"**/conventional-changelog-ember": "2.0.4", | ||
"**/conventional-changelog-eslint": "3.0.4", | ||
"**/conventional-changelog-express": "2.0.1", | ||
"**/conventional-changelog-jshint": "2.0.3", | ||
"**/conventional-changelog-preset-loader": "2.3.0", | ||
"**/conventional-changelog-writer": "4.0.11", | ||
"**/conventional-commits-filter": "2.0.2", | ||
"**/conventional-commits-parser": "3.0.8" | ||
"ts-jest": "^26.4.4", | ||
"ts-node": "^9.1.1", | ||
"typescript": "~4.1.3", | ||
"usb-detection": "^4.10.0" | ||
} | ||
} |
@@ -6,6 +6,3 @@ # elgato-stream-deck | ||
![Node CI](https://github.com/Julusian/node-elgato-stream-deck/workflows/Node%20CI/badge.svg) | ||
[![Coverage Status](https://coveralls.io/repos/github/Julusian/node-elgato-stream-deck/badge.svg?branch=master)](https://coveralls.io/github/Julusian/node-elgato-stream-deck?branch=master) | ||
![alt text](media/streamdeck_ui.png 'elgato-stream-deck') | ||
[`elgato-stream-deck`](https://github.com/julusian/elgato-stream-deck) is a Node.js library for interfacing | ||
@@ -24,5 +21,5 @@ with the various models of the [Elgato Stream Deck](https://www.elgato.com/en/gaming/stream-deck). | ||
`$ npm install --save @julusian/jpeg-turbo@^0.5.3` (Optional) | ||
`$ npm install --save @julusian/jpeg-turbo@^1.0.0` (Optional) | ||
It is recommended to install `@julusian/jpeg-turbo@^0.5.3` to greatly improve performance for writing images to the StreamDeck XL or the Original-v2. Without doing so `jpeg-js` will be used instead, but image transfers will be noticably more cpu intensive and slower. `jpeg-turbo` has prebuilt binaries, but is not installed by default to ensure installation time is kept to a minimum for users who do not need the performance or the XL or the Original-v2. | ||
It is recommended to install `@julusian/jpeg-turbo` to greatly improve performance for writing images to the StreamDeck XL or the Original-v2. Without doing so `jpeg-js` will be used instead, but image transfers will be noticably more cpu intensive and slower. `jpeg-turbo` has prebuilt binaries, but is not installed by default to ensure installation is easy for users who do not need the performance or the XL or the Original-v2. | ||
@@ -64,13 +61,3 @@ ### Linux | ||
* Linux (**including Raspberry Pi**) | ||
* Follow the instructions for Linux in the ["Compiling from source"](https://github.com/node-hid/node-hid#compiling-from-source) steps for `node-hid`: | ||
```bash | ||
sudo apt-get install build-essential git | ||
sudo apt-get install gcc-4.8 g++-4.8 && export CXX=g++-4.8 | ||
sudo apt-get install sudo apt install libusb-1.0-0 libusb-1.0-0-dev | ||
``` | ||
* Install a recent version of Node.js.: | ||
```bash | ||
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - | ||
sudo apt-get install -y nodejs | ||
``` | ||
* Follow the instructions for Linux in the ["Compiling from source"](https://github.com/node-hid/node-hid#compiling-from-source) steps for | ||
* Try installing `node-elgato-stream-deck` | ||
@@ -133,7 +120,7 @@ * If you still have issues, ensure everything is updated and try again: | ||
myStreamDeck.on('down', keyIndex => { | ||
myStreamDeck.on('down', (keyIndex) => { | ||
console.log('key %d down', keyIndex) | ||
}) | ||
myStreamDeck.on('up', keyIndex => { | ||
myStreamDeck.on('up', (keyIndex) => { | ||
console.log('key %d up', keyIndex) | ||
@@ -144,3 +131,3 @@ }) | ||
// Always add a listener for this event! If you don't, errors will be silently dropped. | ||
myStreamDeck.on('error', error => { | ||
myStreamDeck.on('error', (error) => { | ||
console.error(error) | ||
@@ -199,3 +186,3 @@ }) | ||
const streamDeck = openStreamDeck('0001:0021:00', { | ||
useOriginalKeyOrder: true | ||
useOriginalKeyOrder: true, | ||
}) | ||
@@ -274,6 +261,6 @@ ``` | ||
.toBuffer() | ||
.then(buffer => { | ||
.then((buffer) => { | ||
streamDeck.fillImage(2, buffer) | ||
}) | ||
.catch(err => { | ||
.catch((err) => { | ||
console.error(err) | ||
@@ -297,6 +284,6 @@ }) | ||
.toBuffer() | ||
.then(buffer => { | ||
.then((buffer) => { | ||
streamDeck.fillPanel(buffer) | ||
}) | ||
.catch(err => { | ||
.catch((err) => { | ||
console.error(err) | ||
@@ -381,3 +368,3 @@ }) | ||
```javascript | ||
streamDeck.on('down', keyIndex => { | ||
streamDeck.on('down', (keyIndex) => { | ||
console.log('key %d down', keyIndex) | ||
@@ -394,3 +381,3 @@ }) | ||
```javascript | ||
streamDeck.on('up', keyIndex => { | ||
streamDeck.on('up', (keyIndex) => { | ||
console.log('key %d up', keyIndex) | ||
@@ -408,3 +395,3 @@ }) | ||
```javascript | ||
streamDeck.on('error', error => { | ||
streamDeck.on('error', (error) => { | ||
console.error(error) | ||
@@ -411,0 +398,0 @@ }) |
85919
22
37
878
399
+ Addeddecompress-response@6.0.0(transitive)
+ Addeddetect-libc@2.0.3(transitive)
+ Addedmimic-response@3.1.0(transitive)
+ Addednode-abi@3.64.0(transitive)
+ Addednode-addon-api@3.2.1(transitive)
+ Addednode-hid@2.2.0(transitive)
+ Addedprebuild-install@7.1.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsemver@7.6.2(transitive)
+ Addedsimple-get@4.0.1(transitive)
+ Addedstring_decoder@1.3.0(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedaproba@1.2.0(transitive)
- Removedare-we-there-yet@1.1.7(transitive)
- Removedcode-point-at@1.1.0(transitive)
- Removedconsole-control-strings@1.1.0(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddecompress-response@4.2.1(transitive)
- Removeddelegates@1.0.0(transitive)
- Removeddetect-libc@1.0.3(transitive)
- Removedgauge@2.7.4(transitive)
- Removedhas-unicode@2.0.1(transitive)
- Removedis-fullwidth-code-point@1.0.0(transitive)
- Removedisarray@1.0.0(transitive)
- Removedmimic-response@2.1.0(transitive)
- Removednan@2.19.0(transitive)
- Removednode-abi@2.30.1(transitive)
- Removednode-hid@1.3.2(transitive)
- Removednpmlog@4.1.2(transitive)
- Removednumber-is-nan@1.0.1(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedprebuild-install@6.1.4(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedsemver@5.7.2(transitive)
- Removedset-blocking@2.0.0(transitive)
- Removedsignal-exit@3.0.7(transitive)
- Removedsimple-get@3.1.1(transitive)
- Removedstring-width@1.0.2(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedwide-align@1.1.5(transitive)
Updatednode-hid@^2.1.1