#include "radio.h" #include "yaml-cpp/yaml.h" #include #include #include Radio::Radio(QObject *parent) : QObject(parent), logo(0, 0) { mgr = 0; logoTries = 0; currentSong = 0; songsTries = 0; streamTries = 0; songTimer = new QTimer(this); songTimer->setSingleShot(true); connect(songTimer, SIGNAL(timeout()), this, SLOT(songEnded())); player = new QMediaPlayer(this); player->setVolume(100); } QString Radio::getName() { return name; } QString Radio::getClaim() { return claim; } QColor Radio::getTextColor() { return textColor; } QUrl Radio::getLogoUrl() { return logoUrl; } QUrl Radio::getStreamUrl() { return streamUrl; } int Radio::getId() { return id; } QUrl Radio::getApiBase() { return apiBase; } QUrl Radio::getCoverBase() { return coverBase; } Song *Radio::getCurrentSong() { return currentSong; } void Radio::setName(QString n) { name = n; } void Radio::setClaim(QString c) { claim = c; } void Radio::setTextColor(QColor c) { textColor = c; } void Radio::setLogoUrl(QUrl u) { logoUrl = u; } void Radio::setStreamUrl(QUrl u) { streamUrl = u; } void Radio::setId(int i) { id = i; } void Radio::setApiBase(QUrl u) { apiBase = u; } void Radio::setCoverBase(QUrl u) { coverBase = u; } void Radio::setCurrentSong(Song *s) { if(currentSong != 0) { nextSongs.removeOne(currentSong); currentSong->deleteLater(); } currentSong = s; songTimer->stop(); songTimer->setInterval(s->getDuration() <= 0 ? 1000 : s->getDuration()); songTimer->start(); nextSongs.removeOne(currentSong); updateNextSongs(); emit songChanged(currentSong); } void Radio::updateNextSongs() { songsTries = 0; QUrl url = apiBase; QUrlQuery query(url.query()); query.addQueryItem("act", "get_plist"); query.addQueryItem("id_wr", QString::number(id)); url.setQuery(query); QNetworkReply* reply = mgr->get(QNetworkRequest(url)); connect(reply, SIGNAL(finished()), this, SLOT(songsFinished())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(songsError(QNetworkReply::NetworkError))); } void Radio::downloadLogo() { if(logo.isNull()) { logoTries = 0; QNetworkReply* reply = mgr->get(QNetworkRequest(logoUrl)); connect(reply, SIGNAL(finished()), this, SLOT(logoFinished())); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(logoError(QNetworkReply::NetworkError))); } else emit logoDownloaded(logo); } void Radio::startStream() { stopStream(); streamTries = 0; player->setMedia(streamUrl); player->play(); } void Radio::stopStream() { player->stop(); } void Radio::logoFinished() { QNetworkReply* reply = (QNetworkReply*)sender(); if(logo.loadFromData(reply->readAll()) && !logo.isNull()) emit logoDownloaded(logo); } void Radio::logoError(QNetworkReply::NetworkError) { if(logoTries < 3) { ++logoTries; downloadLogo(); } } void Radio::songsFinished() { qDeleteAll(nextSongs); nextSongs.clear(); QNetworkReply* reply = (QNetworkReply*)sender(); YAML::Node itms = YAML::Load(reply->readAll().constData())["itms"]; for(unsigned i = 1;i < itms.size(); ++i) { YAML::Node itm = itms[i]; if(itm["id"].as() == -1) continue; Song* song = new Song(this); song->setDuration(itm["t_dur"].as()); song->setArtist(itm["art"].as().c_str()); song->setTitle(itm["tit"].as().c_str()); QUrl url = coverBase; url.setPath(url.path() + itm["cov"].as().c_str()); song->setCoverUrl(url); nextSongs.append(song); } } void Radio::songsError(QNetworkReply::NetworkError) { if(songsTries < 3) { ++songsTries; updateNextSongs(); } } void Radio::streamError() { if(streamTries < 3) { ++streamTries; stopStream(); startStream(); } } void Radio::songEnded() { if(!nextSongs.isEmpty()) setCurrentSong(nextSongs.at(0)); } void Radio::setNetworkManager(QNetworkAccessManager *m) { mgr = m; }