mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
fix: track not skipping to next even when source is available
This commit is contained in:
parent
0e5d54639a
commit
0b7affdc05
@ -72,7 +72,9 @@ class PlaylistCard extends HookConsumerWidget {
|
|||||||
playlistNotifier.addCollection(playlist.id!);
|
playlistNotifier.addCollection(playlist.id!);
|
||||||
tracks.value = fetchedTracks;
|
tracks.value = fetchedTracks;
|
||||||
} finally {
|
} finally {
|
||||||
updating.value = false;
|
if (context.mounted) {
|
||||||
|
updating.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onAddToQueuePressed: () async {
|
onAddToQueuePressed: () async {
|
||||||
|
@ -156,7 +156,7 @@ if (DesktopTools.platform.isAndroid) {
|
|||||||
runApp(
|
runApp(
|
||||||
DevicePreview(
|
DevicePreview(
|
||||||
availableLocales: L10n.all,
|
availableLocales: L10n.all,
|
||||||
enabled: !kReleaseMode && DesktopTools.platform.isDesktop,
|
enabled: false,
|
||||||
data: const DevicePreviewData(
|
data: const DevicePreviewData(
|
||||||
isEnabled: false,
|
isEnabled: false,
|
||||||
orientation: Orientation.portrait,
|
orientation: Orientation.portrait,
|
||||||
|
@ -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();
|
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:async/async.dart';
|
||||||
import 'package:catcher/catcher.dart';
|
import 'package:catcher/catcher.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@ -68,7 +69,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
|
|||||||
() async {
|
() async {
|
||||||
notificationService = await AudioServices.create(ref, this);
|
notificationService = await AudioServices.create(ref, this);
|
||||||
|
|
||||||
(String, List<SkipSegment>)? currentSegments;
|
({String source, List<SkipSegment> segments})? currentSegments;
|
||||||
bool isFetchingSegments = false;
|
bool isFetchingSegments = false;
|
||||||
audioPlayer.activeSourceChangedStream.listen((newActiveSource) async {
|
audioPlayer.activeSourceChangedStream.listen((newActiveSource) async {
|
||||||
final newActiveTrack =
|
final newActiveTrack =
|
||||||
@ -110,14 +111,14 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
|
|||||||
|
|
||||||
bool isPreSearching = false;
|
bool isPreSearching = false;
|
||||||
|
|
||||||
listenTo60Percent(percent) async {
|
listenTo2Percent(int percent) async {
|
||||||
if (isPreSearching ||
|
if (isPreSearching ||
|
||||||
audioPlayer.currentSource == null ||
|
audioPlayer.currentSource == null ||
|
||||||
audioPlayer.nextSource == null) return;
|
audioPlayer.nextSource == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
isPreSearching = true;
|
isPreSearching = true;
|
||||||
|
|
||||||
// TODO: Make repeat mode sensitive changes later
|
|
||||||
final oldTrack =
|
final oldTrack =
|
||||||
mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
|
mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
|
||||||
final track = await ensureSourcePlayable(audioPlayer.nextSource!);
|
final track = await ensureSourcePlayable(audioPlayer.nextSource!);
|
||||||
@ -126,12 +127,12 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
|
|||||||
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
|
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
|
||||||
if (currentSegments == null ||
|
if (currentSegments == null ||
|
||||||
(oldTrack?.id != null &&
|
(oldTrack?.id != null &&
|
||||||
currentSegments!.$1 != oldTrack!.id!) &&
|
currentSegments!.source != oldTrack!.id!) &&
|
||||||
!isFetchingSegments) {
|
!isFetchingSegments) {
|
||||||
isFetchingSegments = true;
|
isFetchingSegments = true;
|
||||||
currentSegments = (
|
currentSegments = (
|
||||||
audioPlayer.currentSource!,
|
source: audioPlayer.currentSource!,
|
||||||
await getAndCacheSkipSegments(
|
segments: await getAndCacheSkipSegments(
|
||||||
track.ytTrack.id,
|
track.ytTrack.id,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -147,47 +148,32 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
isPreSearching = false;
|
isPreSearching = false;
|
||||||
|
if (percent > 98 && !audioPlayer.isPlaying) {
|
||||||
/// 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) {
|
|
||||||
await audioPlayer.resume();
|
await audioPlayer.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
audioPlayer.percentCompletedStream(60).listen(listenTo60Percent);
|
audioPlayer.percentCompletedStream(2).listen(listenTo2Percent);
|
||||||
|
|
||||||
// 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.positionStream.listen((position) async {
|
audioPlayer.positionStream.listen((position) async {
|
||||||
if (preferences.searchMode == SearchMode.youtubeMusic ||
|
if (preferences.searchMode == SearchMode.youtubeMusic ||
|
||||||
!preferences.skipNonMusic) return;
|
!preferences.skipNonMusic) return;
|
||||||
|
|
||||||
if (currentSegments == null ||
|
if (currentSegments == null ||
|
||||||
currentSegments!.$1 != state.activeTrack!.id! &&
|
currentSegments!.source != state.activeTrack!.id! &&
|
||||||
!isFetchingSegments) {
|
!isFetchingSegments) {
|
||||||
isFetchingSegments = true;
|
isFetchingSegments = true;
|
||||||
currentSegments = (
|
currentSegments = (
|
||||||
audioPlayer.currentSource!,
|
source: audioPlayer.currentSource!,
|
||||||
await getAndCacheSkipSegments(
|
segments: await getAndCacheSkipSegments(
|
||||||
(state.activeTrack as SpotubeTrack).ytTrack.id,
|
(state.activeTrack as SpotubeTrack).ytTrack.id,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
isFetchingSegments = false;
|
isFetchingSegments = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final (_, segments) = currentSegments!;
|
final (source: _, :segments) = currentSegments!;
|
||||||
if (segments.isEmpty) return;
|
if (segments.isEmpty) return;
|
||||||
|
|
||||||
for (final segment in segments) {
|
for (final segment in segments) {
|
||||||
|
@ -3,7 +3,6 @@ import 'dart:io';
|
|||||||
import 'package:dbus/dbus.dart';
|
import 'package:dbus/dbus.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.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/models/spotube_track.dart';
|
||||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist.dart';
|
import 'package:spotube/provider/proxy_playlist/proxy_playlist.dart';
|
||||||
import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.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:spotube/utils/type_conversion_utils.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
|
final dbus = DBusClient.session();
|
||||||
|
|
||||||
class _MprisMediaPlayer2 extends DBusObject {
|
class _MprisMediaPlayer2 extends DBusObject {
|
||||||
/// Creates a new object to expose on [path].
|
/// Creates a new object to expose on [path].
|
||||||
_MprisMediaPlayer2() : super(DBusObjectPath('/org/mpris/MediaPlayer2')) {
|
_MprisMediaPlayer2() : super(DBusObjectPath('/org/mpris/MediaPlayer2')) {
|
||||||
|
Loading…
Reference in New Issue
Block a user