{"id":19952200,"url":"https://github.com/timluq/stream-deck-ts","last_synced_at":"2026-03-03T01:38:18.050Z","repository":{"id":94638605,"uuid":"156381305","full_name":"TimLuq/stream-deck-ts","owner":"TimLuq","description":"A library to interface with a stream deck. Built to be extendable to multiple products.","archived":false,"fork":false,"pushed_at":"2018-11-25T11:33:18.000Z","size":2604,"stargazers_count":10,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-01T19:39:21.496Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TimLuq.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-06T12:36:21.000Z","updated_at":"2023-03-22T20:52:29.000Z","dependencies_parsed_at":"2023-03-30T08:35:28.845Z","dependency_job_id":null,"html_url":"https://github.com/TimLuq/stream-deck-ts","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimLuq%2Fstream-deck-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimLuq%2Fstream-deck-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimLuq%2Fstream-deck-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimLuq%2Fstream-deck-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TimLuq","download_url":"https://codeload.github.com/TimLuq/stream-deck-ts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252241927,"owners_count":21717069,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T01:12:07.900Z","updated_at":"2025-10-07T19:54:43.656Z","avatar_url":"https://github.com/TimLuq.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# stream-deck-ts\n[![Build Status](https://travis-ci.org/TimLuq/stream-deck-ts.svg?branch=master)](https://travis-ci.org/TimLuq/stream-deck-ts)\n[![npm version](https://img.shields.io/npm/v/stream-deck-ts.svg)](https://npm.im/stream-deck-ts)\n[![license](https://img.shields.io/npm/l/stream-deck-ts.svg)](https://npm.im/stream-deck-ts)\n[![dependencies Status](https://david-dm.org/TimLuq/stream-deck-ts/status.svg)](https://david-dm.org/TimLuq/stream-deck-ts)\n[![Coverage Status](https://coveralls.io/repos/github/TimLuq/stream-deck-ts/badge.svg?branch=master)](https://coveralls.io/github/TimLuq/stream-deck-ts?branch=master)\n\nThis is a library for developers to use. It is not a program for end users. It cannot and will not replace the official Stream Deck program. That is not its goal. However, it does enable someone to more easily write a program which *does* do that.\n\n## Supported devices\n\nAny additional devices would be appriciated. If you are able to control another device than those listed - please send a PR.\n\n### Elgato\n- [Elgato Stream Deck](products/elgato/elgato-stream-deck.md).\n- [Elgato Stream Deck Mini](products/elgato/elgato-stream-deck-mini.md).\n\n\n## Install\n\n`$ npm install --save stream-deck-ts`\n\nAll of this library's native dependencies ship with prebuilt binaries, so having a full compiler toolchain should not be necessary to install `stream-deck-ts`.\n\nHowever, in the event that installation _does_ fail (**or if you are on a platform that our dependencies don't provide prebuilt binaries for, such as a Raspberry Pi**), you will need to install a compiler toolchain to enable npm to build some of `stream-deck-ts`'s dependencies from source. Expand the details block below for full instructions on how to do so.\n\n\u003cdetails\u003e\n\t\u003csummary\u003eCompiling dependencies from source\u003c/summary\u003e\n\t\n* Windows\n  * Install [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools):\n  ```bash\n  npm install --global windows-build-tools\n  ```\n* MacOS\n  * Install the Xcode Command Line Tools:\n  ```bash\n  xcode-select --install\n  ```\n* Linux (**including Raspberry Pi**)\n  * Follow the instructions for Linux in the [\"Compiling from source\"](https://github.com/node-hid/node-hid#compiling-from-source) steps for `node-hid`:\n\t```bash\n\tsudo apt-get install build-essential git\n\tsudo apt-get install gcc-4.8 g++-4.8 \u0026\u0026 export CXX=g++-4.8\n\tsudo apt-get install sudo apt install libusb-1.0-0 libusb-1.0-0-dev\n\t```\n  * Install a recent version of Node.js.:\n\t```bash\n\tcurl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -\n\tsudo apt-get install -y nodejs \n\t```\n  * Try installing `stream-deck-ts`\n  * If you still have issues, ensure everything is updated and try again:\n\t```bash\n\tsudo apt-get update \u0026\u0026 sudo apt-get upgrade\n\t```\n\u003c/details\u003e\n\n## Table of Contents\n\n* [Example](#example)\n* [Features](#features)\n* [API](#api)\n  * [Constants](#constants)\n  * [devices()](#devices)\n  * [getStreamDeckProduct(vendor, product)](#getstreamdeckproduct-vendor-product)\n  * [registerStreamDeckProduct(vendor, product, config)](#registerstreamdeckproduct-vendor-product-config)\n  * [selectDevice([vendor[, product]])](#selectdevice-vendor-product)\n  * [selectAllDevices([vendor[, product]])](#selectalldevices-vendor-product)\n  * [setHidAsyncType(asyncMode)](#sethidasynctype-asyncmode)\n  * [Class: StreamDeck](#class-streamdeck)\n    * [Event: 'down'](#event-down)\n    * [Event: 'up'](#event-up)\n    * [Event: 'error'](#event-error)\n\t* [streamDeck.buttonColumns](#streamdeck-buttoncolumns)\n\t* [streamDeck.buttonLength](#streamdeck-buttonlength)\n\t* [streamDeck.buttonRows](#streamdeck-buttonrows)\n\t* [streamDeck.iconSize](#streamdeck-iconsize)\n\t* [streamDeck.pressedKeys](#streamdeck-pressedkeys)\n\t* [streamDeck.buttonIndexFromPosition(x, y)](#streamdeck-buttonindexfromposition-x-y)\n\t* [streamDeck.checkValidKeyIndex(keyIndex)](#streamDeck-checkvalidkeyindex-keyindex)\n\t* [streamDeck.clearAllKeys()](#streamdeck-clearallkeys)\n\t* [streamDeck.clearKey(keyIndex)](#streamdeck-clearkey-keyIndex)\n\t* [streamDeck.fillColor(keyIndex, rgb)](#streamdeck-fillcolor-keyindex-rgb)\n\t* [streamDeck.fillColor(keyIndex, r, g, b)](#streamdeck-fillcolor-keyindex-r-g-b)\n\t* [streamDeck.fillImage(keyIndex, buffer)](#streamdeck-fillimage-keyindex-buffer)\n\t* [streamDeck.fillImageFromFile(keyIndex, filePath)](#streamdeck-fillimagefromfile-keyindex-filepath)\n\t* [streamDeck.fillPanel(imagePathOrBuffer[, rawOptions])](#streamdeck-fillpanel-imagepathorbuffer-rawoptions)\n\t* [streamDeck.forEachKey(callback)](#streamdeck-foreachkey-callback)\n    * [streamDeck.sendFeatureReport(buffer)](#streamdeck-sendfeaturereport-buffer)\n    * [streamDeck.setBrightness(percentage)](#streamdeck-setbrightness-percentage)\n    * [streamDeck.setImageLibrary(library)](#streamdeck-setimagelibrary-library)\n\t* [streamDeck.write(buffer)](#streamdeck-write-buffer)\n\t* [streamDeck.writeMulti(buffers)](#streamdeck-writemulti-buffers)\n  * [Abstract class: StreamDeckBase](#abstract-class-streamdeckbase)\n  * [Interface: IImageLibrary](#interface-iimagelibrary)\n  \t* [IImageLibrary.extract(options)](#iimagelibrary-extract-options)\n  \t* [IImageLibrary.flatten()](#iimagelibrary-flatten)\n  \t* [IImageLibrary.resize(width, height)](#iimagelibrary-resize-width-height)\n  \t* [IImageLibrary.toUint8Array()](#iimagelibrary-touint8array)\n  * [Interface: IImageLibraryCreator](#interface-iimagelibrarycreator)\n  \t* [IImageLibraryCreator.createRaw(options)](#iimagelibrarycreator-createraw-data-rawoptions)\n  \t* [IImageLibraryCreator.loadFile(filepath)](#iimagelibrarycreator-loadfile-filepath)\n  \t* [IImageLibraryCreator.loadFileData(filedata)](#iimagelibrarycreator-loadfiledata-filedata)\n\n## Example\n\n```javascript\nimport { resolve } from \"path\";\nimport { selectDevice } from \"stream-deck-ts\";\n\n(async function asyncMain() {\n\t// Automatically discovers connected Stream Decks, and attaches to the first one.\n\t// Returns `null` if there are no connected stream decks.\n\t// You also have the option of providing the numeric vendor identifier and product identifier.\n\t// For example: `const myStreamDeck = await selectDevice(VENDOR_ELGATO, PRODUCT_ELGATO_STREAMDECK_MINI);`\n\tconst myStreamDeck = await selectDevice();\n\tif (!myStreamDeck) {\n\t\tthrow new Error(\"No StreamDeck found.\");\n\t}\n\n\tmyStreamDeck.on('down', (keyIndex) =\u003e {\n\t\tconsole.log('key %d down', keyIndex);\n\t});\n\n\tmyStreamDeck.on('up', (keyIndex) =\u003e {\n\t\tconsole.log('key %d up', keyIndex);\n\t});\n\n\t// Fired whenever an error is detected by the `node-hid` library.\n\t// Always add a listener for this event!\n\tmyStreamDeck.on('error', (error) =\u003e {\n\t\tconsole.error(error);\n\t});\n\n\t// Fill button 3 with an image of the GitHub logo.\n\t// This is asynchronous and returns a promise.\n\tmyStreamDeck.fillImageFromFile(3, resolve(__dirname, 'github_logo.png')).then(() =\u003e {\n\t\tconsole.log('Successfully wrote a GitHub logo to key 3.');\n\t});\n\n\t// Fill the first button form the left in the first row with a solid red color. This is synchronous.\n\tmyStreamDeck.fillColor(4, 255, 0, 0);\n\tconsole.log('Successfully wrote a red square to key 4.');\n}());\n```\n\n## Features\n\n* Multiplatform support: Windows 7-10, MacOS, Linux, and even Raspberry Pi!\n* Key `down` and key `up` events\n* Fill keys with images or solid RGB colors\n* Fill the entire panel with a single image, spread across all keys\n* Set the Stream Deck brightness\n* TypeScript support\n* Multi device support\n* Optional user supplier image processing library\n\n## API\n\n### Constants\n\n#### Constant: DEVICE_MODELS\n\n- \u0026lt;Object\u0026lt;number, Object\u0026lt;number, Object\u0026gt;\u0026gt;\u0026gt; \n\nAn object containing devices which are supported.\n\n- `DEVICE_MODELS[vendor][device].import` \u0026lt;string\u0026gt; A path to the device implementation.\n- `DEVICE_MODELS[vendor][device].productName` \u0026lt;string\u0026gt; A name representing the product of the device.\n- `DEVICE_MODELS[vendor][device].vendorName` \u0026lt;string\u0026gt; A name representing the vendor of the device.\n\nTo get specific product information [`getStreamDeckProduct`](#getstreamdeckproduct-vendor-product) is the preferred solution.\n\n#### Constant: PRODUCT_ELGATO_STREAMDECK\n\n```js\nexport const PRODUCT_ELGATO_STREAMDECK = 96;\n```\n\nExported constant to use as the `product` filter while selecting a device.\n\n#### Constant: PRODUCT_ELGATO_STREAMDECK_MINI\n\n```js\nexport const PRODUCT_ELGATO_STREAMDECK_MINI = 99;\n```\n\nExported constant to use as the `product` filter while selecting a device.\n\n#### Constant: VENDOR_ELGATO\n\n```js\nexport const VENDOR_ELGATO = 4057;\n```\n\nExported constant to use as the `vendor` filter while selecting a device.\n\n### devices ()\n\n- Returns: \u0026lt;Promise\u0026lt;Object[]\u0026gt;\u0026gt;\n\n* `object.vendorId` \u0026lt;number\u0026gt; Numeric vendor id.\n* `object.productId` \u0026lt;number\u0026gt; Numeric product id.\n* `object.release` \u0026lt;number\u0026gt; Numeric release value.\n* `object.interface` \u0026lt;number\u0026gt; Interface number.\n* `object.path` \u0026lt;string\u0026gt; Path to the specific device.\n\nGet a list of connected HID devices.\n\n### getStreamDeckProduct (vendor, product)\n\n- `vendor` \u0026lt;number\u0026gt; A vendor identity number to register the product to.\n- `product` \u0026lt;number\u0026gt; A product identity number to register the product to.\n- Returns: \u0026lt;Object | undefined\u0026gt; Configuration if one exists.\n\n* `object.import` \u0026lt;string\u0026gt; Module name of the device implementation.\n* `object.productName` \u0026lt;string\u0026gt; Name of the product.\n* `object.vendorName` \u0026lt;string\u0026gt; Name of the vendor.\n\nRegister a `StreamDeck` compatable product. When a device matching the product is selected the module path in `config.import` is loaded and instantiated.\n\nThe module referenced by `config.import` must export a class named `default`. The exported class SHOULD extend [`StreamDeckBase`](#abstract-class-streamdeckbase).\n\n### registerStreamDeckProduct (vendor, product, config)\n\n- `vendor` \u0026lt;number\u0026gt; A vendor identity number to register the product to.\n- `product` \u0026lt;number\u0026gt; A product identity number to register the product to.\n- `config` \u0026lt;Object\u0026gt; The configuration object describing the product.\n- Returns: \u0026lt;Object | undefined\u0026gt; Previous configuration if one existed.\n\n* `config.import` \u0026lt;string\u0026gt; Module name of the device implementation.\n* `config.productName` \u0026lt;string\u0026gt; Name of the product.\n* `config.vendorName` \u0026lt;string\u0026gt; Name of the vendor.\n\nRegister a `StreamDeck` compatable product. When a device matching the product is selected the module path in `config.import` is loaded and instantiated.\n\nThe module referenced by `config.import` must export a class named `default`. The exported class SHOULD extend [`StreamDeckBase`](#abstract-class-streamdeckbase).\n\n### selectDevice ([vendor[, product]])\n\n- `vendor` \u0026lt;number\u0026gt; An optional vendor identity number to limit which device will be selected.\n- `product` \u0026lt;number\u0026gt; An optional product identity number to limit which device will be selected.\n- Returns: \u0026lt;Promise\u0026lt;[StreamDeck](#Class_StreamDeck) | null\u0026gt;\u0026gt;\n\nSelect the first supported device. If no supported device is found `null` is returned.\n\n### selectAllDevices ([vendor[, product]])\n\n- `vendor` \u0026lt;number\u0026gt; An optional vendor identity number to limit which devices will be selected.\n- `product` \u0026lt;number\u0026gt; An optional product identity number to limit which devices will be selected.\n- Returns: \u0026lt;Promise\u0026lt;Array\u0026lt;Promise\u0026lt;[StreamDeck](#Class_StreamDeck)\u0026gt;\u0026gt;\u0026gt;\u0026gt;\n\nGet a list of all supported devices while they're being opened.\n\n### setHidAsyncType (type)\n\n- `type` \u0026lt;string\u0026gt; Sets which type of async provider should be used.\n\nThe async provider type handles how async calls are made.\n\n- `auto` selects one of the other modes available to the system, based on priority.\n- `emulated` will emulate an async environment with microtasks while still running synchronously inside the main thread. This might be good for debugging or as a last resort fallback but should be avoided if possible.\n- `process` creates a [`forked`](https://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options) process to handle the USB communication which is first sent serialized over an IPC channel.\n- `worker` spins up a [`Worker`](https://nodejs.org/api/worker_threads.html) to handle the USB communication, which should be the most performant mode by using transferrable `ByteArray`s. But workers are not currently supported by `node-hid`.\n\n### Class: StreamDeck\n\nInstances of the `StreamDeck` class have an active connection to a device.\n\n#### Event: 'down'\n\n- `keyIndex` \u0026lt;number\u0026gt; The index of the key that got pressed.\n\nThe `down` event is triggered when a button on the Stream Deck has been pressed down.\n\n#### Event: 'up'\n\n- `keyIndex` \u0026lt;number\u0026gt; The index of the key that got released.\n\nThe `up` event is triggered when a button on the Stream Deck has been released which previously had been pressed down.\n\n#### Event: 'error'\n\n- `error` \u0026lt;Error\u0026gt; The index of the key that got released.\n\nFired whenever an error is detected by the `node-hid` library.\n**Always** add a listener for this event! If you don't, errors will be silently dropped.\n\n#### streamDeck .buttonColumns\n\n- \u0026lt;number\u0026gt;\n\nReturns the number of button columns available to this `StreamDeck`.\n\n#### streamDeck. buttonLength\n\n- \u0026lt;number\u0026gt;\n\nReturns the number of buttons available to this `StreamDeck`.\n\n#### streamDeck .buttonRows\n\n- \u0026lt;number\u0026gt;\n\nReturns the number of button rows available to this `StreamDeck`.\n\n#### streamDeck .hasPressedKeys\n\n- \u0026lt;boolean\u0026gt;\n\nA boolean showing if there currently are any pressed keys.\n\n#### streamDeck .iconSize\n\n- \u0026lt;number\u0026gt;\n\nReturns the size in pixels used for icons.\n\n#### streamDeck .pressedKeys\n\n- \u0026lt;Array\u0026lt;number\u0026gt;\u0026gt;\n\nA sorted list of all buttons currently pressed.\n\n#### streamDeck .buttonIndexFromPosition (x, y)\n\n- `x` \u0026lt;number\u0026gt; Cloumn number counted from from the left.\n- `y` \u0026lt;number\u0026gt; Row number counted from from the top.\n- Returns: \u0026lt;number\u0026gt; The `keyIndex` at the given position or `undefined` if out of bounds.\n\nGet the `keyIndex` at a specific column and row.\n\n#### streamDeck .checkValidKeyIndex (keyIndex)\n\n- `keyIndex` \u0026lt;number\u0026gt; Cloumn number counted from from the left.\n- `y` \u0026lt;number\u0026gt; Row number counted from from the top.\n- Returns: \u0026lt;number\u0026gt; The `keyIndex` at the given position or `undefined` if out of bounds.\n\nValidate a `keyIndex`. If the number is not valid the function will throw a `TypeError`, otherwise the same value will be returned.\n\n#### streamDeck .clearAllKeys ()\n\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nSynchronously clears all keys on the device.\n\n##### Example: clear all keys\n\n```javascript\n// Clear all keys.\nstreamDeck.clearAllKeys();\n```\n\n#### streamDeck .clearKey (keyIndex)\n\n- `keyIndex` \u0026lt;number\u0026gt; Key to affect.\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nSynchronously clears the given `keyIndex`'s screen.\n\n##### Example: clear button 2\n\n```javascript\n// Clear button 2.\nstreamDeck.clearKey(2);\n```\n\n#### streamDeck .close ()\n\nCloses this reference to the device.\n\n#### streamDeck .fillColor (keyIndex, rgb)\n\n- `keyIndex` \u0026lt;number\u0026gt; Key to affect.\n- `rgb` \u0026lt;number\u0026gt; Fill color.\n\nSynchronously sets the given `keyIndex`'s screen to a solid RGB color.\n\n##### Example: set button 4 to solid red\n\n```javascript\n// Turn key 4 solid red.\nstreamDeck.fillColor(4, 0xFF0000);\n```\n\n#### streamDeck .fillColor (keyIndex, r, g, b)\n\n- `keyIndex` \u0026lt;number\u0026gt; Key to affect.\n- `r` \u0026lt;number\u0026gt; Red component between `0` - `255`.\n- `g` \u0026lt;number\u0026gt; Green component between `0` - `255`.\n- `b` \u0026lt;number\u0026gt; Blue component between `0` - `255`.\n\nSynchronously sets the given `keyIndex`'s screen to a solid RGB color.\n\n##### Example: set button 5 to solid blue\n\n```javascript\n// Turn key 5 solid blue.\nstreamDeck.fillColor(5, 0, 0, 0xFF);\n```\n\n#### streamDeck .fillImage (keyIndex, buffer)\n\n- `keyIndex` \u0026lt;number\u0026gt; Key to affect.\n- `buffer` \u0026lt;[Buffer](https://nodejs.org/api/buffer.html)\u0026gt; Image bytes.\n- Returns: \u0026lt;Promise\u0026lt;StreamDeck\u0026gt;\u0026gt;\n\nSynchronously writes a buffer of `streamDeck.iconSize` * `streamDeck.iconSize` RGB image data to the given `keyIndex`'s screen.\nThe buffer must be exactly the expected length of bytes. Any other length will result in an error being thrown.\n\n##### Example: fill button 2 with an image of the GitHub logo\n\n```javascript\n// Fill button 2 with an image of the GitHub logo.\nimport * as sharp from \"sharp\"; // See http://sharp.dimens.io/en/stable/ for full docs on this great library!\nimport { resolve } from \"path\";\n\nconst filepath = resolve(__dirname, 'github_logo.png');\nconst buffer = await sharp(filepath)\n\t.flatten() // Eliminate alpha channel, if any.\n\t.resize(streamDeck.iconSize, streamDeck.iconSize) // Scale up/down to the right size, cropping if necessary.\n\t.raw() // Give us uncompressed RGB.\n\t.toBuffer();\n\nstreamDeck.fillImage(2, buffer);\n```\n\n#### streamDeck .fillImageFromFile (keyIndex, filePath)\n\n- `keyIndex` \u0026lt;number\u0026gt; Key to affect.\n- `filePath` \u0026lt;string\u0026gt; File system path to an image file.\n- Returns: \u0026lt;Promise\u0026lt;StreamDeck\u0026gt;\u0026gt;\n\nAsynchronously reads an image from `filePath` and sets the given `keyIndex`'s screen to that image.\nAutomatically scales the image to the expected height and width and strips out the alpha channel.\nIf necessary, the image will be center-cropped to fit into a square.\n\n##### Example: fill the button 3 with an image of the GitHub logo\n\n```javascript\n// Fill the button 3 with an image of the GitHub logo.\nawait streamDeck.fillImageFromFile(3, path.resolve(__dirname, 'github_logo.png'));\nconsole.log('Successfully wrote a GitHub logo to key 3.');\n```\n\n#### streamDeck .fillPanel (imagePathOrBuffer[, rawOptions])\n\n- `imagePathOrBuffer` \u0026lt;string | Uint8Array | [Buffer](https://nodejs.org/api/buffer.html)\u0026gt; Image data or path to a file.\n- `rawOptions` \u0026lt;object\u0026gt; Optional options object used if the image buffer contained raw pixel data.\n  - `rawOptions.channels` \u0026lt;number\u0026gt; Number of channels per pixel. `RGBA = 4`.\n  - `rawOptions.height` \u0026lt;number\u0026gt; Height in pixels.\n  - `rawOptions.width` \u0026lt;number\u0026gt; Width in pixels.\n- Returns: \u0026lt;Promise\u0026lt;StreamDeck\u0026gt;\u0026gt;\n\nAsynchronously applies an image to the entire panel, spreading it over all keys. The image is scaled down and center-cropped to fit. This method does not currently account for the gaps between keys, and behaves as if each key was directly connected to its neighbors. If you wish to account for the gaps between keys, you'll need to do so via other means, and bake that into the image you provide to `fillPanel`.\n\nThis method accepts either a path to an image on the disk, or a buffer. The image path or buffer is passed directly to [`sharp`](https://github.com/lovell/sharp). Therefore, this method accepts all images and buffers which `sharp` can accept.\n\n##### Example: fill the entire panel with a photo of a sunny field\n\n```javascript\n// Fill the entire panel with a photo of a sunny field.\nimport { resolve } from \"path\";\n\nconst filepath = resolve(__dirname, 'examples/fixtures/sunny_field.png');\nawait streamDeck.fillPanel(filepath);\nconsole.log('Successfully filled the panel with an image.');\n```\n\n#### streamDeck .forEachKey (callback)\n\n- `callback` \u0026lt;Function\u0026gt; The function to call for each button in the stream deck.\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nExecute a function for each button available to the `StreamDeck`.\n\n#### streamDeck .sendFeatureReport (buffer)\n\n- `buffer` \u0026lt;[Buffer](https://nodejs.org/api/buffer.html) | Uint8Array\u0026gt; The buffer send to the Stream Deck.\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nSends a HID feature report to the Stream Deck.\n\n#### streamDeck .setBrightness (percentage)\n\n- `percentage` \u0026lt;number\u0026gt; Percentage of brightness.\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nSynchronously set the brightness of the Stream Deck. This affects all keys at once. The brightness of individual keys cannot be controlled.\n\n##### Example: set the Stream Deck to maximum brightness\n\n```javascript\n// Set the Stream Deck to maximum brightness\nstreamDeck.setBrightness(100);\n```\n\n#### streamDeck .setImageLibrary (library)\n\n- `library` \u0026lt;string | [IImageLibraryCreator](#interface-iimagelibrarycreator) | Promise\u0026lt;IImageLibraryCreator\u0026gt;\u0026gt; An object capable to create image contexts or a string representing a module exporting such an object as `default`.\n- Returns: \u0026lt;StreamDeck\u0026gt;\n\nAllows users to switch image processing library to a non standard version.\nThis might be because of the library providing better performance or image quality, or simply to minimize bloat when another image library is used somewhere else.\n\n#### streamDeck .write (buffer)\n\n- `buffer` \u0026lt;[Buffer](https://nodejs.org/api/buffer.html) | Uint8Array\u0026gt; Data to write.\n- Returns: \u0026lt;Promise\u0026lt;number\u0026gt;\u0026gt; When written this resolves to the number of bytes\n\nAsynchronously writes an arbitrary `Uint8Array` instance to the Stream Deck.\nThe promise is rejected if an error is encountered during the write operation.\n\n#### streamDeck .writeMulti (buffers)\n\n- `buffers` \u0026lt;Array\u0026lt;[Buffer](https://nodejs.org/api/buffer.html) | Uint8Array\u0026gt;\u0026gt; Data buffers to write.\n- Returns: \u0026lt;Promise\u0026lt;number\u0026gt;\u0026gt; When written this resolves to the number of bytes\n\nAsynchronously writes a bunch of arbitrary `Uint8Array` instances to the Stream Deck.\nThe promise is rejected if an error is encountered during the write operation.\n\n##### Example: write a number of zeros to the stream deck\n\n```javascript\n// Writes a total of 32 bytes of zero to the Stream Deck in two pages and waits for the last one to finish.\nawait streamDeck.writeMulti([\n\tBuffer.alloc(16), Buffer.alloc(16)\n]);\n```\n### Abstract class: StreamDeckBase\n\nAbstract base class which is a partial implementation and must be extended.\n\nTo see which abstract properties and methods are required for a subclass check out the [source code for `StreamDeck`](https://github.com/TimLuq/stream-deck-ts/blob/master/src/stream-deck.ts) and look for the keyword `abstract`.\n\n### Interface: IImageLibrary\n\nAn image instance controlled by an image library.\n\nAny library implementing, or wrapped by an object implementing, this interface could be used for image operations.\n\n#### IImageLibrary .extract (options)\n\n- `options` \u0026lt;Object\u0026gt; Data to write.\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nExtract a section of the image.\n\nIf this is a immutable data structure a clone of the original should be returned with the new 2d slice.\nA mutable structure should return the original but with a view which may be moved with another call to extract.\n\n* `options.left` \u0026lt;number\u0026gt; the distance from the left edge of the original\n* `options.top` \u0026lt;number\u0026gt; the distance from the top edge of the original\n* `options.width` \u0026lt;number\u0026gt; the width of this subsection\n* `options.height` \u0026lt;number\u0026gt; the height of this subsection\n\n#### IImageLibrary .flatten ()\n\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nRemove alpha channel if one exists.\n\n#### IImageLibrary .resize (width, height)\n\n- `width` \u0026lt;number\u0026gt; Width of the resulting image.\n- `height` \u0026lt;number\u0026gt; Height of the resulting image.\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nResizes an image to the specified size.\nInterpolation and ratio perservation mode is up to the library or wrapper.\nHowever it is recommended that the image be applied in a `cover` fashion.\n\n#### IImageLibrary .toUint8Array ()\n\n- Returns: \u0026lt;Uint8Array | Promise\u0026lt;Uint8Array\u0026gt;\u0026gt;\n\nGet the RGB raw pixel bytes representing the image.\n\n### Interface: IImageLibraryCreator\n\nAn object implementing this interface is tasked with instantiating image contexts using a library or a custom implementation.\n\n#### IImageLibraryCreator .createRaw (data, rawOptions)\n\n- `data` \u0026lt;Uint8Array\u0026gt; Raw RGB pixel data.\n- `rawOptions` \u0026lt;Object\u0026gt; Parameters describing the raw image.\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nCreates an image context containing the pixels given in the `data` argument.\nThe image size and number of channels are specified in the `rawOptions` argument.\n\n- `rawOptions.channels` \u0026lt;number\u0026gt; The number of channels used. `4` is RGBA, `3` is RGB.\n- `rawOptions.height` \u0026lt;number\u0026gt; The height of the image.\n- `rawOptions.width` \u0026lt;number\u0026gt; The width of the image.\n\nThe total number of bytes should be equal to `height * width * channels`.\n\n#### IImageLibraryCreator .loadFile (filepath)\n\n- `filepath` \u0026lt;string\u0026gt; Path to an image file.\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nIf using a library exposing a way to read a file or support stream decoding such a function sould be used here.\nIf no streaming optimization is available this could be implemented by doing an async `readFile` and passing the resulting data to [`loadFileData`](#iimagelibrarycreator-loadimagedata-filedata).\n\n#### IImageLibraryCreator .loadFileData (filedata)\n\n- `filedata` \u0026lt;Uint8Array\u0026gt; Bytes of some image format hoping to be decoded.\n- Returns: \u0026lt;[IImageLibrary](#interface-iimagelibrary) | Promise\u0026lt;[IImageLibrary](#interface-iimagelibrary)\u0026gt;\u0026gt;\n\nCreates an image context based on an existing image.\nWhich image encodings is supported is determined by the library or implementor.\nRecommended formats are `PNG`, `JPEG`, and `SVG`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimluq%2Fstream-deck-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimluq%2Fstream-deck-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimluq%2Fstream-deck-ts/lists"}