diff --git a/lib/main.dart b/lib/main.dart index e90642ec3..e1161287e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -87,9 +87,9 @@ Future main(List rawArgs) async { MediaKit.ensureInitialized(); // force High Refresh Rate on some Android devices (like One Plus) -if (DesktopTools.platform.isAndroid) { + if (DesktopTools.platform.isAndroid) { await FlutterDisplayMode.setHighRefreshRate(); -} + } await DesktopTools.ensureInitialized( DesktopWindowOptions( @@ -122,7 +122,7 @@ if (DesktopTools.platform.isAndroid) { MatchedTrack.boxName, path: hiveCacheDir, ); - await Hive.openLazyBox>( + await Hive.openLazyBox( SkipSegment.boxName, path: hiveCacheDir, ); diff --git a/lib/models/skip_segment.dart b/lib/models/skip_segment.dart index ef4cb8896..90f20f5a9 100644 --- a/lib/models/skip_segment.dart +++ b/lib/models/skip_segment.dart @@ -12,8 +12,7 @@ class SkipSegment { static String version = 'v1'; static final boxName = "oss.krtirtho.spotube.skip_segments.$version"; - static LazyBox> get box => - Hive.lazyBox>(boxName); + static LazyBox get box => Hive.lazyBox(boxName); SkipSegment.fromJson(Map json) : start = json['start'], diff --git a/lib/provider/proxy_playlist/next_fetcher_mixin.dart b/lib/provider/proxy_playlist/next_fetcher_mixin.dart index ac8f5bbc4..0236ec589 100644 --- a/lib/provider/proxy_playlist/next_fetcher_mixin.dart +++ b/lib/provider/proxy_playlist/next_fetcher_mixin.dart @@ -94,12 +94,13 @@ mixin NextFetcher on StateNotifier { } List mapSourcesToTracks(List sources) { - final tracks = state.tracks; - return sources .map((source) { - final track = tracks.firstWhereOrNull( - (track) => makeAppropriateSource(track) == source, + final track = state.tracks.firstWhereOrNull( + (track) { + final newSource = makeAppropriateSource(track); + return newSource == source; + }, ); return track; }) diff --git a/lib/provider/proxy_playlist/proxy_playlist_provider.dart b/lib/provider/proxy_playlist/proxy_playlist_provider.dart index c7dcfbc26..32343b79e 100644 --- a/lib/provider/proxy_playlist/proxy_playlist_provider.dart +++ b/lib/provider/proxy_playlist/proxy_playlist_provider.dart @@ -70,7 +70,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier notificationService = await AudioServices.create(ref, this); ({String source, List segments})? currentSegments; - bool isFetchingSegments = false; + audioPlayer.activeSourceChangedStream.listen((newActiveSource) async { final newActiveTrack = mapSourcesToTracks([newActiveSource]).firstOrNull; @@ -87,10 +87,6 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier .indexWhere((element) => element.id == newActiveTrack.id), ); - isFetchingSegments = true; - - isFetchingSegments = false; - updatePalette(); }); @@ -114,7 +110,8 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier listenTo2Percent(int percent) async { if (isPreSearching || audioPlayer.currentSource == null || - audioPlayer.nextSource == null) return; + audioPlayer.nextSource == null || + isPlayable(audioPlayer.nextSource!)) return; try { isPreSearching = true; @@ -125,19 +122,6 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier if (track != null) { state = state.copyWith(tracks: mergeTracks([track], state.tracks)); - if (currentSegments == null || - (oldTrack?.id != null && - currentSegments!.source != oldTrack!.id!) && - !isFetchingSegments) { - isFetchingSegments = true; - currentSegments = ( - source: audioPlayer.currentSource!, - segments: await getAndCacheSkipSegments( - track.ytTrack.id, - ), - ); - isFetchingSegments = false; - } } if (oldTrack != null && track != null) { @@ -148,29 +132,34 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier } } finally { isPreSearching = false; - if (percent > 98 && !audioPlayer.isPlaying) { - await audioPlayer.resume(); - } } } audioPlayer.percentCompletedStream(2).listen(listenTo2Percent); + bool isFetchingSegments = false; + audioPlayer.positionStream.listen((position) async { - if (preferences.searchMode == SearchMode.youtubeMusic || + if ((preferences.youtubeApiType == YoutubeApiType.piped && + preferences.searchMode == SearchMode.youtubeMusic) || !preferences.skipNonMusic) return; + final notSameSegmentId = + currentSegments?.source != audioPlayer.currentSource; + if (currentSegments == null || - currentSegments!.source != state.activeTrack!.id! && - !isFetchingSegments) { + (notSameSegmentId && !isFetchingSegments)) { isFetchingSegments = true; - currentSegments = ( - source: audioPlayer.currentSource!, - segments: await getAndCacheSkipSegments( - (state.activeTrack as SpotubeTrack).ytTrack.id, - ), - ); - isFetchingSegments = false; + try { + currentSegments = ( + source: audioPlayer.currentSource!, + segments: await getAndCacheSkipSegments( + (state.activeTrack as SpotubeTrack).ytTrack.id, + ), + ); + } finally { + isFetchingSegments = false; + } } final (source: _, :segments) = currentSegments!; @@ -354,6 +343,10 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier } Future addTracksAtFirst(Iterable tracks) async { + if (state.tracks.length == 1) { + return addTracks(tracks); + } + tracks = blacklist.filter(tracks).toList() as List; final destIndex = state.active != null ? state.active! + 1 : 0; final newTracks = state.tracks.toList()..insertAll(destIndex, tracks); @@ -492,12 +485,15 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier Future> getAndCacheSkipSegments(String id) async { if (!preferences.skipNonMusic || - preferences.searchMode != SearchMode.youtube) return []; + (preferences.youtubeApiType == YoutubeApiType.piped && + preferences.searchMode == SearchMode.youtubeMusic)) return []; try { final cached = await SkipSegment.box.get(id); if (cached != null && cached.isNotEmpty) { - return List.castFrom(cached); + return List.castFrom( + (cached as List).map((json) => SkipSegment.fromJson(json)).toList(), + ); } final res = await get(Uri( @@ -519,6 +515,11 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier )); if (res.body == "Not Found") { + Catcher.reportCheckedError( + "[SponsorBlock] no skip segments found for $id\n" + "${res.request?.url}", + StackTrace.current, + ); return List.castFrom([]); } @@ -537,7 +538,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier await SkipSegment.box.put( id, - segments, + segments.map((e) => e.toJson()).toList(), ); return List.castFrom(segments); } catch (e, stack) { diff --git a/lib/services/audio_player/mk_state_player.dart b/lib/services/audio_player/mk_state_player.dart index 5eb16e01d..81e5e67e0 100644 --- a/lib/services/audio_player/mk_state_player.dart +++ b/lib/services/audio_player/mk_state_player.dart @@ -270,7 +270,8 @@ class MkPlayerWithState extends Player { FutureOr insert(int index, Media media) { if (_playlist == null || index < 0 || - index > _playlist!.medias.length - 1) { + (_playlist!.medias.length > 1 && + index > _playlist!.medias.length - 1)) { return null; }