Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions mpd-interface/mpdconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,13 +1220,53 @@ void MPDConnection::playListChanges()
playListInfo();
}

std::pair<QList<Song>, bool> MPDConnection::readPlaylistInfoChunked()
{
quint32 playlistLength = 0;
quint32 playlistVersion = 0;
Response status = sendCommand("status");
if (!status.ok) {
return {{}, false};
}

MPDStatusValues sv = MPDParseUtils::parseStatus(status.data);
playlistLength = sv.playlistLength;
playlistVersion = sv.playlist;

for (int retry = 0; retry < 10; ++retry) {
QList<Song> songs;
const quint32 batchSize = 10000;
for (quint32 batchStart = 0; batchStart < playlistLength; batchStart += batchSize) {
const quint32 batchEnd = std::min(batchStart + batchSize, playlistLength);
Response response = sendCommand("playlistinfo " + QByteArray::number(batchStart) + ":" + QByteArray::number(batchEnd));
if (!response.ok) {
return {{}, false};
}

songs.append(MPDParseUtils::parseSongs(response.data, MPDParseUtils::Loc_PlayQueue));
}

Response status = sendCommand("status");
if (!status.ok) {
return {{}, false};
}
MPDStatusValues sv = MPDParseUtils::parseStatus(status.data);
if (playlistVersion == sv.playlist && playlistLength == sv.playlistLength) {
lastUpdatePlayQueueVersion = lastStatusPlayQueueVersion = sv.playlist;
emitStatusUpdated(sv);
return {songs, true};
}

// retry if playlist has changed while reading it
}
return {{}, false};
}

void MPDConnection::playListInfo()
{
Response response = sendCommand("playlistinfo");
QList<Song> songs;
if (response.ok) {
lastUpdatePlayQueueVersion = lastStatusPlayQueueVersion;
songs = MPDParseUtils::parseSongs(response.data, MPDParseUtils::Loc_PlayQueue);
const auto& [songs, ok] = readPlaylistInfoChunked();

if (ok) {
playQueueIds.clear();
streamIds.clear();

Expand All @@ -1249,12 +1289,9 @@ void MPDConnection::playListInfo()
if (songs.isEmpty()) {
stopVolumeFade();
}
Response status = sendCommand("status");
if (status.ok) {
MPDStatusValues sv = MPDParseUtils::parseStatus(status.data);
lastUpdatePlayQueueVersion = lastStatusPlayQueueVersion = sv.playlist;
emitStatusUpdated(sv);
}
}
else {
emit error(tr("Failed loading play queue from MPD"));
}
emit playlistUpdated(songs, true);
}
Expand Down
2 changes: 2 additions & 0 deletions mpd-interface/mpdconnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <QStringList>
#include <QTcpSocket>
#include <time.h>
#include <utility>

class QTimer;
class Thread;
Expand Down Expand Up @@ -507,6 +508,7 @@ private Q_SLOTS:
void getStickerSupport();
void playFirstTrack(bool emitErrors);
void determineIfaceIp();
std::pair<QList<Song>, bool> readPlaylistInfoChunked();

private:
bool isInitialConnect;
Expand Down
Loading