1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Music Player Daemon client library
22 # Connection to a MPD server
25 # Socket connection to server.
26 var socket
: nullable TCPStream = null
35 var password
: nullable String
38 var error
: nullable String = null
40 # Connect to the MPD server
43 var p
: nullable TCPStream = null
45 p
= new TCPStream.connect
(host
, port
)
50 var rep
= p
.read
(1024)
51 assert not rep
.is_empty
52 if not rep
.has_prefix
("OK") then
53 print
"MPD responded {rep}"
59 var password
= password
60 if password
!= null then
61 write_and_check
("password {password}\n")
65 # Write a command to the MPD server
66 protected fun write_and_check
(msg
: String)
68 if socket
== null then connect
72 var rep
= socket
.read
(1024)
73 if not rep
.has_prefix
("OK") then
74 print
"Error: MPD responded {rep}"
80 # Get MPD server status
81 fun status
: nullable ServerStatus
83 if socket
== null then connect
85 var volume
: nullable Int = null
86 var state
: nullable String = null
87 var elapsed
: nullable Int = null
88 var time_at
: nullable Int = null
89 var time_total
: nullable Int = null
92 socket
.write
("status\n")
93 var rep
= socket
.read
(1024)
94 for l
in rep
.split_with
("\n") do
95 var words
= l
.split_with
(" ")
96 if words
.length
> 1 then
97 var key
= words
[0].to_lower
98 var first_space
= l
.chars
.index_of
(' ')
99 var rest
= l
.substring_from
(first_space
+1)
100 if key
== "volume:" then
102 if volume
== -1 then volume
= null
103 else if key
== "state:" then
105 else if key
== "elapsed:" then
107 else if key
== "time:" then
108 var times
= rest
.split
(":")
109 time_at
= times
[0].to_i
110 time_total
= times
[1].to_i
115 if state
!= null then
116 var status
= new ServerStatus(volume
, state
, elapsed
, time_at
, time_total
)
123 # Set the volume relatively
124 fun relative_volume
=(diff
: Int)
126 if socket
== null then connect
129 if status
!= null then
130 var vol
= status
.volume
132 var new_vol
= vol
+ diff
133 new_vol
= new_vol
.max
(0).min
(100)
139 error
= "Cannot get volume"
142 # Set MPD server volume.
143 fun volume
=(vol
: Int) do write_and_check
("setvol {vol}\n")
145 # Pause music playing on the MPD server
146 fun pause
do write_and_check
("pause\n")
148 # Stop music playing on the MPD server
149 fun stop
do write_and_check
("stop\n")
151 # Play music playing on the MPD server
152 fun play
do write_and_check
("play\n")
154 # Get information on the currently playing song on the MPD server
155 fun current_song
: nullable SongInfo
157 if socket
== null then connect
159 var album
: nullable String = null
160 var artist
: nullable String = null
161 var title
: nullable String = null
162 var time
: nullable Int = null
164 socket
.write
("currentsong\n")
165 var rep
= socket
.read
(1024)
166 for l
in rep
.split_with
("\n") do
167 var words
= l
.split_with
(" ")
168 if words
.length
> 1 then
169 var key
= words
[0].to_lower
170 var first_space
= l
.chars
.index_of
(' ')
171 var rest
= l
.substring_from
(first_space
+1)
172 if key
== "album:" then
174 else if key
== "artist:" then
176 else if key
== "title:" then
178 else if key
== "time:" then
184 if album
!= null and artist
!= null and
185 title
!= null and time
!= null then
186 return new SongInfo(album
, artist
, title
, time
)
192 # Load playlist named `name`.
193 fun load_playlist
(name
: String)
195 write_and_check
"load \"{name}\
""
210 # Song total duration.
218 var volume
: nullable Int
220 # Playback state (play/stop/pause).
223 # Is MPD server playing?
224 fun playing
: Bool do return state
== "play"
226 # Is MPD server stopped?
227 fun stopped
: Bool do return state
== "stop"
229 # Time elapsed within the current song.
230 var elapsed
: nullable Int
233 var time_at
: nullable Int
235 # Total time of the current song.
236 var time_total
: nullable Int
238 # Get the cursor position on the song duration.
239 fun time_ratio
: nullable Float do
240 if time_at
== null or time_total
== null then return null
241 return time_at
.to_f
/ time_total
.to_f
246 if volume
!= null then vol
= volume
.to_s
248 var time_at
= time_at
249 var time_total
= time_total
250 var elapsed
= elapsed
251 if time_at
!= null and time_total
!= null and elapsed
!= null then
252 return "volume: {vol}\nstate: {state}\nelapsed: {elapsed}\ntime_[at|total]: {time_at}:{time_total}\ntime_ratio: {time_ratio.as(not null)}"
254 return "volume: {vol}\nstate: {state}"