fix: last track of queue never plays & repeat playlist never works

This commit is contained in:
Kingkor Roy Tirtho 2023-08-25 22:52:43 +06:00
parent 190df17adc
commit c3c09f5b76
5 changed files with 45 additions and 29 deletions

View File

@ -98,10 +98,10 @@ mixin NextFetcher on StateNotifier<ProxyPlaylist> {
return sources return sources
.map((source) { .map((source) {
final track = state.tracks.firstWhereOrNull( final track = state.tracks.firstWhereOrNull(
(track) { (track) =>
final newSource = makeAppropriateSource(track); trackToUnplayableSource(track) == source ||
return newSource == source; (track is SpotubeTrack && track.ytUri == source) ||
}, (track is LocalTrack && track.path == source),
); );
return track; return track;
}) })

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:math';
import 'package:catcher/catcher.dart'; import 'package:catcher/catcher.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -129,6 +130,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
final oldTrack = final oldTrack =
mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull; mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
final track = await ensureSourcePlayable(audioPlayer.nextSource!); final track = await ensureSourcePlayable(audioPlayer.nextSource!);
if (track != null) { if (track != null) {
@ -439,13 +441,16 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
Future<void> next() async { Future<void> next() async {
if (audioPlayer.nextSource == null) return; if (audioPlayer.nextSource == null) return;
final oldTrack = mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull; final oldTrack = mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
state = state.copyWith( state = state.copyWith(
active: state.tracks active: state.tracks
.toList() .toList()
.indexWhere((element) => element.id == oldTrack?.id), .indexWhere((element) => element.id == oldTrack?.id),
); );
await audioPlayer.pause(); await audioPlayer.pause();
final track = await ensureSourcePlayable(audioPlayer.nextSource!); final track = await ensureSourcePlayable(audioPlayer.nextSource!);
if (track != null) { if (track != null) {
state = state.copyWith( state = state.copyWith(
tracks: mergeTracks([track], state.tracks), tracks: mergeTracks([track], state.tracks),
@ -613,7 +618,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
final oldCollections = state.collections; final oldCollections = state.collections;
await load( await load(
state.tracks, state.tracks,
initialIndex: state.active ?? 0, initialIndex: max(state.active ?? 0, 0),
autoPlay: false, autoPlay: false,
); );
state = state.copyWith(collections: oldCollections); state = state.copyWith(collections: oldCollections);

View File

@ -111,7 +111,7 @@ abstract class AudioPlayerInterface {
// } // }
} }
Future<PlaybackLoopMode> get loopMode async { PlaybackLoopMode get loopMode {
return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode); return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);
// if (mkSupportedPlatform) { // if (mkSupportedPlatform) {
// return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode); // return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);

View File

@ -156,6 +156,12 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
String? get nextSource { String? get nextSource {
// if (mkSupportedPlatform) { // if (mkSupportedPlatform) {
if (loopMode == PlaybackLoopMode.all &&
_mkPlayer.playlist.index == _mkPlayer.playlist.medias.length - 1) {
return sources.first;
}
return _mkPlayer.playlist.medias return _mkPlayer.playlist.medias
.elementAtOrNull(_mkPlayer.playlist.index + 1) .elementAtOrNull(_mkPlayer.playlist.index + 1)
?.uri; ?.uri;
@ -169,6 +175,10 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
} }
String? get previousSource { String? get previousSource {
if (loopMode == PlaybackLoopMode.all && _mkPlayer.playlist.index == 0) {
return sources.last;
}
// if (mkSupportedPlatform) { // if (mkSupportedPlatform) {
return _mkPlayer.playlist.medias return _mkPlayer.playlist.medias
.elementAtOrNull(_mkPlayer.playlist.index - 1) .elementAtOrNull(_mkPlayer.playlist.index - 1)

View File

@ -170,6 +170,7 @@ class MkPlayerWithState extends Player {
return super.open(_playlist!.medias[_playlist!.index], play: true); return super.open(_playlist!.medias[_playlist!.index], play: true);
} else if (!isLast) { } else if (!isLast) {
playlist = _playlist!.copyWith(index: _playlist!.index + 1); playlist = _playlist!.copyWith(index: _playlist!.index + 1);
return super.open(_playlist!.medias[_playlist!.index], play: true); return super.open(_playlist!.medias[_playlist!.index], play: true);
} }
} }
@ -233,30 +234,30 @@ class MkPlayerWithState extends Player {
final isOldUrlPlaying = _playlist!.medias[_playlist!.index].uri == oldUrl; final isOldUrlPlaying = _playlist!.medias[_playlist!.index].uri == oldUrl;
for (var i = 0; i < _playlist!.medias.length - 1; i++) { // ends the loop where match is found
final media = _playlist!.medias[i]; // tends to be a bit more efficient than forEach
if (media.uri == oldUrl) { _playlist!.medias.firstWhereIndexedOrNull((i, media) {
if (isOldUrlPlaying) { if (media.uri != oldUrl) return false;
pause(); if (isOldUrlPlaying) {
} pause();
final newMedias = _playlist!.medias.toList();
newMedias[i] = Media(newUrl, extras: media.extras);
playlist = _playlist!.copyWith(medias: newMedias);
if (isOldUrlPlaying) {
super.open(
newMedias[i],
play: true,
);
}
// replace in the _tempMedias if it's not null
if (shuffled && _tempMedias != null) {
final tempIndex = _tempMedias!.indexOf(media);
_tempMedias![tempIndex] = Media(newUrl, extras: media.extras);
}
break;
} }
} final copyMedias = [..._playlist!.medias];
copyMedias[i] = Media(newUrl, extras: media.extras);
playlist = _playlist!.copyWith(medias: copyMedias);
if (isOldUrlPlaying) {
super.open(
copyMedias[i],
play: true,
);
}
// replace in the _tempMedias if it's not null
if (shuffled && _tempMedias != null) {
final tempIndex = _tempMedias!.indexOf(media);
_tempMedias![tempIndex] = Media(newUrl, extras: media.extras);
}
return true;
});
} }
@override @override