Closed duypham312 closed 3 years ago
I'm not observing that behavior:
Oh, I understand now. You're talking about the audio. The title is changing but for some reason the audio is not matching the title. Let me look more into it.
Oh, I understand now. You're talking about the audio. The title is changing but for some reason the audio is not matching the title. Let me look more into it.
Yeah, that's what I meant
I'm a little stuck. I'm not sure how to solve this. If you find the solution can you let me know?
If I call _player.seekToNext()
it will play the right song but the labels will be messed up. Somehow the audio handler and the player need to be synced.
Actually, I had to use a temporary solution. First of all, I'm calling seekToNext()
and seekToPrevious()
instead of _skip()
. Then, I got the index of the song being played by the _player
in the shuffled list by the following way:
_audioPlayer.durationStream.listen((duration) {
var index = _audioPlayer.currentIndex;
final newQueue = queue.value;
if (index == null || newQueue.isEmpty) return;
if (_audioPlayer.shuffleModeEnabled) {
index = _audioPlayer.shuffleIndices!.indexOf(index);
}
final oldMediaItem = newQueue[index];
final newMediaItem = oldMediaItem.copyWith(duration: duration);
newQueue[index] = newMediaItem;
queue.add(newQueue);
mediaItem.add(newMediaItem);
});
_audioPlayer.currentIndexStream.listen((index) {
final playlist = queue.value;
if (index == null || playlist.isEmpty) return;
if (_audioPlayer.shuffleModeEnabled) {
index = _audioPlayer.shuffleIndices!.indexOf(index);
}
mediaItem.add(playlist[index]);
});
This solution can temporarily make the song's title sync with the song played by the _player
. However, in my case, when the current song ends, the player
plays the next song without following the shuffled order. I hope this temporary solution can help you find a more effective solution to this problem
In addition, this is how I implement skipToQueueItem(int index)
@override
Future<void> skipToQueueItem(int index) async {
if (index < 0 || index >= queue.value.length) return;
if (_audioPlayer.shuffleModeEnabled) {
index = _audioPlayer.shuffleIndices![index];
}
_audioPlayer.seek(Duration.zero, index: index);
}
Besides, if you have a more efficient solution, you can share it in the issue that I have opened here
@duypham312 Thank you for posting the solution you have so far. I reproduced your results. Seeking to next and previous works but when one song finishes it automatically loads the incorrect song even though shuffling mode is enabled.
Steps to reproduce (for others interested in this problem):
void _listenForDurationChanges() {
_player.durationStream.listen((duration) {
var index = _player.currentIndex;
final newQueue = queue.value;
if (index == null || newQueue.isEmpty) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices!.indexOf(index);
}
final oldMediaItem = newQueue[index];
final newMediaItem = oldMediaItem.copyWith(duration: duration);
newQueue[index] = newMediaItem;
queue.add(newQueue);
mediaItem.add(newMediaItem);
});
}
void _listenForCurrentSongIndexChanges() {
_player.currentIndexStream.listen((index) {
final playlist = queue.value;
if (index == null || playlist.isEmpty) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices!.indexOf(index);
}
mediaItem.add(playlist[index]);
});
}
@override
Future<void> skipToQueueItem(int index) async {
if (index < 0 || index >= queue.value.length) return;
if (_player.shuffleModeEnabled) {
index = _player.shuffleIndices![index];
}
_player.seek(Duration.zero, index: index);
}
@override
Future<void> skipToNext() async {
_player.seekToNext();
}
@override
Future<void> skipToPrevious() async {
_player.seekToPrevious();
}
The next played song is Song 2 even though it should be Song 3.
I added a note to the shuffle section of the tutorial alerting readers to the bug and directing them here.
The source code for just_audio_background might provide some clues, but this is pretty different than my tutorial setup.
@suragch Hey, have you tried to reproduce this error on Android? This bug has gone when I test on my android phone. I think this might be a bug of just_audio and it only happens on iOS
I think I found the cause of the bug related to auto-next. The _player.setShuffleModeEnabled(true)
is called before the _player.shuffle()
is called and that resulted in the problem as I mentioned. When I call await _player.shuffle()
before _player.setShuffleModeEnabled(true)
, it works properly.
@suragch hey, I found another bug related to the shuffle mode. If I play Song 3 while the shuffle mode is on and let it end, the app will crash without printing any error message.
@duypham312 Nice job on finding a workaround for the auto-next issue!
The play-song-3-on-shuffle-mode bug seems to only cause a crash on iOS and macOS. Android and web work for me.
I've updated the tutorial and the project code up to this point. Even though there is still a bug with shuffling, it's better than it was before.
@suragch hey, Ryanheise just informed me about the new fix/queue
branch, I tested with this branch and the app doesn't crash anymore.
@duypham312 That's great! Could you ping me again when that branch gets merged?
That branch has been merged, you can update the tutorial now
I've updated the tutorial. Thank you for your help in resolving this problem! I'll close the issue now.
As the title mentioned,
skipToNext()
andskipToPrevious()
functions do not work properly whenshuffleModeEnabled
is true. For example, if the initial order is[song 1, song 2, song 3]
and the shuffled order is[song 1, song 3, song 2]
, when skipping to the second song in the shuffled order (song 3
with theindex
is1
in that array), callingskipToNext()
will playsong 2
even though the UI will showsong 3
as the current song being played. I think this problem comes from the implementation ofskipToNext()
andskipToPrevious()
that callingseek(Duration.zero, index: index)
becauseseek(Duration.zero, index: index)
operates on the initial order, not the shuffled order.