Plasma
mpris.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mpris.h"
00020 #include "mpris_p.h"
00021 #include <mprisplayer.h>
00022
00023 #include <QtDBus>
00024 #include <QFile>
00025
00026 #include <kdebug.h>
00027 #include <KIO/NetAccess>
00028
00029
00030
00031 MprisFactory::MprisFactory(QObject* parent)
00032 : DBusPlayerFactory(parent)
00033 {
00034 setObjectName("MprisFactory");
00035 qDBusRegisterMetaType<MprisDBusVersion>();
00036 qDBusRegisterMetaType<MprisDBusStatus>();
00037 }
00038
00039 Player::Ptr MprisFactory::create(const QVariantList& args)
00040 {
00041 if (args.isEmpty()) {
00042 return Player::Ptr(0);
00043 }
00044 QString dbusName(args.first().toString());
00045 if (dbusName.isEmpty()) {
00046 return Player::Ptr(0);
00047 }
00048 Mpris* player = new Mpris(dbusName, this);
00049 if (!player->isRunning()) {
00050 delete player;
00051 player = 0;
00052 }
00053 return Player::Ptr(player);
00054 }
00055
00056 bool MprisFactory::matches(const QString& serviceName)
00057 {
00058 return serviceName.startsWith("org.mpris");
00059 }
00060
00061
00062
00063 Mpris::Mpris(const QString& name, PlayerFactory* factory)
00064 : QObject(),
00065 Player(factory),
00066 m_player(0),
00067 m_playerName(name)
00068 {
00069 if (!name.startsWith("org.mpris")) {
00070 m_playerName = "org.mpris." + name;
00071 }
00072 setName(m_playerName);
00073 setup();
00074 }
00075
00076 Mpris::~Mpris()
00077 {
00078 delete m_player;
00079 }
00080
00081 void Mpris::setup() {
00082 delete m_player;
00083 m_player = new MprisPlayer(
00084 m_playerName,
00085 "/Player",
00086 QDBusConnection::sessionBus());
00087
00088 m_metadata.clear();
00089 m_state = Stopped;
00090 m_caps = NO_CAPS;
00091
00092 if (m_player->isValid()) {
00093 connect(m_player, SIGNAL(CapsChange(int)),
00094 this, SLOT(capsChanged(int)));
00095 connect(m_player, SIGNAL(TrackChange(QVariantMap)),
00096 this, SLOT(trackChanged(QVariantMap)));
00097 connect(m_player, SIGNAL(StatusChange(MprisDBusStatus)),
00098 this, SLOT(stateChanged(MprisDBusStatus)));
00099
00100 capsChanged(m_player->GetCaps());
00101 trackChanged(m_player->GetMetadata());
00102 stateChanged(m_player->GetStatus());
00103 }
00104 }
00105
00106 bool Mpris::isRunning()
00107 {
00108 if (!m_player->isValid()) {
00109 setup();
00110 }
00111 return m_player->isValid();
00112 }
00113
00114 Player::State Mpris::state()
00115 {
00116 return m_state;
00117 }
00118
00119 QString Mpris::artist()
00120 {
00121 if (m_metadata.contains("artist")) {
00122 return m_metadata["artist"].toString();
00123 }
00124 return QString();
00125 }
00126
00127 QString Mpris::album()
00128 {
00129 if (m_metadata.contains("album")) {
00130 return m_metadata["album"].toString();
00131 }
00132 return QString();
00133 }
00134
00135 QString Mpris::title()
00136 {
00137 if (m_metadata.contains("title")) {
00138 return m_metadata["title"].toString();
00139 }
00140 return QString();
00141 }
00142
00143 int Mpris::trackNumber()
00144 {
00145 QVariant track;
00146 if (m_metadata.contains("trackNumber")) {
00147 track = m_metadata["trackNumber"];
00148 } else if (m_metadata.contains("tracknumber")) {
00149 track = m_metadata["tracknumber"];
00150 }
00151 if (track.isValid()) {
00152 if (track.canConvert(QVariant::Int)) {
00153 return track.toInt();
00154 } else {
00155 QString text = track.toString();
00156 int pos = text.indexOf('/');
00157 if (pos >= 0) {
00158 text.truncate(pos);
00159 }
00160 return text.toInt();
00161 }
00162 }
00163 return 0;
00164 }
00165
00166 QString Mpris::comment()
00167 {
00168 if (m_metadata.contains("comment")) {
00169 return m_metadata["comment"].toString();
00170 }
00171 return QString();
00172 }
00173
00174 QString Mpris::genre()
00175 {
00176 if (m_metadata.contains("genre")) {
00177 return m_metadata["genre"].toString();
00178 }
00179 return QString();
00180 }
00181
00182 int Mpris::length()
00183 {
00184 if (m_metadata.contains("time")) {
00185 return m_metadata["time"].toInt();
00186 } else if (m_metadata.contains("length")) {
00187
00188 return m_metadata["length"].toInt()/1000;
00189 }
00190 return 0;
00191 }
00192
00193 int Mpris::position()
00194 {
00195 if (m_player->isValid()) {
00196 return m_player->PositionGet() / 1000;
00197 }
00198 return 0;
00199 }
00200
00201 float Mpris::volume()
00202 {
00203 if (m_player->isValid()) {
00204 return ((float)m_player->VolumeGet()) / 100;
00205 }
00206 return 0;
00207 }
00208
00209 QPixmap Mpris::artwork()
00210 {
00211 if (m_metadata.contains("arturl")) {
00212 QString arturl = m_metadata["arturl"].toString();
00213 if (!arturl.isEmpty()) {
00214 if (!m_artfiles.contains(arturl) ||
00215 !QFile::exists(m_artfiles[arturl])) {
00216 QString artfile;
00217 if (!KIO::NetAccess::download(arturl, artfile, 0)) {
00218 kWarning() << KIO::NetAccess::lastErrorString();
00219 return QPixmap();
00220 }
00221 m_artfiles[arturl] = artfile;
00222 }
00223 return QPixmap(m_artfiles[arturl]);
00224 }
00225 }
00226 return QPixmap();
00227 }
00228
00229 bool Mpris::canPlay()
00230 {
00231 return m_caps & CAN_PLAY;
00232 }
00233
00234 void Mpris::play()
00235 {
00236 if (m_player->isValid()) {
00237 m_player->Play();
00238 }
00239 }
00240
00241 bool Mpris::canPause()
00242 {
00243 return m_caps & CAN_PAUSE;
00244 }
00245
00246 void Mpris::pause()
00247 {
00248 if (m_player->isValid()) {
00249 m_player->Pause();
00250 }
00251 }
00252
00253 bool Mpris::canStop()
00254 {
00255 return m_state != Stopped;
00256 }
00257
00258 void Mpris::stop()
00259 {
00260 if (m_player->isValid()) {
00261 m_player->Stop();
00262 }
00263 }
00264
00265 bool Mpris::canGoPrevious()
00266 {
00267 return m_caps & CAN_GO_PREV;
00268 }
00269
00270 void Mpris::previous()
00271 {
00272 if (m_player->isValid()) {
00273 m_player->Prev();
00274 }
00275 }
00276
00277 bool Mpris::canGoNext()
00278 {
00279 return m_caps & CAN_GO_NEXT;
00280 }
00281
00282 void Mpris::next()
00283 {
00284 if (m_player->isValid()) {
00285 m_player->Next();
00286 }
00287 }
00288
00289 bool Mpris::canSetVolume()
00290 {
00291 return true;
00292 }
00293
00294 void Mpris::setVolume(qreal volume)
00295 {
00296 if (m_player->isValid()) {
00297 m_player->VolumeSet((int)(volume * 100));
00298 }
00299 }
00300
00301 bool Mpris::canSeek()
00302 {
00303 return m_caps & CAN_SEEK;
00304 }
00305
00306 void Mpris::seek(int time)
00307 {
00308 if (m_player->isValid()) {
00309
00310 m_player->PositionSet(time * 1000);
00311 }
00312 }
00313
00314
00315
00316 void Mpris::trackChanged(const QVariantMap& metadata)
00317 {
00318 kDebug() << m_playerName << "metadata:" << metadata;
00319 m_metadata = metadata;
00320 }
00321
00322 void Mpris::stateChanged(MprisDBusStatus state)
00323 {
00324 kDebug() << m_playerName << "state:" << state.play;
00325 switch (state.play) {
00326 case MprisDBusStatus::Playing:
00327 m_state = Playing;
00328 break;
00329 case MprisDBusStatus::Paused:
00330 m_state = Paused;
00331 break;
00332 case MprisDBusStatus::Stopped:
00333 m_state = Stopped;
00334 break;
00335 default:
00336 kDebug() << m_playerName << "unexpected state" << state.play;
00337 }
00338 }
00339
00340 void Mpris::capsChanged(int caps)
00341 {
00342 kDebug() << m_playerName << "capabilities:" << caps;
00343 m_caps = (DBusCaps)caps;
00344 if (!(caps & CAN_PROVIDE_METADATA)) {
00345 m_metadata.clear();
00346 }
00347 }
00348
00349
00350 #include "mpris.moc"
00351 #include "mpris_p.moc"