fix: 任务栏媒体播放插件异常

关闭一个播放器后无法再次控制剩余的播放器
记录所有的播放器控制接口,退出一个后回退到上一个播放器控制

Issue: https://github.com/linuxdeepin/developer-center/issues/5719
This commit is contained in:
ck 2023-12-20 15:43:57 +08:00 committed by mike
parent dab0083dcd
commit d765d60b22
2 changed files with 57 additions and 49 deletions

View File

@ -122,87 +122,94 @@ void MediaPlayerModel::playNext()
m_mediaInter->Next(); m_mediaInter->Next();
} }
void MediaPlayerModel::onServiceChanged()
{
if (m_mediaInter) {
// 不论是新打开一个播放器还是关闭播放器都清理一下
delete m_mediaInter;
m_mediaInter = nullptr;
}
m_isActived = !m_mprisServices.isEmpty();
if (m_isActived) {
m_mediaInter = new MediaPlayerInterface(m_mprisServices.last(), "/org/mpris/MediaPlayer2",
QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
}
Q_EMIT startStop(m_isActived);
}
void MediaPlayerModel::initMediaPlayer() void MediaPlayerModel::initMediaPlayer()
{ {
QDBusInterface dbusInter("org.freedesktop.DBus", "/", "org.freedesktop.DBus", QDBusConnection::sessionBus(), this); QDBusInterface dbusInter("org.freedesktop.DBus", "/", "org.freedesktop.DBus", QDBusConnection::sessionBus(), this);
QDBusPendingCall call = dbusInter.asyncCall("ListNames"); QDBusPendingCall call = dbusInter.asyncCall("ListNames");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
connect(watcher, &QDBusPendingCallWatcher::finished, [ = ] { connect(watcher, &QDBusPendingCallWatcher::finished, [ = ] {
m_serviceName.clear(); m_mprisServices.clear();
if (call.isError()) if (call.isError())
return; return;
QDBusReply<QStringList> reply = call.reply(); QDBusReply<QStringList> reply = call.reply();
const QStringList &serviceList = reply.value(); const QStringList &serviceList = reply.value();
auto serviceCanPlay = [](const QString &service){
QDBusInterface serviceInterface(service, "/org/mpris/MediaPlayer2",
"org.mpris.MediaPlayer2.Player",
QDBusConnection::sessionBus());
// 如果开启了谷歌浏览器的后台服务(org.mpris.MediaPlayer2.chromium.instance17352)
// 也符合名称要求,但是它不是音乐服务,此时需要判断是否存在这个属性
QVariant v = serviceInterface.property("CanPlay");
return v.isValid() && v.value<bool>();
};
for (const QString &serv : serviceList) { for (const QString &serv : serviceList) {
if (!serv.startsWith("org.mpris.MediaPlayer2")) if (!serv.startsWith("org.mpris.MediaPlayer2"))
continue; continue;
QDBusInterface serviceInterface(serv, "/org/mpris/MediaPlayer2", if (!serviceCanPlay(serv)) {
"org.mpris.MediaPlayer2.Player", QDBusConnection::sessionBus(), this); qWarning() << "ignore invalid service" << serv;
// 如果开启了谷歌浏览器的后台服务(org.mpris.MediaPlayer2.chromium.instance17352)
// 也符合名称要求,但是它不是音乐服务,此时需要判断是否存在这个属性
QVariant v = serviceInterface.property("CanPlay");
if (!v.isValid() || !v.value<bool>())
continue; continue;
}
m_serviceName = serv; m_mprisServices << serv;
break; break;
} }
if (!m_serviceName.isEmpty()) { onServiceChanged();
m_isActived = true;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
Q_EMIT startStop(m_isActived);
return;
}
QDBusConnectionInterface *dbusInterface = QDBusConnection::sessionBus().interface(); QDBusConnectionInterface *dbusInterface = QDBusConnection::sessionBus().interface();
connect(dbusInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, connect(dbusInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[ = ](const QString &name, const QString &, const QString &newOwner) { [ = ](const QString &name, const QString &, const QString &newOwner) {
if (name.startsWith("org.mpris.MediaPlayer2")) { if (name.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放 if (newOwner.isEmpty()) {
m_isActived = !newOwner.isEmpty(); m_mprisServices.removeAll(name);
if (m_isActived) { } else if (serviceCanPlay(name)){
m_serviceName = name; m_mprisServices << name;
m_mediaInter = new MediaPlayerInterface(m_serviceName, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
connect(m_mediaInter, &MediaPlayerInterface::PlaybackStatusChanged, this, [ this ] {
Q_EMIT statusChanged(convertStatus(m_mediaInter->playbackStatus()));
});
connect(m_mediaInter, &MediaPlayerInterface::MetadataChanged, this, &MediaPlayerModel::metadataChanged);
Dict v = m_mediaInter->metadata();
m_name = v.value("xesam:title").toString();
m_icon = v.value("mpris:artUrl").toString();
m_album = v.value("xesam:album").toString();
m_artist = v.value("xesam:artist").toString();
} else { } else {
if (!m_serviceName.isEmpty()) { qWarning() << "ignore invalid service" << name;
delete m_mediaInter;
m_mediaInter = nullptr;
}
m_serviceName.clear();
} }
Q_EMIT startStop(m_isActived);
onServiceChanged();
} }
}); });
connect(dbusInterface, &QDBusConnectionInterface::serviceUnregistered, this, connect(dbusInterface, &QDBusConnectionInterface::serviceUnregistered, this,
[ = ](const QString &service) { [ = ](const QString &service) {
if (service.startsWith("org.mpris.MediaPlayer2")) { if (service.startsWith("org.mpris.MediaPlayer2")) {
// 启动了音乐播放 m_mprisServices.removeAll(service);
m_serviceName.clear();
m_isActived = false; onServiceChanged();
Q_EMIT startStop(m_isActived);
} }
}); });
}); });

View File

@ -54,10 +54,11 @@ Q_SIGNALS:
private: private:
void initMediaPlayer(); void initMediaPlayer();
PlayStatus convertStatus(const QString &stat); PlayStatus convertStatus(const QString &stat);
void onServiceChanged();
private: private:
bool m_isActived; bool m_isActived;
QString m_serviceName; QStringList m_mprisServices;
QString m_name; QString m_name;
QString m_icon; QString m_icon;
QString m_album; QString m_album;