fix: track not skipping to next even when source is available

This commit is contained in:
Kingkor Roy Tirtho 2023-08-04 11:51:13 +06:00
parent 0e5d54639a
commit 0b7affdc05
5 changed files with 19 additions and 42 deletions

View File

@ -72,7 +72,9 @@ class PlaylistCard extends HookConsumerWidget {
playlistNotifier.addCollection(playlist.id!);
tracks.value = fetchedTracks;
} finally {
updating.value = false;
if (context.mounted) {
updating.value = false;
}
}
},
onAddToQueuePressed: () async {

View File

@ -156,7 +156,7 @@ if (DesktopTools.platform.isAndroid) {
runApp(
DevicePreview(
availableLocales: L10n.all,
enabled: !kReleaseMode && DesktopTools.platform.isDesktop,
enabled: false,
data: const DevicePreviewData(
isEnabled: false,
orientation: Orientation.portrait,

View File

@ -1,12 +0,0 @@
import 'package:dbus/dbus.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotube/utils/platform.dart';
final Provider<DBusClient?> dbusClientProvider = Provider<DBusClient?>((ref) {
if (kIsLinux) {
return DBusClient.session();
}
return null;
});
final dbus = DBusClient.session();

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:async/async.dart';
import 'package:catcher/catcher.dart';
import 'package:collection/collection.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -68,7 +69,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
() async {
notificationService = await AudioServices.create(ref, this);
(String, List<SkipSegment>)? currentSegments;
({String source, List<SkipSegment> segments})? currentSegments;
bool isFetchingSegments = false;
audioPlayer.activeSourceChangedStream.listen((newActiveSource) async {
final newActiveTrack =
@ -110,14 +111,14 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
bool isPreSearching = false;
listenTo60Percent(percent) async {
listenTo2Percent(int percent) async {
if (isPreSearching ||
audioPlayer.currentSource == null ||
audioPlayer.nextSource == null) return;
try {
isPreSearching = true;
// TODO: Make repeat mode sensitive changes later
final oldTrack =
mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
final track = await ensureSourcePlayable(audioPlayer.nextSource!);
@ -126,12 +127,12 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
if (currentSegments == null ||
(oldTrack?.id != null &&
currentSegments!.$1 != oldTrack!.id!) &&
currentSegments!.source != oldTrack!.id!) &&
!isFetchingSegments) {
isFetchingSegments = true;
currentSegments = (
audioPlayer.currentSource!,
await getAndCacheSkipSegments(
source: audioPlayer.currentSource!,
segments: await getAndCacheSkipSegments(
track.ytTrack.id,
),
);
@ -147,47 +148,32 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
}
} finally {
isPreSearching = false;
/// Sometimes fetching can take a lot of time, so we need to check
/// if next source is playable or not at 99% progress. If not, then
/// it'll be paused automatically
///
/// After fetching the nextSource and replacing it, we need to check
/// if the player is paused or not. If it is paused, then we need to
/// resume it to skip to next track
if (audioPlayer.isPaused) {
if (percent > 98 && !audioPlayer.isPlaying) {
await audioPlayer.resume();
}
}
}
audioPlayer.percentCompletedStream(60).listen(listenTo60Percent);
// player stops at 99% if nextSource is still not playable
audioPlayer.percentCompletedStream(99).listen((_) async {
if (audioPlayer.nextSource == null ||
isPlayable(audioPlayer.nextSource!)) return;
await audioPlayer.pause();
});
audioPlayer.percentCompletedStream(2).listen(listenTo2Percent);
audioPlayer.positionStream.listen((position) async {
if (preferences.searchMode == SearchMode.youtubeMusic ||
!preferences.skipNonMusic) return;
if (currentSegments == null ||
currentSegments!.$1 != state.activeTrack!.id! &&
currentSegments!.source != state.activeTrack!.id! &&
!isFetchingSegments) {
isFetchingSegments = true;
currentSegments = (
audioPlayer.currentSource!,
await getAndCacheSkipSegments(
source: audioPlayer.currentSource!,
segments: await getAndCacheSkipSegments(
(state.activeTrack as SpotubeTrack).ytTrack.id,
),
);
isFetchingSegments = false;
}
final (_, segments) = currentSegments!;
final (source: _, :segments) = currentSegments!;
if (segments.isEmpty) return;
for (final segment in segments) {

View File

@ -3,7 +3,6 @@ import 'dart:io';
import 'package:dbus/dbus.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotube/provider/dbus_provider.dart';
import 'package:spotube/models/spotube_track.dart';
import 'package:spotube/provider/proxy_playlist/proxy_playlist.dart';
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart';
@ -12,6 +11,8 @@ import 'package:spotube/services/audio_player/loop_mode.dart';
import 'package:spotube/utils/type_conversion_utils.dart';
import 'package:window_manager/window_manager.dart';
final dbus = DBusClient.session();
class _MprisMediaPlayer2 extends DBusObject {
/// Creates a new object to expose on [path].
_MprisMediaPlayer2() : super(DBusObjectPath('/org/mpris/MediaPlayer2')) {