You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

radio.cpp 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "radio.h"
  2. #include "yaml-cpp/yaml.h"
  3. #include <QDebug>
  4. #include <QUrlQuery>
  5. #include <QTextCodec>
  6. Radio::Radio(QObject *parent) : QObject(parent), logo(0, 0)
  7. {
  8. mgr = 0;
  9. logoTries = 0;
  10. currentSong = 0;
  11. songsTries = 0;
  12. streamTries = 0;
  13. songTimer = new QTimer(this);
  14. songTimer->setSingleShot(true);
  15. connect(songTimer, SIGNAL(timeout()), this, SLOT(songEnded()));
  16. player = new QMediaPlayer(this);
  17. player->setVolume(100);
  18. }
  19. QString Radio::getName()
  20. {
  21. return name;
  22. }
  23. QString Radio::getClaim()
  24. {
  25. return claim;
  26. }
  27. QColor Radio::getTextColor()
  28. {
  29. return textColor;
  30. }
  31. QUrl Radio::getLogoUrl()
  32. {
  33. return logoUrl;
  34. }
  35. QUrl Radio::getStreamUrl()
  36. {
  37. return streamUrl;
  38. }
  39. int Radio::getId()
  40. {
  41. return id;
  42. }
  43. QUrl Radio::getApiBase()
  44. {
  45. return apiBase;
  46. }
  47. QUrl Radio::getCoverBase()
  48. {
  49. return coverBase;
  50. }
  51. Song *Radio::getCurrentSong()
  52. {
  53. return currentSong;
  54. }
  55. void Radio::setName(QString n)
  56. {
  57. name = n;
  58. }
  59. void Radio::setClaim(QString c)
  60. {
  61. claim = c;
  62. }
  63. void Radio::setTextColor(QColor c)
  64. {
  65. textColor = c;
  66. }
  67. void Radio::setLogoUrl(QUrl u)
  68. {
  69. logoUrl = u;
  70. }
  71. void Radio::setStreamUrl(QUrl u)
  72. {
  73. streamUrl = u;
  74. }
  75. void Radio::setId(int i)
  76. {
  77. id = i;
  78. }
  79. void Radio::setApiBase(QUrl u)
  80. {
  81. apiBase = u;
  82. }
  83. void Radio::setCoverBase(QUrl u)
  84. {
  85. coverBase = u;
  86. }
  87. void Radio::setCurrentSong(Song *s)
  88. {
  89. if(currentSong != 0)
  90. {
  91. nextSongs.removeOne(currentSong);
  92. currentSong->deleteLater();
  93. }
  94. currentSong = s;
  95. songTimer->stop();
  96. songTimer->setInterval(s->getDuration() <= 0 ? 1000 : s->getDuration());
  97. songTimer->start();
  98. nextSongs.removeOne(currentSong);
  99. updateNextSongs();
  100. emit songChanged(currentSong);
  101. }
  102. void Radio::updateNextSongs()
  103. {
  104. songsTries = 0;
  105. QUrl url = apiBase;
  106. QUrlQuery query(url.query());
  107. query.addQueryItem("act", "get_plist");
  108. query.addQueryItem("id_wr", QString::number(id));
  109. url.setQuery(query);
  110. QNetworkReply* reply = mgr->get(QNetworkRequest(url));
  111. connect(reply, SIGNAL(finished()), this, SLOT(songsFinished()));
  112. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(songsError(QNetworkReply::NetworkError)));
  113. }
  114. void Radio::downloadLogo()
  115. {
  116. if(logo.isNull())
  117. {
  118. logoTries = 0;
  119. QNetworkReply* reply = mgr->get(QNetworkRequest(logoUrl));
  120. connect(reply, SIGNAL(finished()), this, SLOT(logoFinished()));
  121. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(logoError(QNetworkReply::NetworkError)));
  122. }
  123. else
  124. emit logoDownloaded(logo);
  125. }
  126. void Radio::startStream()
  127. {
  128. stopStream();
  129. streamTries = 0;
  130. player->setMedia(streamUrl);
  131. player->play();
  132. }
  133. void Radio::stopStream()
  134. {
  135. player->stop();
  136. }
  137. void Radio::logoFinished()
  138. {
  139. QNetworkReply* reply = (QNetworkReply*)sender();
  140. if(logo.loadFromData(reply->readAll()) && !logo.isNull())
  141. emit logoDownloaded(logo);
  142. }
  143. void Radio::logoError(QNetworkReply::NetworkError)
  144. {
  145. if(logoTries < 3)
  146. {
  147. ++logoTries;
  148. downloadLogo();
  149. }
  150. }
  151. void Radio::songsFinished()
  152. {
  153. qDeleteAll(nextSongs);
  154. nextSongs.clear();
  155. QNetworkReply* reply = (QNetworkReply*)sender();
  156. YAML::Node itms = YAML::Load(reply->readAll().constData())["itms"];
  157. for(unsigned i = 1;i < itms.size(); ++i)
  158. {
  159. YAML::Node itm = itms[i];
  160. if(itm["id"].as<int>() == -1)
  161. continue;
  162. Song* song = new Song(this);
  163. song->setDuration(itm["t_dur"].as<int>());
  164. song->setArtist(itm["art"].as<std::string>().c_str());
  165. song->setTitle(itm["tit"].as<std::string>().c_str());
  166. QUrl url = coverBase;
  167. url.setPath(url.path() + itm["cov"].as<std::string>().c_str());
  168. song->setCoverUrl(url);
  169. nextSongs.append(song);
  170. }
  171. }
  172. void Radio::songsError(QNetworkReply::NetworkError)
  173. {
  174. if(songsTries < 3)
  175. {
  176. ++songsTries;
  177. updateNextSongs();
  178. }
  179. }
  180. void Radio::streamError()
  181. {
  182. if(streamTries < 3)
  183. {
  184. ++streamTries;
  185. stopStream();
  186. startStream();
  187. }
  188. }
  189. void Radio::songEnded()
  190. {
  191. if(!nextSongs.isEmpty())
  192. setCurrentSong(nextSongs.at(0));
  193. }
  194. void Radio::setNetworkManager(QNetworkAccessManager *m)
  195. {
  196. mgr = m;
  197. }