Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
stream-deck-ts
Advanced tools
Changelog
1.0.0 (2018-11-11)
Almost a complete rewrite from the original project.
sharp
. If no other library is specified and sharp
isn't installed any image operation will throw an exception.fork
.worker_threads
with ArrayBuffer
transfer. However, this is not supported by node-hid
at the moment.setHidAsyncType()
.<a name="0.0.0"></a>
Readme
This 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.
Any additional devices would be appriciated. If you are able to control another device than those listed - please send a PR.
$ npm install --save stream-deck-ts
All 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
.
However, 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.
windows-build-tools
:npm install --global windows-build-tools
xcode-select --install
node-hid
:
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
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
stream-deck-ts
sudo apt-get update && sudo apt-get upgrade
import { resolve } from "path";
import { selectDevice } from "stream-deck-ts";
(async function asyncMain() {
// Automatically discovers connected Stream Decks, and attaches to the first one.
// Returns `null` if there are no connected stream decks.
// You also have the option of providing the numeric vendor identifier and product identifier.
// For example: `const myStreamDeck = await selectDevice(VENDOR_ELGATO, PRODUCT_ELGATO_STREAMDECK_MINI);`
const myStreamDeck = await selectDevice();
if (!myStreamDeck) {
throw new Error("No StreamDeck found.");
}
myStreamDeck.on('down', (keyIndex) => {
console.log('key %d down', keyIndex);
});
myStreamDeck.on('up', (keyIndex) => {
console.log('key %d up', keyIndex);
});
// Fired whenever an error is detected by the `node-hid` library.
// Always add a listener for this event!
myStreamDeck.on('error', (error) => {
console.error(error);
});
// Fill button 3 with an image of the GitHub logo.
// This is asynchronous and returns a promise.
myStreamDeck.fillImageFromFile(3, resolve(__dirname, 'github_logo.png')).then(() => {
console.log('Successfully wrote a GitHub logo to key 3.');
});
// Fill the first button form the left in the first row with a solid red color. This is synchronous.
myStreamDeck.fillColor(4, 255, 0, 0);
console.log('Successfully wrote a red square to key 4.');
}());
down
and key up
eventsAn object containing devices which are supported.
DEVICE_MODELS[vendor][device].import
<string> A path to the device implementation.DEVICE_MODELS[vendor][device].productName
<string> A name representing the product of the device.DEVICE_MODELS[vendor][device].vendorName
<string> A name representing the vendor of the device.To get specific product information getStreamDeckProduct
is the preferred solution.
export const PRODUCT_ELGATO_STREAMDECK = 96;
Exported constant to use as the product
filter while selecting a device.
export const PRODUCT_ELGATO_STREAMDECK_MINI = 99;
Exported constant to use as the product
filter while selecting a device.
export const VENDOR_ELGATO = 4057;
Exported constant to use as the vendor
filter while selecting a device.
object.vendorId
<number> Numeric vendor id.object.productId
<number> Numeric product id.object.release
<number> Numeric release value.object.interface
<number> Interface number.object.path
<string> Path to the specific device.Get a list of connected HID devices.
vendor
<number> A vendor identity number to register the product to.product
<number> A product identity number to register the product to.object.import
<string> Module name of the device implementation.object.productName
<string> Name of the product.object.vendorName
<string> Name of the vendor.Register a StreamDeck
compatable product. When a device matching the product is selected the module path in config.import
is loaded and instantiated.
The module referenced by config.import
must export a class named default
. The exported class SHOULD extend StreamDeckBase
.
vendor
<number> A vendor identity number to register the product to.product
<number> A product identity number to register the product to.config
<Object> The configuration object describing the product.config.import
<string> Module name of the device implementation.config.productName
<string> Name of the product.config.vendorName
<string> Name of the vendor.Register a StreamDeck
compatable product. When a device matching the product is selected the module path in config.import
is loaded and instantiated.
The module referenced by config.import
must export a class named default
. The exported class SHOULD extend StreamDeckBase
.
vendor
<number> An optional vendor identity number to limit which device will be selected.product
<number> An optional product identity number to limit which device will be selected.Select the first supported device. If no supported device is found null
is returned.
vendor
<number> An optional vendor identity number to limit which devices will be selected.product
<number> An optional product identity number to limit which devices will be selected.Get a list of all supported devices while they're being opened.
type
<string> Sets which type of async provider should be used.The async provider type handles how async calls are made.
auto
selects one of the other modes available to the system, based on priority.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.process
creates a forked
process to handle the USB communication which is first sent serialized over an IPC channel.worker
spins up a Worker
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
.Instances of the StreamDeck
class have an active connection to a device.
keyIndex
<number> The index of the key that got pressed.The down
event is triggered when a button on the Stream Deck has been pressed down.
keyIndex
<number> The index of the key that got released.The up
event is triggered when a button on the Stream Deck has been released which previously had been pressed down.
error
<Error> The index of the key that got released.Fired whenever an error is detected by the node-hid
library.
Always add a listener for this event! If you don't, errors will be silently dropped.
Returns the number of button columns available to this StreamDeck
.
Returns the number of buttons available to this StreamDeck
.
Returns the number of button rows available to this StreamDeck
.
A boolean showing if there currently are any pressed keys.
Returns the size in pixels used for icons.
A sorted list of all buttons currently pressed.
x
<number> Cloumn number counted from from the left.y
<number> Row number counted from from the top.keyIndex
at the given position or undefined
if out of bounds.Get the keyIndex
at a specific column and row.
keyIndex
<number> Cloumn number counted from from the left.y
<number> Row number counted from from the top.keyIndex
at the given position or undefined
if out of bounds.Validate a keyIndex
. If the number is not valid the function will throw a TypeError
, otherwise the same value will be returned.
Synchronously clears all keys on the device.
// Clear all keys.
streamDeck.clearAllKeys();
keyIndex
<number> Key to affect.Synchronously clears the given keyIndex
's screen.
// Clear button 2.
streamDeck.clearKey(2);
Closes this reference to the device.
keyIndex
<number> Key to affect.rgb
<number> Fill color.Synchronously sets the given keyIndex
's screen to a solid RGB color.
// Turn key 4 solid red.
streamDeck.fillColor(4, 0xFF0000);
keyIndex
<number> Key to affect.r
<number> Red component between 0
- 255
.g
<number> Green component between 0
- 255
.b
<number> Blue component between 0
- 255
.Synchronously sets the given keyIndex
's screen to a solid RGB color.
// Turn key 5 solid blue.
streamDeck.fillColor(5, 0, 0, 0xFF);
keyIndex
<number> Key to affect.buffer
<Buffer> Image bytes.Synchronously writes a buffer of streamDeck.iconSize
* streamDeck.iconSize
RGB image data to the given keyIndex
's screen.
The buffer must be exactly the expected length of bytes. Any other length will result in an error being thrown.
// Fill button 2 with an image of the GitHub logo.
import * as sharp from "sharp"; // See http://sharp.dimens.io/en/stable/ for full docs on this great library!
import { resolve } from "path";
const filepath = resolve(__dirname, 'github_logo.png');
const buffer = await sharp(filepath)
.flatten() // Eliminate alpha channel, if any.
.resize(streamDeck.iconSize, streamDeck.iconSize) // Scale up/down to the right size, cropping if necessary.
.raw() // Give us uncompressed RGB.
.toBuffer();
streamDeck.fillImage(2, buffer);
keyIndex
<number> Key to affect.filePath
<string> File system path to an image file.Asynchronously reads an image from filePath
and sets the given keyIndex
's screen to that image.
Automatically scales the image to the expected height and width and strips out the alpha channel.
If necessary, the image will be center-cropped to fit into a square.
// Fill the button 3 with an image of the GitHub logo.
await streamDeck.fillImageFromFile(3, path.resolve(__dirname, 'github_logo.png'));
console.log('Successfully wrote a GitHub logo to key 3.');
imagePathOrBuffer
<string | Uint8Array | Buffer> Image data or path to a file.rawOptions
<object> Optional options object used if the image buffer contained raw pixel data.
rawOptions.channels
<number> Number of channels per pixel. RGBA = 4
.rawOptions.height
<number> Height in pixels.rawOptions.width
<number> Width in pixels.Asynchronously 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
.
This method accepts either a path to an image on the disk, or a buffer. The image path or buffer is passed directly to sharp
. Therefore, this method accepts all images and buffers which sharp
can accept.
// Fill the entire panel with a photo of a sunny field.
import { resolve } from "path";
const filepath = resolve(__dirname, 'examples/fixtures/sunny_field.png');
await streamDeck.fillPanel(filepath);
console.log('Successfully filled the panel with an image.');
callback
<Function> The function to call for each button in the stream deck.Execute a function for each button available to the StreamDeck
.
buffer
<Buffer | Uint8Array> The buffer send to the Stream Deck.Sends a HID feature report to the Stream Deck.
percentage
<number> Percentage of brightness.Synchronously set the brightness of the Stream Deck. This affects all keys at once. The brightness of individual keys cannot be controlled.
// Set the Stream Deck to maximum brightness
streamDeck.setBrightness(100);
library
<string | IImageLibraryCreator | Promise<IImageLibraryCreator>> An object capable to create image contexts or a string representing a module exporting such an object as default
.Allows users to switch image processing library to a non standard version. This 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.
buffer
<Buffer | Uint8Array> Data to write.Asynchronously writes an arbitrary Uint8Array
instance to the Stream Deck.
The promise is rejected if an error is encountered during the write operation.
buffers
<Array<Buffer | Uint8Array>> Data buffers to write.Asynchronously writes a bunch of arbitrary Uint8Array
instances to the Stream Deck.
The promise is rejected if an error is encountered during the write operation.
// Writes a total of 32 bytes of zero to the Stream Deck in two pages and waits for the last one to finish.
await streamDeck.writeMulti([
Buffer.alloc(16), Buffer.alloc(16)
]);
Abstract base class which is a partial implementation and must be extended.
To see which abstract properties and methods are required for a subclass check out the source code for StreamDeck
and look for the keyword abstract
.
An image instance controlled by an image library.
Any library implementing, or wrapped by an object implementing, this interface could be used for image operations.
options
<Object> Data to write.Extract a section of the image.
If this is a immutable data structure a clone of the original should be returned with the new 2d slice. A mutable structure should return the original but with a view which may be moved with another call to extract.
options.left
<number> the distance from the left edge of the originaloptions.top
<number> the distance from the top edge of the originaloptions.width
<number> the width of this subsectionoptions.height
<number> the height of this subsectionRemove alpha channel if one exists.
width
<number> Width of the resulting image.height
<number> Height of the resulting image.Resizes an image to the specified size.
Interpolation and ratio perservation mode is up to the library or wrapper.
However it is recommended that the image be applied in a cover
fashion.
Get the RGB raw pixel bytes representing the image.
An object implementing this interface is tasked with instantiating image contexts using a library or a custom implementation.
data
<Uint8Array> Raw RGB pixel data.rawOptions
<Object> Parameters describing the raw image.Creates an image context containing the pixels given in the data
argument.
The image size and number of channels are specified in the rawOptions
argument.
rawOptions.channels
<number> The number of channels used. 4
is RGBA, 3
is RGB.rawOptions.height
<number> The height of the image.rawOptions.width
<number> The width of the image.The total number of bytes should be equal to height * width * channels
.
filepath
<string> Path to an image file.If using a library exposing a way to read a file or support stream decoding such a function sould be used here.
If no streaming optimization is available this could be implemented by doing an async readFile
and passing the resulting data to loadFileData
.
filedata
<Uint8Array> Bytes of some image format hoping to be decoded.Creates an image context based on an existing image.
Which image encodings is supported is determined by the library or implementor.
Recommended formats are PNG
, JPEG
, and SVG
.
FAQs
An npm module for interfacing with a stream deck
The npm package stream-deck-ts receives a total of 1 weekly downloads. As such, stream-deck-ts popularity was classified as not popular.
We found that stream-deck-ts demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.