Fixed last track not sent to ListenBrainz, fixes #438

This commit is contained in:
emeric
2024-03-27 23:42:26 +01:00
parent ac69582f4b
commit 2d01814ede
3 changed files with 61 additions and 54 deletions
+11 -7
View File
@@ -97,17 +97,21 @@ LMS.mediaplayer = function () {
_lastStartPlaying = Date.now(); _lastStartPlaying = Date.now();
} }
let _stopTimer = function() { let _pauseTimer = function() {
if (_lastStartPlaying != null) { if (_lastStartPlaying != null) {
_playedDuration += Date.now() - _lastStartPlaying; _playedDuration += Date.now() - _lastStartPlaying;
_lastStartPlaying = null;
} }
} }
let _resetTimer = function() { let _resetTimer = function() {
if (_lastStartPlaying != null) if (_lastStartPlaying != null)
_pauseTimer();
if (_playedDuration > 0) {
Wt.emit(_root, "scrobbleListenFinished", _trackId, _playedDuration); Wt.emit(_root, "scrobbleListenFinished", _trackId, _playedDuration);
_playedDuration = 0; _playedDuration = 0;
_lastStartPlaying = null; }
} }
let _durationToString = function (duration) { let _durationToString = function (duration) {
@@ -229,7 +233,7 @@ LMS.mediaplayer = function () {
navigator.mediaSession.setPositionState({ navigator.mediaSession.setPositionState({
duration: _duration, duration: _duration,
playbackRate: 1, playbackRate: 1,
position: _offset + _elems.audio.currentTime, position: Math.min(_offset + _elems.audio.currentTime, _duration),
}); });
if (_elems.audio.paused) if (_elems.audio.paused)
@@ -276,9 +280,9 @@ LMS.mediaplayer = function () {
_elems.audio.addEventListener("playing", _updateMediaSessionState); _elems.audio.addEventListener("playing", _updateMediaSessionState);
_elems.audio.addEventListener("pause", _updateMediaSessionState); _elems.audio.addEventListener("pause", _updateMediaSessionState);
_elems.audio.addEventListener("pause", _stopTimer); _elems.audio.addEventListener("pause", _pauseTimer);
_elems.audio.addEventListener("playing", _startTimer); _elems.audio.addEventListener("playing", _startTimer);
_elems.audio.addEventListener("waiting", _stopTimer); _elems.audio.addEventListener("waiting", _pauseTimer);
_elems.audio.addEventListener("timeupdate", function() { _elems.audio.addEventListener("timeupdate", function() {
_elems.progress.style.width = "" + ((_offset + _elems.audio.currentTime) / _duration) * 100 + "%"; _elems.progress.style.width = "" + ((_offset + _elems.audio.currentTime) / _duration) * 100 + "%";
@@ -286,6 +290,7 @@ LMS.mediaplayer = function () {
}); });
_elems.audio.addEventListener("ended", function() { _elems.audio.addEventListener("ended", function() {
_resetTimer();
Wt.emit(_root, "playbackEnded"); Wt.emit(_root, "playbackEnded");
}); });
@@ -366,7 +371,6 @@ LMS.mediaplayer = function () {
} }
let loadTrack = function(params, autoplay) { let loadTrack = function(params, autoplay) {
_stopTimer();
_resetTimer(); _resetTimer();
_trackId = params.trackId; _trackId = params.trackId;
+49 -46
View File
@@ -489,10 +489,12 @@ namespace lms::ui
// Events from MediaPlayer // Events from MediaPlayer
_mediaPlayer->playNext.connect([this] _mediaPlayer->playNext.connect([this]
{ {
LMS_LOG(UI, DEBUG, "Received playNext from player");
_playQueue->playNext(); _playQueue->playNext();
}); });
_mediaPlayer->playPrevious.connect([this] _mediaPlayer->playPrevious.connect([this]
{ {
LMS_LOG(UI, DEBUG, "Received playPrevious from player");
_playQueue->playPrevious(); _playQueue->playPrevious();
}); });
@@ -501,58 +503,59 @@ namespace lms::ui
LMS_LOG(UI, DEBUG, "Received ScrobbleListenNow from player for trackId = " << trackId.toString()); LMS_LOG(UI, DEBUG, "Received ScrobbleListenNow from player for trackId = " << trackId.toString());
const scrobbling::Listen listen{ getUserId(), trackId }; const scrobbling::Listen listen{ getUserId(), trackId };
core::Service<scrobbling::IScrobblingService>::get()->listenStarted(listen); core::Service<scrobbling::IScrobblingService>::get()->listenStarted(listen);
}); });
_mediaPlayer->scrobbleListenFinished.connect([this](db::TrackId trackId, unsigned durationMs) _mediaPlayer->scrobbleListenFinished.connect([this](db::TrackId trackId, unsigned durationMs)
{ {
LMS_LOG(UI, DEBUG, "Received ScrobbleListenFinished from player for trackId = " << trackId.toString() << ", duration = " << (durationMs / 1000) << "s"); LMS_LOG(UI, DEBUG, "Received ScrobbleListenFinished from player for trackId = " << trackId.toString() << ", duration = " << (durationMs / 1000) << "s");
const std::chrono::milliseconds duration{ durationMs }; const std::chrono::milliseconds duration{ durationMs };
const scrobbling::Listen listen{ getUserId(), trackId }; const scrobbling::Listen listen{ getUserId(), trackId };
core::Service<scrobbling::IScrobblingService>::get()->listenFinished(listen, std::chrono::duration_cast<std::chrono::seconds>(duration)); core::Service<scrobbling::IScrobblingService>::get()->listenFinished(listen, std::chrono::duration_cast<std::chrono::seconds>(duration));
}); });
_mediaPlayer->playbackEnded.connect([this] _mediaPlayer->playbackEnded.connect([this]
{ {
_playQueue->onPlaybackEnded(); LMS_LOG(UI, DEBUG, "Received playbackEnded from player");
}); _playQueue->onPlaybackEnded();
});
_playQueue->trackSelected.connect([this](db::TrackId trackId, bool play, float replayGain) _playQueue->trackSelected.connect([this](db::TrackId trackId, bool play, float replayGain)
{ {
_mediaPlayer->loadTrack(trackId, play, replayGain); _mediaPlayer->loadTrack(trackId, play, replayGain);
}); });
_playQueue->trackUnselected.connect([this] _playQueue->trackUnselected.connect([this]
{ {
_mediaPlayer->stop(); _mediaPlayer->stop();
}); });
_playQueue->trackCountChanged.connect([this](std::size_t trackCount) _playQueue->trackCountChanged.connect([this](std::size_t trackCount)
{ {
_mediaPlayer->onPlayQueueUpdated(trackCount); _mediaPlayer->onPlayQueueUpdated(trackCount);
}); });
_mediaPlayer->onPlayQueueUpdated(_playQueue->getCount()); _mediaPlayer->onPlayQueueUpdated(_playQueue->getCount());
const bool isAdmin{ getUserType() == db::UserType::ADMIN }; const bool isAdmin{ getUserType() == db::UserType::ADMIN };
if (isAdmin) if (isAdmin)
{ {
_scannerEvents.scanComplete.connect([this](const scanner::ScanStats& stats) _scannerEvents.scanComplete.connect([this](const scanner::ScanStats& stats)
{ {
notifyMsg(Notification::Type::Info, notifyMsg(Notification::Type::Info,
Wt::WString::tr("Lms.Admin.Database.database"), Wt::WString::tr("Lms.Admin.Database.database"),
Wt::WString::tr("Lms.Admin.Database.scan-complete") Wt::WString::tr("Lms.Admin.Database.scan-complete")
.arg(static_cast<unsigned>(stats.nbFiles())) .arg(static_cast<unsigned>(stats.nbFiles()))
.arg(static_cast<unsigned>(stats.additions)) .arg(static_cast<unsigned>(stats.additions))
.arg(static_cast<unsigned>(stats.updates)) .arg(static_cast<unsigned>(stats.updates))
.arg(static_cast<unsigned>(stats.deletions)) .arg(static_cast<unsigned>(stats.deletions))
.arg(static_cast<unsigned>(stats.duplicates.size())) .arg(static_cast<unsigned>(stats.duplicates.size()))
.arg(static_cast<unsigned>(stats.errors.size()))); .arg(static_cast<unsigned>(stats.errors.size())));
}); });
} }
internalPathChanged().connect(mainStack, [=] internalPathChanged().connect(mainStack, [=]
{ {
handlePathChange(*mainStack, isAdmin); handlePathChange(*mainStack, isAdmin);
}); });
handlePathChange(*mainStack, isAdmin); handlePathChange(*mainStack, isAdmin);
} }
void LmsApplication::notify(const Wt::WEvent& event) void LmsApplication::notify(const Wt::WEvent& event)
+1 -1
View File
@@ -253,7 +253,7 @@ namespace lms::ui
<< " trackId :\"" << trackId.toString() << "\"," << " trackId :\"" << trackId.toString() << "\","
<< " nativeResource: \"" << nativeResource << "\"," << " nativeResource: \"" << nativeResource << "\","
<< " transcodingResource: \"" << transcodingResource << "\"," << " transcodingResource: \"" << transcodingResource << "\","
<< " duration: " << std::chrono::duration_cast<std::chrono::seconds>(track->getDuration()).count() << "," << " duration: " << std::chrono::duration_cast<std::chrono::duration<float>>(track->getDuration()).count() << ","
<< " replayGain: " << replayGain << "," << " replayGain: " << replayGain << ","
<< " title: \"" << core::stringUtils::jsEscape(track->getName()) << "\"," << " title: \"" << core::stringUtils::jsEscape(track->getName()) << "\","
<< " artist: \"" << (!artists.empty() ? core::stringUtils::jsEscape(track->getArtistDisplayName()) : "") << "\"," << " artist: \"" << (!artists.empty() ? core::stringUtils::jsEscape(track->getArtistDisplayName()) : "") << "\","