/
main.go
105 lines (87 loc) · 2.1 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"context"
"log"
"os"
"os/signal"
"syscall"
"time"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"github.com/andreykaipov/goobs"
)
type Connections map[uint8]*goobs.Client
func main() {
// Parse config file
cfg := loadConfig()
if err := loadAssets(); err != nil {
panic(err)
}
// Find the streamdeck device through configured serial
d, err := getStreamdeckDeviceBySerial(cfg.Serial)
if err != nil {
panic(err)
}
// Open connection to streamdeck
if err = d.Open(); err != nil {
panic(err)
}
defer d.Close()
// Get firmware revision and reset device
ver, err := d.FirmwareVersion()
if err != nil {
panic(err)
}
if err = d.Reset(); err != nil {
panic(err)
}
log.Printf("Opened device with serial %s (firmware %s)\n", d.Serial, ver)
// Connections list
var clients Connections = make(map[uint8]*goobs.Client)
// Open connections to OBS Websockets
for idx, icfg := range cfg.Instances {
log.Printf("Connecting to instance %d on port %s", idx, icfg.Port)
client, err := goobs.New(
"localhost:"+icfg.Port,
goobs.WithPassword(icfg.Password),
goobs.WithDebug(cfg.Debug),
)
if err != nil {
panic(err)
}
clients[uint8(idx)] = client
}
// Setup deck
if err = setupDeck(clients, d, cfg); err != nil {
panic(err)
}
// error channel for receiving errors from the event loops
errCh := make(chan error, 5)
// Create context and start event loops
ctx, cancel := context.WithCancel(context.Background())
for idx, client := range clients {
// Goroutine with event listener for each OBS client
go obsEventLoop(ctx, errCh, client, d, cfg, idx)
}
// Single goroutine to listen for streamdeck keypresses
go streamdeckLoop(ctx, errCh, clients, d, cfg)
// Wait for OS signal (ctrl-c)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
waitloop:
for {
select {
case <-sigs:
break waitloop
case e := <-errCh:
log.Printf("event error: %s", e)
}
}
// Received a signal, stop the program..
log.Println("Halting")
cancel()
// Give goroutines some time to finish
time.Sleep(1 * time.Second)
_ = d.Reset()
}