|
a/upmpd/mpdcli.cxx |
|
b/upmpd/mpdcli.cxx |
|
... |
|
... |
25 |
#include <mpd/song.h>
|
25 |
#include <mpd/song.h>
|
26 |
#include <mpd/tag.h>
|
26 |
#include <mpd/tag.h>
|
27 |
#include <mpd/player.h>
|
27 |
#include <mpd/player.h>
|
28 |
#include <mpd/queue.h>
|
28 |
#include <mpd/queue.h>
|
29 |
|
29 |
|
|
|
30 |
#include "libupnpp/log.hxx"
|
30 |
#include "mpdcli.hxx"
|
31 |
#include "mpdcli.hxx"
|
31 |
|
32 |
|
32 |
using namespace std;
|
33 |
using namespace std;
|
33 |
|
34 |
|
34 |
#define M_CONN ((struct mpd_connection *)m_conn)
|
35 |
#define M_CONN ((struct mpd_connection *)m_conn)
|
|
... |
|
... |
56 |
mpd_connection_free(M_CONN);
|
57 |
mpd_connection_free(M_CONN);
|
57 |
m_conn = 0;
|
58 |
m_conn = 0;
|
58 |
}
|
59 |
}
|
59 |
m_conn = mpd_connection_new(m_host.c_str(), m_port, 0);
|
60 |
m_conn = mpd_connection_new(m_host.c_str(), m_port, 0);
|
60 |
if (m_conn == NULL) {
|
61 |
if (m_conn == NULL) {
|
61 |
cerr << "mpd_connection_new failed. No memory?" << endl;
|
62 |
LOGERR("mpd_connection_new failed. No memory?" << endl);
|
62 |
return false;
|
63 |
return false;
|
63 |
}
|
64 |
}
|
64 |
|
65 |
|
65 |
if (mpd_connection_get_error(M_CONN) != MPD_ERROR_SUCCESS) {
|
66 |
if (mpd_connection_get_error(M_CONN) != MPD_ERROR_SUCCESS) {
|
66 |
showError("MPDCli::openconn");
|
67 |
showError("MPDCli::openconn");
|
67 |
return false;
|
68 |
return false;
|
68 |
}
|
69 |
}
|
69 |
|
70 |
|
70 |
if(!m_password.empty()) {
|
71 |
if(!m_password.empty()) {
|
71 |
if (!mpd_run_password(M_CONN, m_password.c_str())) {
|
72 |
if (!mpd_run_password(M_CONN, m_password.c_str())) {
|
72 |
cerr << "Password wrong" << endl;
|
73 |
LOGERR("Password wrong" << endl);
|
73 |
return false;
|
74 |
return false;
|
74 |
}
|
75 |
}
|
75 |
}
|
76 |
}
|
76 |
mpd_run_consume(M_CONN, true);
|
77 |
mpd_run_consume(M_CONN, true);
|
77 |
return true;
|
78 |
return true;
|
78 |
}
|
79 |
}
|
79 |
|
80 |
|
80 |
bool MPDCli::showError(const string& who)
|
81 |
bool MPDCli::showError(const string& who)
|
81 |
{
|
82 |
{
|
82 |
if (!ok()) {
|
83 |
if (!ok()) {
|
83 |
cerr << "MPDCli::showError: bad state" << endl;
|
84 |
LOGERR("MPDCli::showError: bad state" << endl);
|
84 |
return false;
|
85 |
return false;
|
85 |
}
|
86 |
}
|
86 |
|
87 |
|
87 |
int error = mpd_connection_get_error(M_CONN);
|
88 |
int error = mpd_connection_get_error(M_CONN);
|
88 |
if (error == MPD_ERROR_SUCCESS)
|
89 |
if (error == MPD_ERROR_SUCCESS)
|
89 |
return false;
|
90 |
return false;
|
90 |
cerr << who << " failed: " << mpd_connection_get_error_message(M_CONN);
|
91 |
LOGERR(who << " failed: " << mpd_connection_get_error_message(M_CONN)
|
|
|
92 |
<< endl);
|
91 |
if (error == MPD_ERROR_SERVER) {
|
93 |
if (error == MPD_ERROR_SERVER) {
|
92 |
cerr << " server error: " << mpd_connection_get_server_error(M_CONN) ;
|
94 |
LOGERR(who << " server error: " <<
|
|
|
95 |
mpd_connection_get_server_error(M_CONN) << endl);
|
93 |
}
|
96 |
}
|
94 |
cerr << endl;
|
97 |
|
95 |
if (error == MPD_ERROR_CLOSED)
|
98 |
if (error == MPD_ERROR_CLOSED)
|
96 |
if (openconn())
|
99 |
if (openconn())
|
97 |
return true;
|
100 |
return true;
|
98 |
return false;
|
101 |
return false;
|
99 |
}
|
102 |
}
|
|
... |
|
... |
108 |
}
|
111 |
}
|
109 |
|
112 |
|
110 |
bool MPDCli::updStatus()
|
113 |
bool MPDCli::updStatus()
|
111 |
{
|
114 |
{
|
112 |
if (!ok()) {
|
115 |
if (!ok()) {
|
113 |
cerr << "MPDCli::updStatus: bad state" << endl;
|
116 |
LOGERR("MPDCli::updStatus: bad state" << endl);
|
114 |
return false;
|
117 |
return false;
|
115 |
}
|
118 |
}
|
116 |
|
119 |
|
117 |
mpd_status *mpds = 0;
|
120 |
mpd_status *mpds = 0;
|
118 |
mpds = mpd_run_status(M_CONN);
|
121 |
mpds = mpd_run_status(M_CONN);
|
119 |
if (mpds == 0) {
|
122 |
if (mpds == 0) {
|
120 |
openconn();
|
123 |
openconn();
|
121 |
mpds = mpd_run_status(M_CONN);
|
124 |
mpds = mpd_run_status(M_CONN);
|
122 |
cerr << "MPDCli::updStatus: can't get status" << endl;
|
125 |
LOGERR("MPDCli::updStatus: can't get status" << endl);
|
123 |
return false;
|
126 |
return false;
|
124 |
}
|
127 |
}
|
125 |
|
128 |
|
126 |
m_stat.volume = mpd_status_get_volume(mpds);
|
129 |
m_stat.volume = mpd_status_get_volume(mpds);
|
127 |
m_stat.rept = mpd_status_get_repeat(mpds);
|
130 |
m_stat.rept = mpd_status_get_repeat(mpds);
|
|
... |
|
... |
160 |
return true;
|
163 |
return true;
|
161 |
}
|
164 |
}
|
162 |
|
165 |
|
163 |
bool MPDCli::updSong(unordered_map<string, string>& tsong, int pos)
|
166 |
bool MPDCli::updSong(unordered_map<string, string>& tsong, int pos)
|
164 |
{
|
167 |
{
|
165 |
// cerr << "MPDCli::updSong" << endl;
|
168 |
// LOGDEB("MPDCli::updSong" << endl);
|
166 |
tsong.clear();
|
169 |
tsong.clear();
|
167 |
if (!ok())
|
170 |
if (!ok())
|
168 |
return false;
|
171 |
return false;
|
169 |
|
172 |
|
170 |
struct mpd_song *song;
|
173 |
struct mpd_song *song;
|
|
... |
|
... |
173 |
} else {
|
176 |
} else {
|
174 |
RETRY_CMD(song = mpd_run_get_queue_song_pos(M_CONN, (unsigned int)pos));
|
177 |
RETRY_CMD(song = mpd_run_get_queue_song_pos(M_CONN, (unsigned int)pos));
|
175 |
}
|
178 |
}
|
176 |
|
179 |
|
177 |
if (song == 0) {
|
180 |
if (song == 0) {
|
178 |
cerr << "mpd_run_current_song failed" << endl;
|
181 |
LOGERR("mpd_run_current_song failed" << endl);
|
179 |
return false;
|
182 |
return false;
|
180 |
}
|
183 |
}
|
181 |
|
184 |
|
182 |
const char *cp;
|
185 |
const char *cp;
|
183 |
cp = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0);
|
186 |
cp = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0);
|
|
... |
|
... |
207 |
|
210 |
|
208 |
mpd_song_free(song);
|
211 |
mpd_song_free(song);
|
209 |
return true;
|
212 |
return true;
|
210 |
}
|
213 |
}
|
211 |
|
214 |
|
212 |
bool MPDCli::setVolume(int volume, bool relative)
|
215 |
bool MPDCli::setVolume(int volume, bool isMute)
|
213 |
{
|
216 |
{
|
214 |
if (!ok()) {
|
217 |
if (!ok()) {
|
215 |
return false;
|
218 |
return false;
|
216 |
}
|
219 |
}
|
|
|
220 |
|
217 |
// Can't set volume if not active
|
221 |
// MPD does not want to set the volume if not active.
|
218 |
if (!(m_stat.state== MpdStatus::MPDS_PLAY) &&
|
222 |
if (!(m_stat.state== MpdStatus::MPDS_PLAY) &&
|
219 |
!(m_stat.state == MpdStatus::MPDS_PAUSE)) {
|
223 |
!(m_stat.state == MpdStatus::MPDS_PAUSE)) {
|
220 |
cerr << "MPDCli::setVolume: not active" << endl;
|
224 |
LOGINF("MPDCli::setVolume: not active" << endl);
|
221 |
return true;
|
225 |
return true;
|
222 |
}
|
226 |
}
|
223 |
cerr << "setVolume: vol " << volume << " relative " << relative << endl;
|
227 |
|
|
|
228 |
LOGDEB("MPDCli::setVolume: vol " << volume << " isMute " << isMute << endl);
|
|
|
229 |
|
|
|
230 |
if (isMute) {
|
224 |
if (volume == 0) {
|
231 |
if (volume) {
|
225 |
if (relative) {
|
|
|
226 |
// Restore premute volume
|
232 |
// Restore premute volume
|
|
|
233 |
LOGDEB("MPDCli::setVolume: restoring premute " << m_premutevolume
|
|
|
234 |
<< endl);
|
227 |
m_stat.volume = m_premutevolume;
|
235 |
volume = m_stat.volume = m_premutevolume;
|
228 |
cerr << "Restoring premute" << endl;
|
|
|
229 |
} else {
|
236 |
} else {
|
230 |
updStatus();
|
|
|
231 |
if (m_stat.volume != 0) {
|
237 |
if (m_stat.volume != 0) {
|
232 |
cerr << "Saving premute: " << m_stat.volume << endl;
|
238 |
cerr << "Saving premute: " << m_stat.volume << endl;
|
233 |
m_premutevolume = m_stat.volume;
|
239 |
m_premutevolume = m_stat.volume;
|
234 |
}
|
240 |
}
|
235 |
}
|
241 |
}
|
236 |
}
|
242 |
}
|
237 |
|
243 |
|
238 |
if (relative)
|
|
|
239 |
volume += m_stat.volume;
|
|
|
240 |
|
|
|
241 |
if (volume < 0)
|
244 |
if (volume < 0)
|
242 |
volume = 0;
|
245 |
volume = 0;
|
243 |
else if (volume > 100)
|
246 |
else if (volume > 100)
|
244 |
volume = 100;
|
247 |
volume = 100;
|
245 |
|
248 |
|
|
... |
|
... |
248 |
return true;
|
251 |
return true;
|
249 |
}
|
252 |
}
|
250 |
|
253 |
|
251 |
int MPDCli::getVolume()
|
254 |
int MPDCli::getVolume()
|
252 |
{
|
255 |
{
|
253 |
if (!updStatus())
|
|
|
254 |
return -1;
|
|
|
255 |
return m_stat.volume == -1 ? 0: m_stat.volume;
|
256 |
return m_stat.volume == -1 ? 0: m_stat.volume;
|
256 |
}
|
257 |
}
|
257 |
|
258 |
|
258 |
bool MPDCli::togglePause()
|
259 |
bool MPDCli::togglePause()
|
259 |
{
|
260 |
{
|
260 |
cerr << "MPDCli::togglePause" << endl;
|
261 |
LOGDEB("MPDCli::togglePause" << endl);
|
261 |
if (!ok())
|
262 |
if (!ok())
|
262 |
return false;
|
263 |
return false;
|
263 |
RETRY_CMD(mpd_run_toggle_pause(M_CONN));
|
264 |
RETRY_CMD(mpd_run_toggle_pause(M_CONN));
|
264 |
return true;
|
265 |
return true;
|
265 |
}
|
266 |
}
|
266 |
|
267 |
|
267 |
bool MPDCli::play(int pos)
|
268 |
bool MPDCli::play(int pos)
|
268 |
{
|
269 |
{
|
269 |
cerr << "MPDCli::play(pos=" << pos << ")" << endl;
|
270 |
LOGDEB("MPDCli::play(pos=" << pos << ")" << endl);
|
270 |
if (!ok())
|
271 |
if (!ok())
|
271 |
return false;
|
272 |
return false;
|
272 |
if (pos >= 0) {
|
273 |
if (pos >= 0) {
|
273 |
RETRY_CMD(mpd_run_play_pos(M_CONN, (unsigned int)pos));
|
274 |
RETRY_CMD(mpd_run_play_pos(M_CONN, (unsigned int)pos));
|
274 |
} else {
|
275 |
} else {
|
275 |
RETRY_CMD(mpd_run_play(M_CONN));
|
276 |
RETRY_CMD(mpd_run_play(M_CONN));
|
276 |
}
|
277 |
}
|
277 |
return true;
|
278 |
return updStatus();
|
278 |
}
|
279 |
}
|
279 |
bool MPDCli::stop()
|
280 |
bool MPDCli::stop()
|
280 |
{
|
281 |
{
|
281 |
cerr << "MPDCli::stop" << endl;
|
282 |
LOGDEB("MPDCli::stop" << endl);
|
282 |
if (!ok())
|
283 |
if (!ok())
|
283 |
return false;
|
284 |
return false;
|
284 |
RETRY_CMD(mpd_run_stop(M_CONN));
|
285 |
RETRY_CMD(mpd_run_stop(M_CONN));
|
285 |
return true;
|
286 |
return true;
|
286 |
}
|
287 |
}
|
287 |
bool MPDCli::seek(int seconds)
|
288 |
bool MPDCli::seek(int seconds)
|
288 |
{
|
289 |
{
|
289 |
if (!updStatus())
|
290 |
if (!updStatus())
|
290 |
return -1;
|
291 |
return -1;
|
291 |
cerr << "MPDCli::seek: pos:"<<m_stat.songpos<<" seconds: "<< seconds<<endl;
|
292 |
LOGDEB("MPDCli::seek: pos:"<<m_stat.songpos<<" seconds: "<< seconds<<endl);
|
292 |
RETRY_CMD(mpd_run_seek_pos(M_CONN, m_stat.songpos, (unsigned int)seconds));
|
293 |
RETRY_CMD(mpd_run_seek_pos(M_CONN, m_stat.songpos, (unsigned int)seconds));
|
293 |
return true;
|
294 |
return true;
|
294 |
}
|
295 |
}
|
295 |
|
296 |
|
296 |
bool MPDCli::next()
|
297 |
bool MPDCli::next()
|
297 |
{
|
298 |
{
|
298 |
cerr << "MPDCli::next" << endl;
|
299 |
LOGDEB("MPDCli::next" << endl);
|
299 |
if (!ok())
|
300 |
if (!ok())
|
300 |
return false;
|
301 |
return false;
|
301 |
RETRY_CMD(mpd_run_next(M_CONN));
|
302 |
RETRY_CMD(mpd_run_next(M_CONN));
|
302 |
return true;
|
303 |
return true;
|
303 |
}
|
304 |
}
|
304 |
bool MPDCli::previous()
|
305 |
bool MPDCli::previous()
|
305 |
{
|
306 |
{
|
306 |
cerr << "MPDCli::previous" << endl;
|
307 |
LOGDEB("MPDCli::previous" << endl);
|
307 |
if (!ok())
|
308 |
if (!ok())
|
308 |
return false;
|
309 |
return false;
|
309 |
RETRY_CMD(mpd_run_previous(M_CONN));
|
310 |
RETRY_CMD(mpd_run_previous(M_CONN));
|
310 |
return true;
|
311 |
return true;
|
311 |
}
|
312 |
}
|
312 |
bool MPDCli::repeat(bool on)
|
313 |
bool MPDCli::repeat(bool on)
|
313 |
{
|
314 |
{
|
314 |
cerr << "MPDCli::repeat:" << on << endl;
|
315 |
LOGDEB("MPDCli::repeat:" << on << endl);
|
315 |
if (!ok())
|
316 |
if (!ok())
|
316 |
return false;
|
317 |
return false;
|
317 |
RETRY_CMD(mpd_run_repeat(M_CONN, on));
|
318 |
RETRY_CMD(mpd_run_repeat(M_CONN, on));
|
318 |
return true;
|
319 |
return true;
|
319 |
}
|
320 |
}
|
320 |
bool MPDCli::random(bool on)
|
321 |
bool MPDCli::random(bool on)
|
321 |
{
|
322 |
{
|
322 |
cerr << "MPDCli::random:" << on << endl;
|
323 |
LOGDEB("MPDCli::random:" << on << endl);
|
323 |
if (!ok())
|
324 |
if (!ok())
|
324 |
return false;
|
325 |
return false;
|
325 |
RETRY_CMD(mpd_run_random(M_CONN, on));
|
326 |
RETRY_CMD(mpd_run_random(M_CONN, on));
|
326 |
return true;
|
327 |
return true;
|
327 |
}
|
328 |
}
|
328 |
bool MPDCli::single(bool on)
|
329 |
bool MPDCli::single(bool on)
|
329 |
{
|
330 |
{
|
330 |
cerr << "MPDCli::single:" << on << endl;
|
331 |
LOGDEB("MPDCli::single:" << on << endl);
|
331 |
if (!ok())
|
332 |
if (!ok())
|
332 |
return false;
|
333 |
return false;
|
333 |
RETRY_CMD(mpd_run_single(M_CONN, on));
|
334 |
RETRY_CMD(mpd_run_single(M_CONN, on));
|
334 |
return true;
|
335 |
return true;
|
335 |
}
|
336 |
}
|
336 |
|
337 |
|
337 |
int MPDCli::insert(const string& uri, int pos)
|
338 |
int MPDCli::insert(const string& uri, int pos)
|
338 |
{
|
339 |
{
|
339 |
cerr << "MPDCli::insert at :" << pos << " uri " << uri << endl;
|
340 |
LOGDEB("MPDCli::insert at :" << pos << " uri " << uri << endl);
|
340 |
if (!ok())
|
341 |
if (!ok())
|
341 |
return -1;
|
342 |
return -1;
|
342 |
|
343 |
|
343 |
if (!updStatus())
|
344 |
if (!updStatus())
|
344 |
return -1;
|
345 |
return -1;
|
|
... |
|
... |
351 |
}
|
352 |
}
|
352 |
return id;
|
353 |
return id;
|
353 |
}
|
354 |
}
|
354 |
bool MPDCli::deleteId(int id)
|
355 |
bool MPDCli::deleteId(int id)
|
355 |
{
|
356 |
{
|
356 |
cerr << "MPDCli::deleteId " << id << endl;
|
357 |
LOGDEB("MPDCli::deleteId " << id << endl);
|
357 |
if (!ok())
|
358 |
if (!ok())
|
358 |
return -1;
|
359 |
return -1;
|
359 |
|
360 |
|
360 |
RETRY_CMD(mpd_run_delete_id(M_CONN, (unsigned)id));
|
361 |
RETRY_CMD(mpd_run_delete_id(M_CONN, (unsigned)id));
|
361 |
return false;
|
362 |
return false;
|
362 |
}
|
363 |
}
|
363 |
bool MPDCli::statId(int id)
|
364 |
bool MPDCli::statId(int id)
|
364 |
{
|
365 |
{
|
365 |
cerr << "MPDCli::statId " << id << endl;
|
366 |
LOGDEB("MPDCli::statId " << id << endl);
|
366 |
if (!ok())
|
367 |
if (!ok())
|
367 |
return -1;
|
368 |
return -1;
|
368 |
|
369 |
|
369 |
mpd_song *song = mpd_run_get_queue_song_id(M_CONN, (unsigned)id);
|
370 |
mpd_song *song = mpd_run_get_queue_song_id(M_CONN, (unsigned)id);
|
370 |
if (song) {
|
371 |
if (song) {
|
|
... |
|
... |
375 |
}
|
376 |
}
|
376 |
int MPDCli::curpos()
|
377 |
int MPDCli::curpos()
|
377 |
{
|
378 |
{
|
378 |
if (!updStatus())
|
379 |
if (!updStatus())
|
379 |
return -1;
|
380 |
return -1;
|
380 |
cerr << "MPDCli::curpos: pos: " << m_stat.songpos << " id "
|
381 |
LOGDEB("MPDCli::curpos: pos: " << m_stat.songpos << " id "
|
381 |
<< m_stat.songid << endl;
|
382 |
<< m_stat.songid << endl);
|
382 |
return m_stat.songpos;
|
383 |
return m_stat.songpos;
|
383 |
}
|
384 |
}
|