unix-streamdeck / streamdeckd

BSD 3-Clause "New" or "Revised" License
51 stars 8 forks source link

Streamdeckd

Help Wanted!

If you want to help with the development of streamdeckd and it's related repos, either by submitting code, finding/fixing bugs, or just replying to issues, please join this discord server: https://discord.gg/nyhuVEJWMQ

Installation

SUBSYSTEM=="input", GROUP="input", MODE="0666"  
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev"  
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev"  
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev"  
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev"  

Then xdotool will be required to simulate keypresses, to install this run:

Arch

sudo pacman -S xdotool

Debian based

sudo apt install xdotool

Configuration

Manual configuration

Warning:

If you are updating from v1.0.0, the config file is now being set in the location as below, instead of where it used to be, in the home dir, either consider moving the config file to that dir, or running streamdeckd with the -config flag, which allows you to point to a config file in a custom location


The configuration file streamdeckd uses is a JSON file found at $XDG_CONFIG_HOME/.streamdeck-config.json

An example config would be something like:

{
  "modules": [
    "/home/user/module.so"
  ],
  "decks": [
    {
      "serial": "AB12C3D45678",
      "pages": [
        [
          {
            "switch_page": 1,
            "icon": "~/icon.png"
          }
        ]
      ]
    }
  ]
}

At the top is the list of custom modules, these are go plugins in the .so format, following that is the list of deck objects, each represents a different streamdeck device, and contains its serial, and its list of pages

The outer array in a deck is the list of pages, the inner array is the list of button on that page, with the buttons going in a right to left order.

The actions you can have on a button are:

D-Bus

There is a D-Bus interface built into the daemon, the service name and interface for D-Bus are com.unixstreamdeck.streamdeckd and com/unixstreamdeck/streamdeckd respectively, and is made up of the following methods/signals

Methods

[
  {
    "icon_size": 72,
    "rows": 3,
    "cols": 5,
    "page": 0,
    "serial": "AB12C3D45678"
  }
]

Signals

Custom Modules

To create custom modules, I suggest looking at the gif, counter, and time modules in the example handlers package in streamdeckd, they should be in a file with the GetModule method as shown below

Loading Modules into streamdeckd

Modules require a method on them in the main package called "GetModule" that returns an instance of handler.Module e.g

package main

type CustomIconHandler struct {

}
...

type CustomKeyHandler struct {

}
...

func GetModule() handlers.Module {
    return handlers.Module{
        Name: "CustomModule", // the name that will be used in the icon_handler/key_handler field in the config, and that will be shown in the handler dropdown in streamdeckui
        NewIcon: func() api.IconHandler { return &CustomerIconHandler{}}, // Method to create a new instance of the Icon handler, if left empty, streamdeckui will not include it in the icon handler fields
        NewKey: func() api.KeyHandler { return &CustomerKeyHandler{}}, // Method to create a new instance of the Key Handler, if left empty, streamdeckui will not include it in the key handler fields
        IconFields: []api.Field{ // list of fields to be shown in streamdeckui when the icon handler is selected
            {
                Title: "Icon", // name of field to show in UI
                Name: "icon", // name of field that will be included in the iconHandlerFields map
                Type: "File" // type of input to show on streamdeckui, options are Text, File, TextAlignment, and Number
                FileTypes: []string{".png", ".jpg"} // Allowed file types if a File input type is used
            }
        },
        KeyFields: []api.Field{}, // Same as IconFields
    }
}