97 void setProperty(
const QString &name,
const QVariant &value,
103 void call(
const QString &method,
104 const QVariant &arg1 = QVariant(),
105 const QVariant &arg2 = QVariant());
107 const QVariant &arg1 = QVariant(),
108 const QVariant &arg2 = QVariant());
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;
131 QHash<quint32, VideoSink*> m_videoSinks;
135 QDBusServiceWatcher m_serviceWatcher;
136 QScopedPointer<DBusPlayer> m_proxy;
199 m_serviceWatcher(m_service.service(), m_service.connection()),
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());
209 const QString path = reply.arguments()[0].value<QDBusObjectPath>().path();
210 m_uuid = reply.arguments()[1].toString();
212 m_proxy.reset(
new DBusPlayer(m_service.connection(), path,
this));
216 QDBusPendingReply<quint32> keyCall =
217 m_proxy->asyncCall(QStringLiteral(
"Key"));
219 QObject::connect(&m_serviceWatcher,
220 &QDBusServiceWatcher::serviceRegistered,
222 QObject::connect(&m_serviceWatcher,
223 &QDBusServiceWatcher::serviceUnregistered,
226 QDBusConnection c(m_service.connection());
228 const QString service = m_proxy->service();
229 const QString path = m_proxy->path();
230 const QString
interface = m_proxy->interface();
233 m_proxy.data(), SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
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"),
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)));
249 QDBusMessage msg = QDBusMessage::createMethodCall(
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();
259 QDBusArgument arg = reply.arguments().first().value<QDBusArgument>();
260 updateProperties(qdbus_cast<QVariantMap>(arg));
264 keyCall.waitForFinished();
265 if (Q_UNLIKELY(keyCall.isError())) {
266 qWarning() <<
"Key() call failed:" << keyCall.error().message();
268 PlayerKey key = keyCall.value();
269 m_videoSinkFactory = createVideoSinkFactory(key, m_backend);
282 bool controlsChanged =
false;
283 bool sourceTypeChanged =
false;
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") {
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;
319 }
else if (name ==
"Metadata") {
320 QDBusArgument arg = i.value().value<QDBusArgument>();
322 const QVariantMap dbusMap = qdbus_cast<QVariantMap>(arg);
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());
329 }
else if (name ==
"Orientation") {
333 }
else if (name ==
"TypedBackend") {
339 if (controlsChanged) {
342 if (sourceTypeChanged) {