Music Hub  ..
A session-wide music playback service
player.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2021-2022 UBports Foundation.
3  *
4  * Contact: Alberto Mardegan <mardy@users.sourceforge.net>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License version 3,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "player.h"
20 
21 #include "dbus_constants.h"
22 #include "dbus_utils.h"
23 #include "error_p.h"
24 #include "track_list_p.h"
25 #include "video_sink_p.h"
26 
27 #include <QDBusAbstractInterface>
28 #include <QDBusMessage>
29 #include <QDBusMetaType>
30 #include <QDBusPendingCall>
31 #include <QDBusPendingCallWatcher>
32 #include <QDBusPendingReply>
33 #include <QDBusReply>
34 #include <QDBusServiceWatcher>
35 #include <QDBusVariant>
36 #include <QHash>
37 #include <QMetaEnum>
38 #include <QVariantMap>
39 #include <QDebug>
40 
41 #include <functional>
42 #include <stdexcept>
43 
44 using namespace lomiri::MediaHub;
45 
46 typedef std::function<void(const QDBusMessage &)> MethodCb;
47 typedef std::function<void()> VoidMethodCb;
48 
50 {
51  Q_OBJECT
52 
53 public:
54  DBusService();
55 
56  QDBusMessage createSession();
57  void destroySession(const QString &uuid);
58 };
59 
61 {
62  Q_OBJECT
63 
64 public:
65  DBusPlayer(const QDBusConnection &conn, const QString &path,
66  PlayerPrivate *d);
67 
68 public Q_SLOTS:
69  void onPropertiesChanged(const QString &interface,
70  const QVariantMap &changed,
71  const QStringList &invalidated);
72  void onVideoDimensionChanged(quint32 height, quint32 width);
73  void onError(quint16 code);
74 
75 private:
76  PlayerPrivate *d;
77 };
78 
79 namespace lomiri {
80 namespace MediaHub {
81 
83 {
84  Q_DECLARE_PUBLIC(Player)
85 
86 public:
88  ~PlayerPrivate();
89 
90  // Internal methods
91  void updateProperties(const QVariantMap &properties);
92  void onVideoDimensionChanged(quint32 height, quint32 width);
93  void onError(quint16 dbusCode);
94  void watchErrors(const QDBusPendingCall &call);
95  void onSuccessfulCompletion(const QDBusPendingCall &call,
96  MethodCb callback);
97  void setProperty(const QString &name, const QVariant &value,
98  VoidMethodCb callback = [](){});
99  QVariant getProperty(const QString &name) const;
100 
101  // Implementation of public methods
102  void setTrackList(TrackList *trackList);
103  void call(const QString &method,
104  const QVariant &arg1 = QVariant(),
105  const QVariant &arg2 = QVariant());
106  void blockingCall(const QString &method,
107  const QVariant &arg1 = QVariant(),
108  const QVariant &arg2 = QVariant());
109  VideoSink &createGLTextureVideoSink(uint32_t textureId);
110 
111 private:
112  bool m_canPlay = false;
113  bool m_canPause = false;
114  bool m_canSeek = false;
115  bool m_canGoPrevious = false;
116  bool m_canGoNext = false;
117  bool m_isVideoSource = false;
118  bool m_isAudioSource = false;
119  bool m_shuffle = false;
120  Player::Volume m_volume = 1.0;
121  Player::Orientation m_orientation = Player::Rotate0;
122  Track::MetaData m_metaData;
123 
124  Player::PlaybackRate m_playbackRate = 1.0;
125  Player::PlaybackRate m_minimumPlaybackRate = 1.0;
126  Player::PlaybackRate m_maximumPlaybackRate = 1.0;
127 
128  Player::PlaybackStatus m_playbackStatus = Player::Null;
129 
131  QHash<quint32, VideoSink*> m_videoSinks;
132 
133  QString m_uuid;
134  DBusService m_service;
135  QDBusServiceWatcher m_serviceWatcher;
136  QScopedPointer<DBusPlayer> m_proxy;
137  TrackList *m_trackList = nullptr;
138  VideoSinkFactory m_videoSinkFactory;
139  Player *q_ptr;
140 };
141 
142 } // namespace MediaHub
143 } // namespace lomiri
144 
147  QStringLiteral(MEDIAHUB_SERVICE_PATH),
149  QDBusConnection::sessionBus(),
150  nullptr)
151 {
152  setTimeout(1000 /* ms*/);
153 }
154 
156 {
157  return call(QStringLiteral("CreateSession"));
158 }
159 
160 void DBusService::destroySession(const QString &uuid)
161 {
162  call(QDBus::NoBlock, QStringLiteral("DestroySession"), uuid);
163 }
164 
165 DBusPlayer::DBusPlayer(const QDBusConnection &conn,
166  const QString &objectPath,
167  PlayerPrivate *d):
169  objectPath,
171  conn,
172  nullptr),
173  d(d)
174 {
175 }
176 
177 void DBusPlayer::onPropertiesChanged(const QString &interface,
178  const QVariantMap &changed,
179  const QStringList &invalidated)
180 {
181  if (interface == QStringLiteral(MPRIS_PLAYER_INTERFACE)) {
182  d->updateProperties(changed);
183  // we know that our service will never invalidate properties
184  Q_UNUSED(invalidated);
185  }
186 }
187 
188 void DBusPlayer::onVideoDimensionChanged(quint32 height, quint32 width)
189 {
190  d->onVideoDimensionChanged(height, width);
191 }
192 
193 void DBusPlayer::onError(quint16 code)
194 {
195  d->onError(code);
196 }
197 
198 PlayerPrivate::PlayerPrivate(Player *q):
199  m_serviceWatcher(m_service.service(), m_service.connection()),
200  q_ptr(q)
201 {
202  {
203  QDBusMessage reply = m_service.createSession();
204  if (Q_UNLIKELY(reply.type() == QDBusMessage::ErrorMessage)) {
205  throw std::runtime_error(
206  (QStringLiteral("Failed to create session: ") + reply.errorMessage())
207  .toLocal8Bit().constData());
208  }
209  const QString path = reply.arguments()[0].value<QDBusObjectPath>().path();
210  m_uuid = reply.arguments()[1].toString();
211 
212  m_proxy.reset(new DBusPlayer(m_service.connection(), path, this));
213  }
214 
215  // We'll connect the result later down
216  QDBusPendingReply<quint32> keyCall =
217  m_proxy->asyncCall(QStringLiteral("Key"));
218 
219  QObject::connect(&m_serviceWatcher,
220  &QDBusServiceWatcher::serviceRegistered,
222  QObject::connect(&m_serviceWatcher,
223  &QDBusServiceWatcher::serviceUnregistered,
225 
226  QDBusConnection c(m_service.connection());
227 
228  const QString service = m_proxy->service();
229  const QString path = m_proxy->path();
230  const QString interface = m_proxy->interface();
231 
232  c.connect(service, path, QStringLiteral(FDO_PROPERTIES_INTERFACE), QStringLiteral("PropertiesChanged"),
233  m_proxy.data(), SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
234 
235  c.connect(service, path, interface, QStringLiteral("Seeked"),
236  q, SLOT(seekedTo(quint64)));
237  c.connect(service, path, interface, QStringLiteral("AboutToFinish"),
238  q, SLOT(aboutToFinish()));
239  c.connect(service, path, interface, QStringLiteral("EndOfStream"),
240  q, SLOT(endOfStream()));
241  c.connect(service, path, interface, QStringLiteral("VideoDimensionChanged"),
242  m_proxy.data(), SLOT(onVideoDimensionChanged(quint32,quint32)));
243  c.connect(service, path, interface, QStringLiteral("Error"),
244  m_proxy.data(), SLOT(onError(quint16)));
245  c.connect(service, path, interface, QStringLiteral("Buffering"),
246  q, SLOT(bufferingChanged(int)));
247 
248  // Blocking call to get the initial properties
249  QDBusMessage msg = QDBusMessage::createMethodCall(
250  service, path,
251  QStringLiteral(FDO_PROPERTIES_INTERFACE),
252  QStringLiteral("GetAll"));
253  msg.setArguments({ interface });
254  QDBusMessage reply = c.call(msg);
255  if (Q_UNLIKELY(reply.type()) == QDBusMessage::ErrorMessage) {
256  qWarning() << "Cannot get player properties:" <<
257  reply.errorMessage();
258  } else {
259  QDBusArgument arg = reply.arguments().first().value<QDBusArgument>();
260  updateProperties(qdbus_cast<QVariantMap>(arg));
261  }
262 
263  // Collect the result from the Key() call
264  keyCall.waitForFinished();
265  if (Q_UNLIKELY(keyCall.isError())) {
266  qWarning() << "Key() call failed:" << keyCall.error().message();
267  } else {
268  PlayerKey key = keyCall.value();
269  m_videoSinkFactory = createVideoSinkFactory(key, m_backend);
270  }
271 }
272 
274 {
275  m_service.destroySession(m_uuid);
276 }
277 
278 void PlayerPrivate::updateProperties(const QVariantMap &properties)
279 {
280  Q_Q(Player);
281 
282  bool controlsChanged = false;
283  bool sourceTypeChanged = false;
284 
285  for (auto i = properties.begin(); i != properties.end(); i++) {
286  const QString &name = i.key();
287  if (name == "CanPlay") {
288  m_canPlay = i.value().toBool();
289  controlsChanged = true;
290  } else if (name == "CanPause") {
291  m_canPause = i.value().toBool();
292  controlsChanged = true;
293  } else if (name == "CanSeek") {
294  m_canSeek = i.value().toBool();
295  controlsChanged = true;
296  } else if (name == "CanGoPrevious") {
297  m_canGoPrevious = i.value().toBool();
298  controlsChanged = true;
299  } else if (name == "CanGoNext") {
300  m_canGoNext = i.value().toBool();
301  controlsChanged = true;
302  } else if (name == "IsVideoSource") {
303  m_isVideoSource = i.value().toBool();
304  sourceTypeChanged = true;
305  } else if (name == "IsAudioSource") {
306  m_isAudioSource = i.value().toBool();
307  sourceTypeChanged = true;
308  } else if (name == "PlaybackStatus") {
309  bool ok = false;
310  const QString status = i.value().toString();
311  int v = QMetaEnum::fromType<Player::PlaybackStatus>().
312  keyToValue(status.toUtf8().constData(), &ok);
313  if (Q_UNLIKELY(!ok)) {
314  qWarning() << "Unknown player status" << status;
315  } else {
316  m_playbackStatus = static_cast<Player::PlaybackStatus>(v);
317  Q_EMIT q->playbackStatusChanged();
318  }
319  } else if (name == "Metadata") {
320  QDBusArgument arg = i.value().value<QDBusArgument>();
321  // strip the mpris:trackid
322  const QVariantMap dbusMap = qdbus_cast<QVariantMap>(arg);
323  m_metaData.clear();
324  for (auto i = dbusMap.begin(); i != dbusMap.end(); i++) {
325  if (i.key() == QStringLiteral("mpris:trackid")) continue;
326  m_metaData.insert(i.key(), i.value());
327  }
328  Q_EMIT q->metaDataForCurrentTrackChanged();
329  } else if (name == "Orientation") {
330  m_orientation =
331  static_cast<Player::Orientation>(i.value().toInt());
332  Q_EMIT q->orientationChanged();
333  } else if (name == "TypedBackend") {
334  m_backend =
335  static_cast<AVBackend::Backend>(i.value().toInt());
336  }
337  }
338 
339  if (controlsChanged) {
340  Q_EMIT q->controlsChanged();
341  }
342  if (sourceTypeChanged) {
343  Q_EMIT q->sourceTypeChanged();
344  }
345 }
346 
347 void PlayerPrivate::onVideoDimensionChanged(quint32 height, quint32 width)
348 {
349  Q_Q(Player);
350  Q_EMIT q->videoDimensionChanged(QSize(width, height));
351 }
352 
353 void PlayerPrivate::onError(quint16 dbusCode)
354 {
355  Q_Q(Player);
356  Error error = errorFromApiCode(dbusCode);
357  if (error.isError()) {
358  Q_EMIT q->errorOccurred(error);
359  }
360 }
361 
362 void PlayerPrivate::watchErrors(const QDBusPendingCall &call)
363 {
364  Q_Q(Player);
365  auto watcher = new QDBusPendingCallWatcher(call);
366  QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
367  q, [this](QDBusPendingCallWatcher *call) {
368  Q_Q(Player);
369  call->deleteLater();
370  QDBusPendingReply<void> reply(*call);
371  if (reply.isError()) {
372  Q_EMIT q->errorOccurred(errorFromDBus(reply.reply()));
373  }
374  });
375 }
376 
377 void PlayerPrivate::onSuccessfulCompletion(const QDBusPendingCall &call,
378  MethodCb callback)
379 {
380  Q_Q(Player);
381  auto watcher = new QDBusPendingCallWatcher(call);
382  QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
383  q, [this, callback](QDBusPendingCallWatcher *call) {
384  Q_Q(Player);
385  call->deleteLater();
386  const QDBusMessage reply = QDBusPendingReply<void>(*call).reply();
387  if (Q_UNLIKELY(reply.type()) == QDBusMessage::ErrorMessage) {
388  Q_EMIT q->errorOccurred(errorFromDBus(reply));
389  } else if (callback) {
390  callback(reply);
391  }
392  });
393 }
394 
395 void PlayerPrivate::setProperty(const QString &name, const QVariant &value,
396  VoidMethodCb callback)
397 {
398  QDBusMessage msg = QDBusMessage::createMethodCall(
399  m_proxy->service(),
400  m_proxy->path(),
401  QStringLiteral(FDO_PROPERTIES_INTERFACE),
402  QStringLiteral("Set"));
403  msg.setArguments({
404  QStringLiteral(MPRIS_PLAYER_INTERFACE),
405  name,
406  QVariant::fromValue(QDBusVariant(value)),
407  });
408  QDBusPendingCall call = m_proxy->connection().asyncCall(msg);
409  onSuccessfulCompletion(call, [callback](const QDBusMessage &) {
410  callback();
411  });
412 }
413 
414 /* This makes a blocking call: use sparingly! */
415 QVariant PlayerPrivate::getProperty(const QString &name) const
416 {
417  QDBusMessage msg = QDBusMessage::createMethodCall(
418  m_proxy->service(),
419  m_proxy->path(),
420  QStringLiteral(FDO_PROPERTIES_INTERFACE),
421  QStringLiteral("Get"));
422  msg.setArguments({
423  QStringLiteral(MPRIS_PLAYER_INTERFACE),
424  name,
425  });
426  QVariant ret;
427  QDBusReply<QVariant> reply = m_proxy->connection().call(msg);
428  if (Q_LIKELY(reply.isValid())) {
429  ret = reply.value();
430  } else {
431  qWarning() << "Error getting property" << name << reply.error();
432  }
433  return ret;
434 }
435 
437 {
438  if (trackList != m_trackList) {
439  if (trackList) {
440  trackList->d_ptr->createProxy(m_proxy->connection(),
441  m_proxy->path() + "/TrackList");
442  }
443  m_trackList = trackList;
444  }
445 }
446 
447 void PlayerPrivate::call(const QString &method,
448  const QVariant &arg1, const QVariant &arg2)
449 {
450  QDBusPendingCall call = m_proxy->asyncCall(method, arg1, arg2);
451  watchErrors(call);
452 }
453 
454 void PlayerPrivate::blockingCall(const QString &method,
455  const QVariant &arg1, const QVariant &arg2)
456 {
457  Q_Q(Player);
458  QDBusPendingCall call = m_proxy->asyncCall(method, arg1, arg2);
459  bool ok = DBusUtils::waitForFinished(call);
460  if (Q_UNLIKELY(!ok)) {
461  Q_EMIT q->errorOccurred(errorFromDBus(call.reply()));
462  }
463 }
464 
466 {
467  Q_Q(Player);
468  auto i = m_videoSinks.find(textureId);
469  if (i == m_videoSinks.end()) {
470  VideoSink *videoSink = m_videoSinkFactory(textureId, q);
471  i = m_videoSinks.insert(textureId, videoSink);
472  }
473  QDBusMessage reply =
474  m_proxy->call(QStringLiteral("CreateVideoSink"), textureId);
475  if (Q_UNLIKELY(reply.type() == QDBusMessage::ErrorMessage)) {
476  Q_EMIT q->errorOccurred(errorFromDBus(reply));
477  }
478  return *i.value();
479 }
480 
482  QObject(parent),
483  d_ptr(new PlayerPrivate(this))
484 {
485  qRegisterMetaType<Error>("Error");
486  QMetaType::registerConverter(&Error::toString);
487  QMetaType::registerEqualsComparator<Error>();
488  qRegisterMetaType<Volume>("Volume");
489  qRegisterMetaType<QVariantMap>("Track::MetaData");
490  qRegisterMetaType<PlaybackRate>("PlaybackRate");
491  qDBusRegisterMetaType<Headers>();
492 }
493 
494 Player::~Player() = default;
495 
496 QString Player::uuid() const
497 {
498  Q_D(const Player);
499  return d->m_uuid;
500 }
501 
503 {
504  Q_D(Player);
505  d->setTrackList(trackList);
506 }
507 
509 {
510  Q_D(const Player);
511  return d->m_trackList;
512 }
513 
515 {
516  Q_D(Player);
517  return d->createGLTextureVideoSink(textureId);
518 }
519 
520 void Player::openUri(const QUrl &uri, const Headers &headers)
521 {
522  Q_D(Player);
523  d->blockingCall(QStringLiteral("OpenUriExtended"),
524  uri.toString(), QVariant::fromValue(headers));
525 }
526 
528 {
529  Q_D(Player);
530  d->call(QStringLiteral("Next"));
531 }
532 
534 {
535  Q_D(Player);
536  d->call(QStringLiteral("Previous"));
537 }
538 
540 {
541  Q_D(Player);
542  d->call(QStringLiteral("Play"));
543 }
544 
546 {
547  Q_D(Player);
548  d->call(QStringLiteral("Pause"));
549 }
550 
552 {
553  Q_D(Player);
554  d->call(QStringLiteral("Stop"));
555 }
556 
557 void Player::seekTo(uint64_t microseconds)
558 {
559  Q_D(Player);
560  d->call(QStringLiteral("Seek"), quint64(microseconds));
561 }
562 
563 bool Player::canPlay() const
564 {
565  Q_D(const Player);
566  return d->m_canPlay;
567 }
568 
569 bool Player::canPause() const
570 {
571  Q_D(const Player);
572  return d->m_canPause;
573 }
574 
575 bool Player::canSeek() const
576 {
577  Q_D(const Player);
578  return d->m_canSeek;
579 }
580 
581 bool Player::canGoPrevious() const
582 {
583  Q_D(const Player);
584  return d->m_canGoPrevious;
585 }
586 
587 bool Player::canGoNext() const
588 {
589  Q_D(const Player);
590  return d->m_canGoNext;
591 }
592 
593 bool Player::isVideoSource() const
594 {
595  Q_D(const Player);
596  return d->m_isVideoSource;
597 }
598 
599 bool Player::isAudioSource() const
600 {
601  Q_D(const Player);
602  return d->m_isAudioSource;
603 }
604 
606 {
607  Q_D(const Player);
608  return d->m_playbackStatus;
609 }
610 
612 {
613  Q_D(Player);
614  d->setProperty(QStringLiteral("PlaybackRate"), rate,
615  [=]() { d->m_playbackRate = rate; });
616 }
617 
619 {
620  Q_D(const Player);
621  return d->m_playbackRate;
622 }
623 
624 void Player::setShuffle(bool shuffle)
625 {
626  Q_D(Player);
627  d->setProperty(QStringLiteral("Shuffle"), shuffle,
628  [=]() { d->m_shuffle = shuffle; });
629 }
630 
631 bool Player::shuffle() const
632 {
633  Q_D(const Player);
634  return d->m_shuffle;
635 }
636 
638 {
639  Q_D(Player);
640  d->setProperty(QStringLiteral("Volume"), volume,
641  // TODO: rewrite when the service gains signals
642  [=]() { d->m_volume = volume; });
643 }
644 
646 {
647  Q_D(const Player);
648  return d->m_volume;
649 }
650 
652 {
653  Q_D(const Player);
654  return d->m_metaData;
655 }
656 
658 {
659  Q_D(const Player);
660  return d->m_minimumPlaybackRate;
661 }
662 
664 {
665  Q_D(const Player);
666  return d->m_maximumPlaybackRate;
667 }
668 
669 quint64 Player::position() const
670 {
671  Q_D(const Player);
672  return d->getProperty(QStringLiteral("Position")).toULongLong();
673 }
674 
675 quint64 Player::duration() const
676 {
677  Q_D(const Player);
678  return d->getProperty(QStringLiteral("Duration")).toULongLong();
679 }
680 
682 {
683  Q_D(const Player);
684  return d->m_orientation;
685 }
686 
688 {
689  Q_D(Player);
690  QString status;
691  switch (loopStatus) {
692  case Player::LoopNone: status = QStringLiteral("None"); break;
693  case Player::LoopTrack: status = QStringLiteral("Track"); break;
694  case Player::LoopPlaylist: status = QStringLiteral("Playlist"); break;
695  default:
696  qWarning() << "Unknown loop status enum:" << loopStatus;
697  return;
698  }
699  d->setProperty(QStringLiteral("LoopStatus"), status);
700 }
701 
703 {
704  Q_D(const Player);
705  // TODO: add to PropertiesChanged
706  const QString status =
707  d->getProperty(QStringLiteral("LoopStatus")).toString();
708  if (status == "None") return Player::LoopNone;
709  if (status == "Track") return Player::LoopTrack;
710  if (status == "Playlist") return Player::LoopPlaylist;
711  qWarning() << "Unknown player status" << status;
712  return Player::LoopNone;
713 }
714 
716 {
717  Q_D(Player);
718  d->setProperty(QStringLiteral("AudioStreamRole"), role);
719 }
720 
722 {
723  Q_D(const Player);
724  // TODO: add to PropertiesChanged
725  return static_cast<AudioStreamRole>(
726  d->getProperty(QStringLiteral("AudioStreamRole")).toInt());
727 }
728 
729 #include "player.moc"
DBusService
Definition: player.cpp:49
lomiri::MediaHub
Definition: dbus_utils.h:25
QObject
MPRIS_PLAYER_INTERFACE
#define MPRIS_PLAYER_INTERFACE
Definition: dbus_constants.h:29
MEDIAHUB_SERVICE_PATH
#define MEDIAHUB_SERVICE_PATH
Definition: dbus_constants.h:23
DBusPlayer
Definition: player.cpp:60
lomiri::MediaHub::Player::PlaybackRate
double PlaybackRate
Definition: player.h:81
lomiri::MediaHub::PlayerPrivate::blockingCall
void blockingCall(const QString &method, const QVariant &arg1=QVariant(), const QVariant &arg2=QVariant())
Definition: player.cpp:454
lomiri::MediaHub::Player::Headers
QMap< QString, QString > Headers
Definition: player.h:83
lomiri::MediaHub::Player::orientationChanged
void orientationChanged()
MEDIAHUB_SERVICE_INTERFACE
#define MEDIAHUB_SERVICE_INTERFACE
Definition: dbus_constants.h:24
lomiri::MediaHub::Player::setVolume
void setVolume(Volume volume)
Definition: player.cpp:637
lomiri::MediaHub::Player::metaDataForCurrentTrackChanged
void metaDataForCurrentTrackChanged()
lomiri::MediaHub::Player::setPlaybackRate
void setPlaybackRate(PlaybackRate rate)
Definition: player.cpp:611
lomiri::MediaHub::Track::MetaData
Definition: track.h:47
lomiri::MediaHub::Player::openUri
void openUri(const QUrl &uri, const Headers &headers={})
Definition: player.cpp:520
mpris::objectPath
const QString objectPath
Definition: media_player2.cpp:39
lomiri::MediaHub::Error::isError
bool isError() const
Definition: error.h:51
MethodCb
std::function< void(const QDBusMessage &)> MethodCb
Definition: player.cpp:46
lomiri::MediaHub::Player::orientation
Orientation orientation
Definition: player.h:72
lomiri::MediaHub::Player::playbackRate
PlaybackRate playbackRate
Definition: player.h:63
lomiri::MediaHub::Player::controlsChanged
void controlsChanged()
lomiri::MediaHub::Player::playbackStatusChanged
void playbackStatusChanged()
lomiri::MediaHub::Player::duration
quint64 duration
Definition: player.h:70
lomiri::MediaHub::Player::Null
@ Null
Definition: player.h:86
FDO_PROPERTIES_INTERFACE
#define FDO_PROPERTIES_INTERFACE
Definition: dbus_constants.h:41
lomiri::MediaHub::Player::pause
void pause()
Definition: player.cpp:545
player.h
DBusPlayer::DBusPlayer
DBusPlayer(const QDBusConnection &conn, const QString &path, PlayerPrivate *d)
Definition: player.cpp:165
lomiri::MediaHub::Player::canPause
bool canPause
Definition: player.h:44
QDBusAbstractInterface
lomiri::MediaHub::Error::toString
QString toString() const
Definition: error.h:55
lomiri::MediaHub::Player::audioStreamRole
AudioStreamRole audioStreamRole
Definition: player.h:78
lomiri::MediaHub::Player::play
void play()
Definition: player.cpp:539
lomiri::MediaHub::PlayerPrivate::onError
void onError(quint16 dbusCode)
Definition: player.cpp:353
lomiri::MediaHub::Player::canSeek
bool canSeek
Definition: player.h:45
lomiri::MediaHub::Player::setTrackList
void setTrackList(TrackList *trackList)
Definition: player.cpp:502
lomiri::MediaHub::Player::videoDimensionChanged
void videoDimensionChanged(const QSize &size)
lomiri::MediaHub::PlayerPrivate::~PlayerPrivate
~PlayerPrivate()
Definition: player.cpp:273
lomiri::MediaHub::errorFromDBus
Error errorFromDBus(const QDBusMessage &msg)
Definition: error.cpp:29
lomiri::MediaHub::Player::Player
Player(QObject *parent=nullptr)
Definition: player.cpp:481
lomiri::MediaHub::VideoSink
A video sink abstracts a queue of buffers, that receives a stream of decoded video buffers from an ar...
Definition: video_sink.h:34
lomiri::MediaHub::Player::volume
Volume volume
Definition: player.h:56
dbus_constants.h
lomiri::MediaHub::PlayerPrivate::onSuccessfulCompletion
void onSuccessfulCompletion(const QDBusPendingCall &call, MethodCb callback)
Definition: player.cpp:377
lomiri::MediaHub::Player::Rotate0
@ Rotate0
Definition: player.h:115
lomiri::MediaHub::PlayerPrivate
Definition: player.cpp:82
lomiri::MediaHub::VideoSinkFactory
std::function< VideoSink *(uint32_t textureId, QObject *parent)> VideoSinkFactory
Definition: video_sink_p.h:43
lomiri::MediaHub::Player::position
quint64 position
Definition: player.h:69
lomiri::MediaHub::Player::isAudioSource
bool isAudioSource
Definition: player.h:50
lomiri::MediaHub::errorFromApiCode
Error errorFromApiCode(quint16 apiCode)
Definition: error.cpp:72
DBusConstants::None
@ None
Definition: dbus_constants.h:71
lomiri::MediaHub::Player::LoopStatus
LoopStatus
Definition: player.h:94
lomiri::MediaHub::Player::serviceReconnected
void serviceReconnected()
video_sink_p.h
lomiri::MediaHub::Player::Volume
double Volume
Definition: player.h:82
DBusPlayer::onVideoDimensionChanged
void onVideoDimensionChanged(quint32 height, quint32 width)
Definition: player.cpp:188
lomiri::MediaHub::Player::errorOccurred
void errorOccurred(const Error &error)
lomiri::MediaHub::PlayerPrivate::setProperty
void setProperty(const QString &name, const QVariant &value, VoidMethodCb callback=[](){})
Definition: player.cpp:395
DBusPlayer::onPropertiesChanged
void onPropertiesChanged(const QString &interface, const QVariantMap &changed, const QStringList &invalidated)
Definition: player.cpp:177
lomiri::MediaHub::Player::canGoPrevious
bool canGoPrevious
Definition: player.h:46
lomiri::MediaHub::Player::sourceTypeChanged
void sourceTypeChanged()
DBusService::DBusService
DBusService()
Definition: player.cpp:145
lomiri::MediaHub::PlayerPrivate::getProperty
QVariant getProperty(const QString &name) const
Definition: player.cpp:415
lomiri::MediaHub::Player::LoopNone
@ LoopNone
Definition: player.h:95
lomiri::MediaHub::Player::Orientation
Orientation
Definition: player.h:114
MEDIAHUB_SERVICE_NAME
#define MEDIAHUB_SERVICE_NAME
Definition: dbus_constants.h:22
lomiri::MediaHub::Player::serviceDisconnected
void serviceDisconnected()
lomiri::MediaHub::Player::metaDataForCurrentTrack
Track::MetaData metaDataForCurrentTrack
Definition: player.h:59
lomiri::MediaHub::Player::setLoopStatus
void setLoopStatus(LoopStatus loopStatus)
Definition: player.cpp:687
lomiri::MediaHub::Player::AudioStreamRole
AudioStreamRole
Definition: player.h:106
lomiri::MediaHub::Player::maximumPlaybackRate
PlaybackRate maximumPlaybackRate
Definition: player.h:67
lomiri::MediaHub::Player::loopStatus
LoopStatus loopStatus
Definition: player.h:75
lomiri::MediaHub::Player::PlaybackStatus
PlaybackStatus
Definition: player.h:85
lomiri::MediaHub::DBusUtils::waitForFinished
static bool waitForFinished(const QDBusPendingCall &call)
Definition: dbus_utils.cpp:34
lomiri::MediaHub::PlayerPrivate::watchErrors
void watchErrors(const QDBusPendingCall &call)
Definition: player.cpp:362
lomiri::MediaHub::Player::seekTo
void seekTo(uint64_t microseconds)
Definition: player.cpp:557
lomiri::MediaHub::PlayerPrivate::setTrackList
void setTrackList(TrackList *trackList)
Definition: player.cpp:436
lomiri::MediaHub::Player::isVideoSource
bool isVideoSource
Definition: player.h:49
DBusPlayer::onError
void onError(quint16 code)
Definition: player.cpp:193
lomiri::MediaHub::Player::canPlay
bool canPlay
Definition: player.h:43
error_p.h
lomiri::MediaHub::Player::playbackStatus
PlaybackStatus playbackStatus
Definition: player.h:53
lomiri::MediaHub::Player::goToNext
void goToNext()
Definition: player.cpp:527
lomiri::MediaHub::Error
Definition: error.h:29
lomiri::MediaHub::Player::shuffle
bool shuffle
Definition: player.h:55
lomiri::MediaHub::Player::setAudioStreamRole
void setAudioStreamRole(AudioStreamRole role)
Definition: player.cpp:715
lomiri::MediaHub::Player::uuid
QString uuid() const
Definition: player.cpp:496
lomiri::MediaHub::AVBackend::Backend
Backend
Definition: video_sink_p.h:34
lomiri::MediaHub::Player::createGLTextureVideoSink
VideoSink & createGLTextureVideoSink(uint32_t textureId)
Definition: player.cpp:514
lomiri::MediaHub::Player::setShuffle
void setShuffle(bool shuffle)
Definition: player.cpp:624
lomiri::MediaHub::Player::~Player
virtual ~Player()
lomiri::MediaHub::Player::minimumPlaybackRate
PlaybackRate minimumPlaybackRate
Definition: player.h:65
lomiri::MediaHub::PlayerPrivate::call
void call(const QString &method, const QVariant &arg1=QVariant(), const QVariant &arg2=QVariant())
Definition: player.cpp:447
lomiri::MediaHub::Player::goToPrevious
void goToPrevious()
Definition: player.cpp:533
DBusService::createSession
QDBusMessage createSession()
Definition: player.cpp:155
lomiri::MediaHub::Player::trackList
TrackList * trackList() const
Definition: player.cpp:508
lomiri::MediaHub::TrackList
Definition: track_list.h:35
lomiri
Definition: dbus_utils.h:24
track_list_p.h
lomiri::MediaHub::PlayerPrivate::onVideoDimensionChanged
void onVideoDimensionChanged(quint32 height, quint32 width)
Definition: player.cpp:347
lomiri::MediaHub::Player::LoopPlaylist
@ LoopPlaylist
Definition: player.h:97
VoidMethodCb
std::function< void()> VoidMethodCb
Definition: player.cpp:47
dbus_utils.h
lomiri::MediaHub::PlayerPrivate::createGLTextureVideoSink
VideoSink & createGLTextureVideoSink(uint32_t textureId)
Definition: player.cpp:465
lomiri::MediaHub::PlayerPrivate::updateProperties
void updateProperties(const QVariantMap &properties)
Definition: player.cpp:278
lomiri::MediaHub::Player::canGoNext
bool canGoNext
Definition: player.h:47
lomiri::MediaHub::Player
Definition: player.h:39
lomiri::MediaHub::Player::stop
void stop()
Definition: player.cpp:551
DBusService::destroySession
void destroySession(const QString &uuid)
Definition: player.cpp:160
lomiri::MediaHub::Player::LoopTrack
@ LoopTrack
Definition: player.h:96