|
a/src/ohradio.cxx |
|
b/src/ohradio.cxx |
|
... |
|
... |
110 |
};
|
110 |
};
|
111 |
|
111 |
|
112 |
static vector<RadioMeta> o_radios;
|
112 |
static vector<RadioMeta> o_radios;
|
113 |
|
113 |
|
114 |
OHRadio::OHRadio(UpMpd *dev)
|
114 |
OHRadio::OHRadio(UpMpd *dev)
|
115 |
: OHService(sTpProduct, sIdProduct, dev), m_active(false),
|
115 |
: OHService(sTpProduct, sIdProduct, dev)
|
116 |
m_id(0), m_ok(false)
|
|
|
117 |
{
|
116 |
{
|
118 |
// Need Python for the radiopl playlist-to-audio-url script
|
117 |
// Need Python for the radiopl playlist-to-audio-url script
|
119 |
string pypath;
|
118 |
string pypath;
|
120 |
if (!ExecCmd::which("python2", pypath)) {
|
119 |
if (!ExecCmd::which("python2", pypath)) {
|
121 |
LOGINF("OHRadio: python2 not found, radio service will not work\n");
|
120 |
LOGINF("OHRadio: python2 not found, radio service will not work\n");
|
|
... |
|
... |
241 |
return true;
|
240 |
return true;
|
242 |
}
|
241 |
}
|
243 |
|
242 |
|
244 |
void OHRadio::maybeExecMetaScript(RadioMeta& radio, MpdStatus &mpds)
|
243 |
void OHRadio::maybeExecMetaScript(RadioMeta& radio, MpdStatus &mpds)
|
245 |
{
|
244 |
{
|
246 |
string seconds("-1");
|
|
|
247 |
if (time(0) < radio.nextMetaScriptExecTime) {
|
245 |
if (time(0) < radio.nextMetaScriptExecTime) {
|
248 |
LOGDEB0("OHRadio::maybeExecMetaScript: next in " <<
|
246 |
LOGDEB0("OHRadio::maybeExecMetaScript: next in " <<
|
249 |
radio.nextMetaScriptExecTime - time(0) << endl);
|
247 |
radio.nextMetaScriptExecTime - time(0) << endl);
|
250 |
return;
|
248 |
return;
|
251 |
}
|
249 |
}
|
|
|
250 |
|
|
|
251 |
string elapsedms("-1");
|
252 |
if (mpds.state == MpdStatus::MPDS_PLAY) {
|
252 |
if (mpds.state == MpdStatus::MPDS_PLAY) {
|
253 |
seconds = SoapHelp::i2s(mpds.songelapsedms);
|
253 |
elapsedms = SoapHelp::i2s(mpds.songelapsedms);
|
|
|
254 |
}
|
254 |
}
|
255 |
|
255 |
vector<string> args{radio.metaScript};
|
256 |
vector<string> args{radio.metaScript};
|
|
|
257 |
args.push_back("elapsedms");
|
256 |
args.push_back(seconds);
|
258 |
args.push_back(elapsedms);
|
257 |
string data;
|
259 |
string data;
|
258 |
if (!ExecCmd::backtick(args, data)) {
|
260 |
if (!ExecCmd::backtick(args, data)) {
|
259 |
LOGERR("OHRadio::makestate: radio metascript failed\n");
|
261 |
LOGERR("OHRadio::makestate: radio metascript failed\n");
|
260 |
return;
|
262 |
return;
|
261 |
}
|
263 |
}
|
|
... |
|
... |
295 |
}
|
297 |
}
|
296 |
if (!found) {
|
298 |
if (!found) {
|
297 |
UpSong song;
|
299 |
UpSong song;
|
298 |
song.album = radio.title;
|
300 |
song.album = radio.title;
|
299 |
song.uri = audioUri;
|
301 |
song.uri = audioUri;
|
300 |
LOGDEB("INSERTING " << song.uri << endl);
|
302 |
LOGDEB0("ohRadio:execmetascript: inserting: " << song.uri << endl);
|
301 |
m_dev->m_mpdcli->single(false);
|
303 |
m_dev->m_mpdcli->single(false);
|
302 |
m_dev->m_mpdcli->consume(true);
|
304 |
m_dev->m_mpdcli->consume(true);
|
303 |
if (m_dev->m_mpdcli->insert(audioUri, -1, song) < 0) {
|
305 |
if (m_dev->m_mpdcli->insert(audioUri, -1, song) < 0) {
|
304 |
LOGERR("OHRadio::mkstate: mpd insert failed."<< " pos " <<
|
306 |
LOGERR("OHRadio::mkstate: mpd insert failed."<< " pos " <<
|
305 |
mpds.songpos << " uri " << audioUri << endl);
|
307 |
mpds.songpos << " uri " << audioUri << endl);
|
306 |
return;
|
308 |
return;
|
307 |
}
|
309 |
}
|
308 |
}
|
310 |
}
|
309 |
// Have to do this else playing does not start, but this is
|
311 |
|
310 |
// going to interfer with a user-initiated pause/stop state
|
312 |
// Start things up if needed.
|
311 |
if (mpds.state != MpdStatus::MPDS_PLAY && !m_dev->m_mpdcli->play(0)) {
|
313 |
if (m_playpending && mpds.state != MpdStatus::MPDS_PLAY &&
|
|
|
314 |
!m_dev->m_mpdcli->play(0)) {
|
312 |
LOGERR("OHRadio::mkstate: mpd play failed\n");
|
315 |
LOGERR("OHRadio::mkstate: mpd play failed\n");
|
313 |
return;
|
316 |
return;
|
314 |
}
|
317 |
}
|
315 |
radio.currentAudioUri = audioUri;
|
318 |
radio.currentAudioUri = audioUri;
|
316 |
}
|
319 |
}
|
|
... |
|
... |
335 |
|
338 |
|
336 |
// Some radios do not insert icy metadata in the stream, but rather
|
339 |
// Some radios do not insert icy metadata in the stream, but rather
|
337 |
// provide a script to retrieve it.
|
340 |
// provide a script to retrieve it.
|
338 |
bool nompddata = mpds.currentsong.title.empty() &&
|
341 |
bool nompddata = mpds.currentsong.title.empty() &&
|
339 |
mpds.currentsong.artist.empty();
|
342 |
mpds.currentsong.artist.empty();
|
340 |
if ((radio.preferScript || nompddata) && radio.metaScript.size()) {
|
343 |
if ((m_playpending || radio.preferScript || nompddata) &&
|
|
|
344 |
radio.metaScript.size()) {
|
341 |
maybeExecMetaScript(radio, mpds);
|
345 |
maybeExecMetaScript(radio, mpds);
|
342 |
mpds.currentsong.title = radio.dynTitle;
|
346 |
mpds.currentsong.title = radio.dynTitle;
|
343 |
mpds.currentsong.artist = radio.dynArtist;
|
347 |
mpds.currentsong.artist = radio.dynArtist;
|
344 |
}
|
348 |
}
|
345 |
|
349 |
|
|
... |
|
... |
402 |
if (radio.uri.empty()) {
|
406 |
if (radio.uri.empty()) {
|
403 |
// We count on the metascript to also return an audio URI,
|
407 |
// We count on the metascript to also return an audio URI,
|
404 |
// which will be sent to MPD during makestate().
|
408 |
// which will be sent to MPD during makestate().
|
405 |
radio.currentAudioUri.clear();
|
409 |
radio.currentAudioUri.clear();
|
406 |
m_dev->m_mpdcli->clearQueue();
|
410 |
m_dev->m_mpdcli->clearQueue();
|
|
|
411 |
m_playpending = true;
|
407 |
return UPNP_E_SUCCESS;
|
412 |
return UPNP_E_SUCCESS;
|
408 |
}
|
413 |
}
|
409 |
|
414 |
|
410 |
string cmdpath = path_cat(g_datadir, "rdpl2stream");
|
415 |
string cmdpath = path_cat(g_datadir, "rdpl2stream");
|
411 |
cmdpath = path_cat(cmdpath, "fetchStream.py");
|
416 |
cmdpath = path_cat(cmdpath, "fetchStream.py");
|
|
... |
|
... |
481 |
|
486 |
|
482 |
int OHRadio::pause(const SoapIncoming& sc, SoapOutgoing& data)
|
487 |
int OHRadio::pause(const SoapIncoming& sc, SoapOutgoing& data)
|
483 |
{
|
488 |
{
|
484 |
LOGDEB("OHRadio::pause" << endl);
|
489 |
LOGDEB("OHRadio::pause" << endl);
|
485 |
bool ok = m_dev->m_mpdcli->pause(true);
|
490 |
bool ok = m_dev->m_mpdcli->pause(true);
|
|
|
491 |
m_playpending = false;
|
486 |
maybeWakeUp(ok);
|
492 |
maybeWakeUp(ok);
|
487 |
return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
|
493 |
return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
|
488 |
}
|
494 |
}
|
489 |
|
495 |
|
490 |
int OHRadio::iStop()
|
496 |
int OHRadio::iStop()
|
491 |
{
|
497 |
{
|
492 |
bool ok = m_dev->m_mpdcli->stop();
|
498 |
bool ok = m_dev->m_mpdcli->stop();
|
|
|
499 |
m_playpending = false;
|
493 |
maybeWakeUp(ok);
|
500 |
maybeWakeUp(ok);
|
494 |
return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
|
501 |
return ok ? UPNP_E_SUCCESS : UPNP_E_INTERNAL_ERROR;
|
495 |
}
|
502 |
}
|
496 |
int OHRadio::stop(const SoapIncoming& sc, SoapOutgoing& data)
|
503 |
int OHRadio::stop(const SoapIncoming& sc, SoapOutgoing& data)
|
497 |
{
|
504 |
{
|