-
Notifications
You must be signed in to change notification settings - Fork 0
/
argvMatey.go
95 lines (88 loc) · 2.09 KB
/
argvMatey.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
package main
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
)
var extension = ".flac"
var maxSongLength = time.Hour
var volumePath = "/volume/"
func endContainer(err error, l *log.Logger) {
l.Println("time to die")
l.Println(err)
out, _ := exec.Command("pgrep", "spotifyd").Output()
pid, _ := strconv.Atoi(strings.TrimSpace(string(out)))
syscall.Kill(pid, syscall.SIGKILL)
panic(err)
}
func getEventOrTrack(fileName string, l *log.Logger) string {
s, err := ioutil.ReadFile(fileName)
if err != nil {
endContainer(errors.New(fmt.Sprintf("could not read from file: %s", fileName)), l)
}
return strings.TrimSpace(string(s))
}
func main() {
l := log.New(&bytes.Buffer{}, "argvMatey: ", log.LUTC)
l.SetOutput(os.Stdout)
l.Println("starting argvMatey")
sigUsr := make(chan os.Signal, 1)
signal.Notify(sigUsr, syscall.SIGUSR1)
death := make(chan struct{})
for {
select {
case <-sigUsr:
close(death)
death = make(chan struct{})
event := getEventOrTrack("PLAYER_EVENT", l)
track := getEventOrTrack("TRACK_ID", l)
l.Println(fmt.Sprintf("Got signal. Event: %s Track: %s", event, track))
switch event {
case "start":
go record(death, l, track)
case "change":
go record(death, l, track)
case "stop":
endContainer(errors.New("spotify stopped"), l)
return
}
}
}
}
func record(death chan struct{}, l *log.Logger, track string) {
l.Println(fmt.Sprintf("track: %s", track))
fileName := volumePath + track + extension
cmd := exec.Command("ffmpeg", "-y", "-f", "pulse", "-i", "default", fileName)
err := cmd.Start()
if err != nil {
l.Println("failed to record track")
return
}
l.Println("recording started")
wgC := make(chan struct{})
go func() {
defer close(wgC)
time.Sleep(maxSongLength)
}()
select {
case <-wgC:
endContainer(errors.New("song is either longer than one hour or this broke"), l)
case <-death:
break
}
err = cmd.Process.Signal(os.Interrupt)
if err != nil {
l.Println("failed to stop recording.")
endContainer(err, l)
}
l.Println("recording stopped")
}