|
a/src/ohsndrcv.cxx |
|
b/src/ohsndrcv.cxx |
|
... |
|
... |
44 |
}
|
44 |
}
|
45 |
void clear() {
|
45 |
void clear() {
|
46 |
if (dev && origmpd) {
|
46 |
if (dev && origmpd) {
|
47 |
dev->m_mpdcli = origmpd;
|
47 |
dev->m_mpdcli = origmpd;
|
48 |
origmpd = 0;
|
48 |
origmpd = 0;
|
49 |
if (dev->m_ohpl) {
|
|
|
50 |
dev->m_ohpl->resetQVers();
|
|
|
51 |
}
|
|
|
52 |
if (dev->m_ohrcv) {
|
49 |
if (dev->m_ohrcv) {
|
53 |
dev->m_ohrcv->iStop();
|
50 |
dev->m_ohrcv->iStop();
|
|
|
51 |
}
|
|
|
52 |
if (dev->m_ohpl) {
|
|
|
53 |
dev->m_ohpl->refreshState();
|
54 |
}
|
54 |
}
|
55 |
}
|
55 |
}
|
56 |
delete mpd;
|
56 |
delete mpd;
|
57 |
delete cmd;
|
57 |
delete cmd;
|
58 |
}
|
58 |
}
|
59 |
UpMpd *dev;
|
59 |
UpMpd *dev;
|
60 |
MPDCli *mpd;
|
60 |
MPDCli *mpd;
|
61 |
MPDCli *origmpd;
|
61 |
MPDCli *origmpd;
|
62 |
ExecCmd *cmd;
|
62 |
ExecCmd *cmd;
|
|
|
63 |
string uri;
|
|
|
64 |
string meta;
|
63 |
};
|
65 |
};
|
64 |
|
66 |
|
65 |
|
67 |
|
66 |
SenderReceiver::SenderReceiver(UpMpd *dev)
|
68 |
SenderReceiver::SenderReceiver(UpMpd *dev)
|
67 |
{
|
69 |
{
|
|
... |
|
... |
72 |
{
|
74 |
{
|
73 |
if (m)
|
75 |
if (m)
|
74 |
delete m;
|
76 |
delete m;
|
75 |
}
|
77 |
}
|
76 |
|
78 |
|
|
|
79 |
static bool copyMpd(MPDCli *src, MPDCli *dest, int seekms)
|
|
|
80 |
{
|
|
|
81 |
if (!src || !dest) {
|
|
|
82 |
LOGERR("copyMpd: src or dest is null\n");
|
|
|
83 |
return false;
|
|
|
84 |
}
|
|
|
85 |
|
|
|
86 |
// Playing state. If playing is stopped at this point elapsedms is
|
|
|
87 |
// lost which is why we get it as a parameter
|
|
|
88 |
MpdStatus mpds = src->getStatus();
|
|
|
89 |
if (seekms < 0) {
|
|
|
90 |
seekms = mpds.songelapsedms;
|
|
|
91 |
}
|
|
|
92 |
// Playlist from source mpd
|
|
|
93 |
vector<UpSong> playlist;
|
|
|
94 |
if (!src->getQueueData(playlist)) {
|
|
|
95 |
LOGERR("copyMpd: can't retrieve current playlist\n");
|
|
|
96 |
return false;
|
|
|
97 |
}
|
|
|
98 |
// Copy the playlist to dest
|
|
|
99 |
dest->clearQueue();
|
|
|
100 |
for (unsigned int i = 0; i < playlist.size(); i++) {
|
|
|
101 |
if (dest->insert(playlist[i].uri, i, playlist[i]) < 0) {
|
|
|
102 |
LOGERR("copyMpdt: mpd->insert failed\n");
|
|
|
103 |
return false;
|
|
|
104 |
}
|
|
|
105 |
}
|
|
|
106 |
dest->play(mpds.songpos);
|
|
|
107 |
dest->setVolume(mpds.volume);
|
|
|
108 |
dest->seek(seekms/1000);
|
|
|
109 |
return true;
|
|
|
110 |
}
|
|
|
111 |
|
77 |
bool SenderReceiver::start(int seekms)
|
112 |
bool SenderReceiver::start(int seekms)
|
78 |
{
|
113 |
{
|
79 |
LOGDEB("SenderReceiver::start. seekms " << seekms << endl);
|
114 |
LOGDEB("SenderReceiver::start. seekms " << seekms << endl);
|
80 |
|
115 |
|
81 |
if (!m->dev || !m->dev->m_ohpl) {
|
116 |
if (!m->dev || !m->dev->m_ohpl) {
|
82 |
LOGERR("SenderReceiver::start: no ohpl\n");
|
117 |
LOGERR("SenderReceiver::start: no ohpl\n");
|
83 |
return false;
|
118 |
return false;
|
84 |
}
|
119 |
}
|
85 |
|
120 |
|
86 |
// Playing state. Playing is stopped at this point (source switch), so
|
|
|
87 |
// we get the elapsedms (would be 0) as input param.
|
|
|
88 |
MpdStatus mpds = m->dev->getMpdStatusNoUpdate();
|
|
|
89 |
|
|
|
90 |
// Retrieve the current playlist from the normal MPD
|
|
|
91 |
vector<UpSong> playlist;
|
|
|
92 |
if (!m->dev->m_mpdcli || !m->dev->m_mpdcli->getQueueData(playlist)) {
|
|
|
93 |
LOGERR("SenderReceiver::start: can't retrieve current playlist\n");
|
|
|
94 |
return false;
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
// Stop MPD Play (normally already done)
|
121 |
// Stop MPD Play (normally already done)
|
98 |
m->dev->m_mpdcli->stop();
|
122 |
m->dev->m_mpdcli->stop();
|
99 |
|
123 |
|
|
|
124 |
if (!m->cmd) {
|
100 |
// Start fifo MPD and Sender
|
125 |
// First time: Start fifo MPD and Sender
|
101 |
m->cmd = new ExecCmd();
|
126 |
m->cmd = new ExecCmd();
|
102 |
vector<string> args;
|
127 |
vector<string> args;
|
103 |
args.push_back("-p");
|
128 |
args.push_back("-p");
|
104 |
args.push_back(SoapHelp::i2s(mpdport));
|
129 |
args.push_back(SoapHelp::i2s(mpdport));
|
|
|
130 |
args.push_back("-f");
|
|
|
131 |
args.push_back(m->dev->m_friendlyname);
|
105 |
m->cmd->startExec(makesendercmd, args, false, true);
|
132 |
m->cmd->startExec(makesendercmd, args, false, true);
|
106 |
|
133 |
|
107 |
string output;
|
134 |
string output;
|
108 |
if (!m->cmd->getline(output)) {
|
135 |
if (!m->cmd->getline(output)) {
|
109 |
LOGERR("SenderReceiver::start: makesender command failed\n");
|
136 |
LOGERR("SenderReceiver::start: makesender command failed\n");
|
110 |
m->clear();
|
137 |
m->clear();
|
111 |
return false;
|
138 |
return false;
|
112 |
}
|
139 |
}
|
113 |
LOGDEB("SenderReceiver::start got [" << output << "] from script\n");
|
140 |
LOGDEB("SenderReceiver::start got [" << output << "] from script\n");
|
114 |
|
141 |
|
115 |
// Output is like [Ok mpdport URI base64-encoded-uri METADATA b64-meta]
|
142 |
// Output is like [Ok mpdport URI base64-encoded-uri METADATA b64-meta]
|
116 |
vector<string> toks;
|
143 |
vector<string> toks;
|
117 |
stringToTokens(output, toks);
|
144 |
stringToTokens(output, toks);
|
118 |
if (toks.size() != 6 || toks[0].compare("Ok")) {
|
145 |
if (toks.size() != 6 || toks[0].compare("Ok")) {
|
119 |
LOGERR("SenderReceiver::start: bad output from script: " << output
|
146 |
LOGERR("SenderReceiver::start: bad output from script: " << output
|
120 |
<< endl);
|
147 |
<< endl);
|
121 |
m->clear();
|
148 |
m->clear();
|
122 |
return false;
|
149 |
return false;
|
123 |
}
|
150 |
}
|
124 |
string uri = base64_decode(toks[3]);
|
151 |
m->uri = base64_decode(toks[3]);
|
125 |
string meta = base64_decode(toks[5]);
|
152 |
m->meta = base64_decode(toks[5]);
|
126 |
|
153 |
|
127 |
// Connect to the new MPD, and copy the playlist
|
154 |
// Connect to the new MPD
|
128 |
m->mpd = new MPDCli("localhost", mpdport);
|
155 |
m->mpd = new MPDCli("localhost", mpdport);
|
129 |
if (!m->mpd || !m->mpd->ok()) {
|
156 |
if (!m->mpd || !m->mpd->ok()) {
|
130 |
LOGERR("SenderReceiver::start: can't connect to new MPD\n");
|
157 |
LOGERR("SenderReceiver::start: can't connect to new MPD\n");
|
131 |
m->clear();
|
|
|
132 |
return false;
|
|
|
133 |
}
|
|
|
134 |
for (unsigned int i = 0; i < playlist.size(); i++) {
|
|
|
135 |
if (m->mpd->insert(playlist[i].uri, i, playlist[i]) < 0) {
|
|
|
136 |
LOGERR("SenderReceiver::start: mpd->insert failed\n");
|
|
|
137 |
m->clear();
|
158 |
m->clear();
|
138 |
return false;
|
159 |
return false;
|
139 |
}
|
160 |
}
|
140 |
}
|
161 |
}
|
141 |
|
162 |
|
142 |
// Start our receiver
|
163 |
// Start our receiver
|
143 |
if (!m->dev->m_ohrcv->iSetSender(uri, meta) ||
|
164 |
if (!m->dev->m_ohrcv->iSetSender(m->uri, m->meta) ||
|
144 |
!m->dev->m_ohrcv->iPlay()) {
|
165 |
!m->dev->m_ohrcv->iPlay()) {
|
145 |
m->clear();
|
166 |
m->clear();
|
146 |
return false;
|
167 |
return false;
|
147 |
}
|
168 |
}
|
148 |
|
169 |
|
149 |
// Replace the original mpd and play
|
170 |
// Copy mpd state
|
|
|
171 |
copyMpd(m->dev->m_mpdcli, m->mpd, seekms);
|
150 |
m->origmpd = m->dev->m_mpdcli;
|
172 |
m->origmpd = m->dev->m_mpdcli;
|
151 |
m->dev->m_mpdcli = m->mpd;
|
173 |
m->dev->m_mpdcli = m->mpd;
|
152 |
LOGDEB("SenderReceiver::starting new mpd. songelapsedms: " <<
|
174 |
|
153 |
mpds.songelapsedms << endl);
|
|
|
154 |
m->mpd->setVolume(mpds.volume);
|
|
|
155 |
m->mpd->play(mpds.songpos);
|
|
|
156 |
m->mpd->seek(seekms/1000);
|
|
|
157 |
m->mpd->setVolume(mpds.volume);
|
|
|
158 |
return true;
|
175 |
return true;
|
159 |
}
|
176 |
}
|
160 |
|
177 |
|
161 |
bool SenderReceiver::stop()
|
178 |
bool SenderReceiver::stop()
|
162 |
{
|
179 |
{
|
163 |
LOGDEB("SenderReceiver::stop()\n");
|
180 |
LOGDEB("SenderReceiver::stop()\n");
|
164 |
// Do we want to transfer the playlist back ? Probably we do.
|
181 |
// Do we want to transfer the playlist back ? Probably we do.
|
165 |
m->clear();
|
182 |
if (!m->dev || !m->origmpd || !m->mpd || !m->dev->m_ohpl ||
|
|
|
183 |
!m->dev->m_ohrcv) {
|
|
|
184 |
LOGERR("SenderReceiver::stop: bad state: dev/origmpd/mpd null\n");
|
|
|
185 |
return false;
|
|
|
186 |
}
|
|
|
187 |
copyMpd(m->mpd, m->origmpd, -1);
|
|
|
188 |
m->mpd->stop();
|
|
|
189 |
m->dev->m_mpdcli = m->origmpd;
|
|
|
190 |
m->origmpd = 0;
|
|
|
191 |
m->dev->m_ohrcv->iStop();
|
|
|
192 |
m->dev->m_ohpl->refreshState();
|
|
|
193 |
|
166 |
return true;
|
194 |
return true;
|
167 |
}
|
195 |
}
|