-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
107 lines (99 loc) · 2.6 KB
/
client.go
File metadata and controls
107 lines (99 loc) · 2.6 KB
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
106
107
package onair
import (
"bufio"
"fmt"
"log"
"net"
"net/textproto"
)
// Commands are valid client commands for controlling playback. They mirror the
// Airport DACP commands.
var Commands = map[string]string{
"display": "Display currently playing track",
"play": "Start playback",
"pause": "Pause playback",
"playpause": "Toggle between play and pause",
"nextitem": "Play next item in playlist",
"previtem": "Play previous item in playlist",
"stop": "Stop playback",
"shuffle_songs": "Shuffle playlist",
"beginff": "Begin fast forward",
"beginrew": "Begin rewind",
"playresume": "Play after fast forward or rewind",
"volumedown": "Turn audio volume down",
"volumeup": "Turn audio volume up",
"mutetoggle": "Toggle mute status",
}
// CommandAliases offers more user friendly options for the DACP commands.
var CommandAliases = map[string]string{
"next": "nextitem",
"skip": "nextitem",
"previous": "previtem",
"back": "previtem",
"shuffle": "shuffle_songs",
"fastforward": "beginff",
"ff": "beginff",
"rewind": "beginrew",
"rew": "beginrew",
"up": "volumeup",
"volup": "volumeup",
"down": "volumedown",
"voldown": "volumedown",
"mute": "mutetoggle",
}
// Client connects to an onair Server for sending playback control commands.
type Client struct {
port int
writer *textproto.Writer
reader *textproto.Reader
conn net.Conn
}
// NewClient attempts to create a new Client connected to a server port.
func NewClient(port int) (Client, error) {
c := Client{
port: port,
}
err := c.connect()
return c, err
}
// Send will attempt to send a valid command to the server.
func (me *Client) Send(cmd string) error {
alt, ok := CommandAliases[cmd]
if ok {
cmd = alt
}
_, ok = Commands[cmd]
if !ok {
return fmt.Errorf("Invalid command: %s", cmd)
}
err := me.writer.PrintfLine("%s", cmd)
if err != nil {
return err
}
if cmd == "display" {
resp, err := me.reader.ReadLine()
if err != nil {
return err
}
fmt.Println(resp)
}
return nil
}
// Close cleans up a client's network connections.
func (me *Client) Close() {
me.conn.Close()
}
func (me *Client) connect() error {
address := net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: me.port}
conn, err := net.DialTCP("tcp", &net.TCPAddr{IP: net.ParseIP("127.0.0.1")}, &address)
if err != nil {
return err
}
log.Println("Connected")
me.conn = conn
w := bufio.NewWriter(conn)
r := bufio.NewReader(conn)
me.writer = textproto.NewWriter(w)
me.reader = textproto.NewReader(r)
return nil
}