Changeset View
Changeset View
Standalone View
Standalone View
plugins/mprisremote/mprisremoteplugin.cpp
Show All 29 Lines | |||||
30 | #include <core/device.h> | 30 | #include <core/device.h> | ||
31 | 31 | | |||
32 | K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mprisremote.json", registerPlugin< MprisRemotePlugin >(); ) | 32 | K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mprisremote.json", registerPlugin< MprisRemotePlugin >(); ) | ||
33 | 33 | | |||
34 | Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_MPRISREMOTE, "kdeconnect.plugin.mprisremote") | 34 | Q_LOGGING_CATEGORY(KDECONNECT_PLUGIN_MPRISREMOTE, "kdeconnect.plugin.mprisremote") | ||
35 | 35 | | |||
36 | MprisRemotePlugin::MprisRemotePlugin(QObject* parent, const QVariantList& args) | 36 | MprisRemotePlugin::MprisRemotePlugin(QObject* parent, const QVariantList& args) | ||
37 | : KdeConnectPlugin(parent, args) | 37 | : KdeConnectPlugin(parent, args) | ||
38 | , m_player() | 38 | , m_currentPlayer() | ||
39 | , m_playing(false) | 39 | , m_players() | ||
40 | , m_nowPlaying() | | |||
41 | , m_volume(50) | | |||
42 | , m_length(0) | | |||
43 | , m_lastPosition(0) | | |||
44 | , m_lastPositionTime() | | |||
45 | , m_playerList() | | |||
46 | { | 40 | { | ||
47 | } | 41 | } | ||
48 | 42 | | |||
49 | MprisRemotePlugin::~MprisRemotePlugin() | 43 | MprisRemotePlugin::~MprisRemotePlugin() | ||
50 | { | 44 | { | ||
51 | } | 45 | } | ||
52 | 46 | | |||
53 | bool MprisRemotePlugin::receivePacket(const NetworkPacket& np) | 47 | bool MprisRemotePlugin::receivePacket(const NetworkPacket& np) | ||
54 | { | 48 | { | ||
55 | if (np.type() != PACKET_TYPE_MPRIS) | 49 | if (np.type() != PACKET_TYPE_MPRIS) | ||
56 | return false; | 50 | return false; | ||
57 | 51 | | |||
58 | if (np.has(QStringLiteral("nowPlaying")) || np.has(QStringLiteral("volume")) || np.has(QStringLiteral("isPlaying")) || np.has(QStringLiteral("length")) || np.has(QStringLiteral("pos"))) { | 52 | if (np.has(QStringLiteral("player"))) { | ||
59 | if (np.get<QString>(QStringLiteral("player")) == m_player) { | 53 | m_players[m_currentPlayer]->parseNetworkPacket(np); | ||
60 | m_nowPlaying = np.get<QString>(QStringLiteral("nowPlaying"), m_nowPlaying); | | |||
61 | m_volume = np.get<int>(QStringLiteral("volume"), m_volume); | | |||
62 | m_length = np.get<int>(QStringLiteral("length"), m_length); | | |||
63 | if(np.has(QStringLiteral("pos"))){ | | |||
64 | m_lastPosition = np.get<int>(QStringLiteral("pos"), m_lastPosition); | | |||
65 | m_lastPositionTime = QDateTime::currentMSecsSinceEpoch(); | | |||
66 | } | 54 | } | ||
67 | m_playing = np.get<bool>(QStringLiteral("isPlaying"), m_playing); | 55 | | ||
56 | if (np.has(QStringLiteral("playerList"))) { | ||||
57 | QStringList players = np.get<QStringList>(QStringLiteral("playerList")); | ||||
58 | qDeleteAll(m_players); | ||||
59 | m_players.clear(); | ||||
60 | for (const QString& player : players) { | ||||
61 | m_players[player] = new MprisRemotePlayer(); | ||||
68 | } | 62 | } | ||
63 | | ||||
64 | if (m_players.empty()) { | ||||
65 | m_currentPlayer = QString(); | ||||
66 | } else if (!m_players.contains(m_currentPlayer)) { | ||||
67 | m_currentPlayer = m_players.keys().first(); | ||||
69 | } | 68 | } | ||
70 | 69 | | |||
71 | if (np.has(QStringLiteral("playerList"))) { | | |||
72 | m_playerList = np.get<QStringList>(QStringLiteral("playerList"), QStringList()); | | |||
73 | } | 70 | } | ||
74 | Q_EMIT propertiesChanged(); | 71 | Q_EMIT propertiesChanged(); | ||
75 | 72 | | |||
76 | return true; | 73 | return true; | ||
77 | } | 74 | } | ||
78 | 75 | | |||
79 | long MprisRemotePlugin::position() const | 76 | long MprisRemotePlugin::position() const | ||
80 | { | 77 | { | ||
81 | if(m_playing) { | 78 | auto player = m_players.value(m_currentPlayer); | ||
82 | return m_lastPosition + (QDateTime::currentMSecsSinceEpoch() - m_lastPositionTime); | 79 | return player ? player->position() : 0; | ||
83 | } else { | | |||
84 | return m_lastPosition; | | |||
85 | } | | |||
86 | } | 80 | } | ||
87 | 81 | | |||
88 | QString MprisRemotePlugin::dbusPath() const | 82 | QString MprisRemotePlugin::dbusPath() const | ||
89 | { | 83 | { | ||
90 | return "/modules/kdeconnect/devices/" + device()->id() + "/mprisremote"; | 84 | return "/modules/kdeconnect/devices/" + device()->id() + "/mprisremote"; | ||
91 | } | 85 | } | ||
92 | 86 | | |||
93 | void MprisRemotePlugin::requestPlayerStatus() | 87 | void MprisRemotePlugin::requestPlayerStatus() | ||
94 | { | 88 | { | ||
95 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | 89 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | ||
96 | {"player", m_player}, | 90 | {"player", m_currentPlayer}, | ||
97 | {"requestNowPlaying", true}, | 91 | {"requestNowPlaying", true}, | ||
98 | {"requestVolume", true}} | 92 | {"requestVolume", true}} | ||
99 | ); | 93 | ); | ||
100 | sendPacket(np); | 94 | sendPacket(np); | ||
101 | } | 95 | } | ||
102 | 96 | | |||
103 | void MprisRemotePlugin::requestPlayerList() | 97 | void MprisRemotePlugin::requestPlayerList() | ||
104 | { | 98 | { | ||
105 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, {{"requestPlayerList", true}}); | 99 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, {{"requestPlayerList", true}}); | ||
106 | sendPacket(np); | 100 | sendPacket(np); | ||
107 | } | 101 | } | ||
108 | 102 | | |||
109 | void MprisRemotePlugin::sendAction(const QString& action) | 103 | void MprisRemotePlugin::sendAction(const QString& action) | ||
110 | { | 104 | { | ||
111 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | 105 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | ||
112 | {"player", m_player}, | 106 | {"player", m_currentPlayer}, | ||
113 | {"action", action} | 107 | {"action", action} | ||
114 | }); | 108 | }); | ||
115 | sendPacket(np); | 109 | sendPacket(np); | ||
116 | } | 110 | } | ||
117 | 111 | | |||
118 | void MprisRemotePlugin::seek(int offset) const | 112 | void MprisRemotePlugin::seek(int offset) const | ||
119 | { | 113 | { | ||
120 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | 114 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | ||
121 | {"player", m_player}, | 115 | {"player", m_currentPlayer}, | ||
122 | {"Seek", offset}}); | 116 | {"Seek", offset}}); | ||
123 | sendPacket(np); | 117 | sendPacket(np); | ||
124 | } | 118 | } | ||
125 | 119 | | |||
126 | void MprisRemotePlugin::setVolume(int volume) | 120 | void MprisRemotePlugin::setVolume(int volume) | ||
127 | { | 121 | { | ||
128 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | 122 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | ||
129 | {"player", m_player}, | 123 | {"player", m_currentPlayer}, | ||
130 | {"setVolume",volume} | 124 | {"setVolume",volume} | ||
131 | }); | 125 | }); | ||
132 | sendPacket(np); | 126 | sendPacket(np); | ||
133 | } | 127 | } | ||
134 | 128 | | |||
135 | void MprisRemotePlugin::setPosition(int position) | 129 | void MprisRemotePlugin::setPosition(int position) | ||
136 | { | 130 | { | ||
137 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | 131 | NetworkPacket np(PACKET_TYPE_MPRIS_REQUEST, { | ||
138 | {"player", m_player}, | 132 | {"player", m_currentPlayer}, | ||
139 | {"SetPosition", position} | 133 | {"SetPosition", position} | ||
140 | }); | 134 | }); | ||
141 | sendPacket(np); | 135 | sendPacket(np); | ||
142 | 136 | | |||
143 | m_lastPosition = position; | 137 | m_players[m_currentPlayer]->setPosition(position); | ||
144 | m_lastPositionTime = QDateTime::currentMSecsSinceEpoch(); | | |||
145 | } | 138 | } | ||
146 | 139 | | |||
147 | void MprisRemotePlugin::setPlayer(const QString& player) | 140 | void MprisRemotePlugin::setPlayer(const QString& player) | ||
148 | { | 141 | { | ||
149 | if (m_player != player) { | 142 | if (m_currentPlayer != player) { | ||
150 | m_player = player; | 143 | m_currentPlayer = player; | ||
151 | requestPlayerStatus(); | 144 | requestPlayerStatus(); | ||
145 | Q_EMIT propertiesChanged(); | ||||
146 | } | ||||
152 | } | 147 | } | ||
148 | | ||||
149 | bool MprisRemotePlugin::isPlaying() const | ||||
150 | { | ||||
151 | auto player = m_players.value(m_currentPlayer); | ||||
152 | return player ? player->playing() : false; | ||||
153 | } | ||||
154 | | ||||
155 | int MprisRemotePlugin::length() const | ||||
156 | { | ||||
157 | auto player = m_players.value(m_currentPlayer); | ||||
158 | return player ? player->length() : 0; | ||||
159 | } | ||||
160 | | ||||
161 | int MprisRemotePlugin::volume() const | ||||
162 | { | ||||
163 | auto player = m_players.value(m_currentPlayer); | ||||
164 | return player ? player->volume() : 0; | ||||
165 | } | ||||
166 | | ||||
167 | QString MprisRemotePlugin::player() const | ||||
168 | { | ||||
169 | if (m_currentPlayer.isEmpty()) | ||||
170 | return QString(); | ||||
171 | return m_currentPlayer; | ||||
172 | } | ||||
173 | | ||||
174 | QStringList MprisRemotePlugin::playerList() const | ||||
175 | { | ||||
176 | return m_players.keys(); | ||||
177 | } | ||||
178 | | ||||
179 | QString MprisRemotePlugin::nowPlaying() const | ||||
180 | { | ||||
181 | auto player = m_players.value(m_currentPlayer); | ||||
182 | return player ? player->nowPlaying() : QString(); | ||||
183 | } | ||||
184 | | ||||
185 | QString MprisRemotePlugin::title() const | ||||
186 | { | ||||
187 | auto player = m_players.value(m_currentPlayer); | ||||
188 | return player ? player->title() : QString(); | ||||
189 | } | ||||
190 | | ||||
191 | QString MprisRemotePlugin::album() const | ||||
192 | { | ||||
193 | auto player = m_players.value(m_currentPlayer); | ||||
194 | return player ? player->album() : QString(); | ||||
195 | } | ||||
196 | | ||||
197 | QString MprisRemotePlugin::artist() const | ||||
198 | { | ||||
199 | auto player = m_players.value(m_currentPlayer); | ||||
200 | return player ? player->artist() : QString(); | ||||
153 | } | 201 | } | ||
154 | 202 | | |||
155 | #include "mprisremoteplugin.moc" | 203 | #include "mprisremoteplugin.moc" | ||
apol: While this will work, if the map ever gets out of sync we could get a crash.
Maybe it's just… |
While this will work, if the map ever gets out of sync we could get a crash.
Maybe it's just safer to do something like: