Rapidly using "Previous" or "Next" is broken.
Double-tapping Player.previousTrack()
before the UI's done updating, the second tap actually goes forwards, from i-1
back to the current track i
, instead of going backwards to i-2
. The indices are correct in Playlist::previous()
, but MediaPlayer2Player::setCurrentTrack()
ends up getting called too many times and with the wrong index. GDB shows that the extraneous calls were coming from Playlist::next()
.
Double-tapping Player.nextTrack()
before the UI's done updating, the second tap actually sometimes goes forwards by two or three tracks, from i+1
to i+3
or i+4
instead of i+2
. GDB also shows the extra jumps are caused by extra calls to Playlist::next()
.
This appears to be caused by the call to Player.nextTrack()
in the player.onFinished
handler in main.qml
.
The bug is in the the &QMediaPlayer::stateChanged
signal connection for Player
that handles advancing to the next track, at player.cpp:L16
. When changing tracks, multiple stateChanged
signals can be dispatched. When rapidly skipping with "Previous" or "Next", presumably due to track metadata not yet having been initialized, this can include a signal in StoppedState
while player->position()
and player->duration()
both equal zero, which the current check mistakenly identifies as reaching the end of a track, emitting the ->finished()
signal and causing Player.nextTrack()
to be incorrectly called in main.qml
:
if (state == QMediaPlayer::StoppedState && this->player->position() == this->player->duration())
Checking that the position/duration are non-zero fixes this issue, and I believe should not really break anything else:
auto position = this->player->position();
if (state == QMediaPlayer::StoppedState && position > 0.0 && position == this->player->duration())
(If anyone actually has a truly zero-length track, this would however prevent the play queue from automatically advancing past that, I guess.)