2 * Copyright 2007 Alex Merry <alex.merry@kdemail.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License version 2 as
6 * published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details
13 * You should have received a copy of the GNU Library General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <mprisplayer.h>
27 #include <KIO/NetAccess>
31 MprisFactory::MprisFactory(QObject
* parent
)
32 : DBusPlayerFactory(parent
)
34 setObjectName("MprisFactory");
35 qDBusRegisterMetaType
<MprisDBusVersion
>();
36 qDBusRegisterMetaType
<MprisDBusStatus
>();
39 Player::Ptr
MprisFactory::create(const QVariantList
& args
)
42 return Player::Ptr(0);
44 QString
dbusName(args
.first().toString());
45 if (dbusName
.isEmpty()) {
46 return Player::Ptr(0);
48 Mpris
* player
= new Mpris(dbusName
, this);
49 if (!player
->isRunning()) {
53 return Player::Ptr(player
);
56 bool MprisFactory::matches(const QString
& serviceName
)
58 return serviceName
.startsWith("org.mpris");
63 Mpris::Mpris(const QString
& name
, PlayerFactory
* factory
)
69 if (!name
.startsWith("org.mpris")) {
70 m_playerName
= "org.mpris." + name
;
72 setName(m_playerName
);
83 m_player
= new MprisPlayer(
86 QDBusConnection::sessionBus());
92 if (m_player
->isValid()) {
93 connect(m_player
, SIGNAL(CapsChange(int)),
94 this, SLOT(capsChanged(int)));
95 connect(m_player
, SIGNAL(TrackChange(QVariantMap
)),
96 this, SLOT(trackChanged(QVariantMap
)));
97 connect(m_player
, SIGNAL(StatusChange(MprisDBusStatus
)),
98 this, SLOT(stateChanged(MprisDBusStatus
)));
100 capsChanged(m_player
->GetCaps());
101 trackChanged(m_player
->GetMetadata());
102 stateChanged(m_player
->GetStatus());
106 bool Mpris::isRunning()
108 if (!m_player
->isValid()) {
111 return m_player
->isValid();
114 Player::State
Mpris::state()
119 QString
Mpris::artist()
121 if (m_metadata
.contains("artist")) {
122 return m_metadata
["artist"].toString();
127 QString
Mpris::album()
129 if (m_metadata
.contains("album")) {
130 return m_metadata
["album"].toString();
135 QString
Mpris::title()
137 if (m_metadata
.contains("title")) {
138 return m_metadata
["title"].toString();
143 int Mpris::trackNumber()
146 if (m_metadata
.contains("trackNumber")) {
147 track
= m_metadata
["trackNumber"];
148 } else if (m_metadata
.contains("tracknumber")) {
149 track
= m_metadata
["tracknumber"];
151 if (track
.isValid()) {
152 if (track
.canConvert(QVariant::Int
)) {
153 return track
.toInt();
155 QString text
= track
.toString();
156 int pos
= text
.indexOf('/');
166 QString
Mpris::comment()
168 if (m_metadata
.contains("comment")) {
169 return m_metadata
["comment"].toString();
174 QString
Mpris::genre()
176 if (m_metadata
.contains("genre")) {
177 return m_metadata
["genre"].toString();
184 if (m_metadata
.contains("time")) {
185 return m_metadata
["time"].toInt();
186 } else if (m_metadata
.contains("length")) {
187 // stupid audacious...
188 return m_metadata
["length"].toInt()/1000;
193 int Mpris::position()
195 if (m_player
->isValid()) {
196 return m_player
->PositionGet() / 1000;
201 float Mpris::volume()
203 if (m_player
->isValid()) {
204 return ((float)m_player
->VolumeGet()) / 100;
209 QPixmap
Mpris::artwork()
211 if (m_metadata
.contains("arturl")) {
212 QString arturl
= m_metadata
["arturl"].toString();
213 if (!arturl
.isEmpty()) {
214 if (!m_artfiles
.contains(arturl
) ||
215 !QFile::exists(m_artfiles
[arturl
])) {
217 if (!KIO::NetAccess::download(arturl
, artfile
, 0)) {
218 kWarning() << KIO::NetAccess::lastErrorString();
221 m_artfiles
[arturl
] = artfile
;
223 return QPixmap(m_artfiles
[arturl
]);
229 bool Mpris::canPlay()
231 return m_caps
& CAN_PLAY
;
236 if (m_player
->isValid()) {
241 bool Mpris::canPause()
243 return m_caps
& CAN_PAUSE
;
248 if (m_player
->isValid()) {
253 bool Mpris::canStop()
255 return m_state
!= Stopped
;
260 if (m_player
->isValid()) {
265 bool Mpris::canGoPrevious()
267 return m_caps
& CAN_GO_PREV
;
270 void Mpris::previous()
272 if (m_player
->isValid()) {
277 bool Mpris::canGoNext()
279 return m_caps
& CAN_GO_NEXT
;
284 if (m_player
->isValid()) {
289 bool Mpris::canSetVolume()
294 void Mpris::setVolume(qreal volume
)
296 if (m_player
->isValid()) {
297 m_player
->VolumeSet((int)(volume
* 100));
301 bool Mpris::canSeek()
303 return m_caps
& CAN_SEEK
;
306 void Mpris::seek(int time
)
308 if (m_player
->isValid()) {
309 // m_player->seek() wants milliseconds
310 m_player
->PositionSet(time
* 1000);
316 void Mpris::trackChanged(const QVariantMap
& metadata
)
318 kDebug() << m_playerName
<< "metadata:" << metadata
;
319 m_metadata
= metadata
;
322 void Mpris::stateChanged(MprisDBusStatus state
)
324 kDebug() << m_playerName
<< "state:" << state
.play
;
325 switch (state
.play
) {
326 case MprisDBusStatus::Playing
:
329 case MprisDBusStatus::Paused
:
332 case MprisDBusStatus::Stopped
:
336 kDebug() << m_playerName
<< "unexpected state" << state
.play
;
340 void Mpris::capsChanged(int caps
)
342 kDebug() << m_playerName
<< "capabilities:" << caps
;
343 m_caps
= (DBusCaps
)caps
;
344 if (!(caps
& CAN_PROVIDE_METADATA
)) {
351 #include "mpris_p.moc"