@elgato-stream-deck/core
Version:
An npm module for interfacing with the Elgato Stream Deck
94 lines • 4.84 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamdeckDefaultLcdService = void 0;
const headerGenerator_js_1 = require("../imageWriter/headerGenerator.js");
const imageWriter_js_1 = require("../imageWriter/imageWriter.js");
const util_js_1 = require("../../util.js");
const preparedBuffer_js_1 = require("../../preparedBuffer.js");
class StreamdeckDefaultLcdService {
#encodeJPEG;
#device;
#lcdControls;
#rotate;
#modelId;
#lcdImageWriter = new imageWriter_js_1.StreamdeckDefaultImageWriter(new headerGenerator_js_1.StreamdeckDefaultLcdImageHeaderGenerator());
constructor(encodeJPEG, device, lcdControls, rotate, modelId) {
this.#encodeJPEG = encodeJPEG;
this.#device = device;
this.#lcdControls = lcdControls;
this.#rotate = rotate;
this.#modelId = modelId;
}
async fillLcd(index, buffer, sourceOptions) {
const lcdControl = this.#lcdControls.find((control) => control.id === index);
if (!lcdControl)
throw new Error(`Invalid lcd segment index ${index}`);
const packets = await this.prepareFillControlRegion(lcdControl, 0, 0, buffer, {
format: sourceOptions.format,
width: lcdControl.pixelSize.width,
height: lcdControl.pixelSize.height,
});
await this.#device.sendReports(packets);
}
async fillLcdRegion(index, x, y, imageBuffer, sourceOptions) {
const lcdControl = this.#lcdControls.find((control) => control.id === index);
if (!lcdControl)
throw new Error(`Invalid lcd segment index ${index}`);
const packets = await this.prepareFillControlRegion(lcdControl, x, y, imageBuffer, sourceOptions);
await this.#device.sendReports(packets);
}
async prepareFillLcdRegion(index, x, y, imageBuffer, sourceOptions, jsonSafe) {
const lcdControl = this.#lcdControls.find((control) => control.id === index);
if (!lcdControl)
throw new Error(`Invalid lcd segment index ${index}`);
const packets = await this.prepareFillControlRegion(lcdControl, x, y, imageBuffer, sourceOptions);
return (0, preparedBuffer_js_1.wrapBufferToPreparedBuffer)(this.#modelId, 'fill-lcd-region', packets, jsonSafe ?? false);
}
async clearLcdSegment(index) {
const lcdControl = this.#lcdControls.find((control) => control.id === index);
if (!lcdControl)
throw new Error(`Invalid lcd segment index ${index}`);
const buffer = new Uint8Array(lcdControl.pixelSize.width * lcdControl.pixelSize.height * 4);
const packets = await this.prepareFillControlRegion(lcdControl, 0, 0, buffer, {
format: 'rgba',
width: lcdControl.pixelSize.width,
height: lcdControl.pixelSize.height,
});
await this.#device.sendReports(packets);
}
async clearAllLcdSegments() {
const ps = [];
for (const control of this.#lcdControls) {
ps.push(this.clearLcdSegment(control.id));
}
await Promise.all(ps);
}
async prepareFillControlRegion(lcdControl, x, y, imageBuffer, sourceOptions) {
// Basic bounds checking
const maxSize = lcdControl.pixelSize;
if (x < 0 || x + sourceOptions.width > maxSize.width) {
throw new TypeError(`Image will not fit within the lcd segment`);
}
if (y < 0 || y + sourceOptions.height > maxSize.height) {
throw new TypeError(`Image will not fit within the lcd segment`);
}
const imageSize = sourceOptions.width * sourceOptions.height * sourceOptions.format.length;
if (imageBuffer.length !== imageSize) {
throw new RangeError(`Expected image buffer of length ${imageSize}, got length ${imageBuffer.length}`);
}
// A lot of this drawing code is heavily based on the normal button
const byteBuffer = await this.convertFillLcdBuffer(imageBuffer, sourceOptions);
return this.#lcdImageWriter.generateFillImageWrites({ ...sourceOptions, x, y }, byteBuffer);
}
async convertFillLcdBuffer(sourceBuffer, sourceOptions) {
const sourceOptions2 = {
format: sourceOptions.format,
offset: 0,
stride: sourceOptions.width * sourceOptions.format.length,
};
const byteBuffer = (0, util_js_1.transformImageBuffer)(sourceBuffer, sourceOptions2, { colorMode: 'rgba', rotate: this.#rotate, yFlip: this.#rotate }, 0, sourceOptions.width, sourceOptions.height);
return this.#encodeJPEG(byteBuffer, this.#rotate ? sourceOptions.height : sourceOptions.width, this.#rotate ? sourceOptions.width : sourceOptions.height);
}
}
exports.StreamdeckDefaultLcdService = StreamdeckDefaultLcdService;
//# sourceMappingURL=generic.js.map