fix: cache segments casting error

This commit is contained in:
Kingkor Roy Tirtho 2023-08-04 13:10:56 +06:00
parent 0b7affdc05
commit dfd60bd4cc
5 changed files with 47 additions and 45 deletions

View File

@ -87,9 +87,9 @@ Future<void> main(List<String> rawArgs) async {
MediaKit.ensureInitialized(); MediaKit.ensureInitialized();
// force High Refresh Rate on some Android devices (like One Plus) // force High Refresh Rate on some Android devices (like One Plus)
if (DesktopTools.platform.isAndroid) { if (DesktopTools.platform.isAndroid) {
await FlutterDisplayMode.setHighRefreshRate(); await FlutterDisplayMode.setHighRefreshRate();
} }
await DesktopTools.ensureInitialized( await DesktopTools.ensureInitialized(
DesktopWindowOptions( DesktopWindowOptions(
@ -122,7 +122,7 @@ if (DesktopTools.platform.isAndroid) {
MatchedTrack.boxName, MatchedTrack.boxName,
path: hiveCacheDir, path: hiveCacheDir,
); );
await Hive.openLazyBox<List<SkipSegment>>( await Hive.openLazyBox(
SkipSegment.boxName, SkipSegment.boxName,
path: hiveCacheDir, path: hiveCacheDir,
); );

View File

@ -12,8 +12,7 @@ class SkipSegment {
static String version = 'v1'; static String version = 'v1';
static final boxName = "oss.krtirtho.spotube.skip_segments.$version"; static final boxName = "oss.krtirtho.spotube.skip_segments.$version";
static LazyBox<List<SkipSegment>> get box => static LazyBox get box => Hive.lazyBox(boxName);
Hive.lazyBox<List<SkipSegment>>(boxName);
SkipSegment.fromJson(Map<String, dynamic> json) SkipSegment.fromJson(Map<String, dynamic> json)
: start = json['start'], : start = json['start'],

View File

@ -94,12 +94,13 @@ mixin NextFetcher on StateNotifier<ProxyPlaylist> {
} }
List<Track> mapSourcesToTracks(List<String> sources) { List<Track> mapSourcesToTracks(List<String> sources) {
final tracks = state.tracks;
return sources return sources
.map((source) { .map((source) {
final track = tracks.firstWhereOrNull( final track = state.tracks.firstWhereOrNull(
(track) => makeAppropriateSource(track) == source, (track) {
final newSource = makeAppropriateSource(track);
return newSource == source;
},
); );
return track; return track;
}) })

View File

@ -70,7 +70,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
notificationService = await AudioServices.create(ref, this); notificationService = await AudioServices.create(ref, this);
({String source, List<SkipSegment> segments})? currentSegments; ({String source, List<SkipSegment> segments})? currentSegments;
bool isFetchingSegments = false;
audioPlayer.activeSourceChangedStream.listen((newActiveSource) async { audioPlayer.activeSourceChangedStream.listen((newActiveSource) async {
final newActiveTrack = final newActiveTrack =
mapSourcesToTracks([newActiveSource]).firstOrNull; mapSourcesToTracks([newActiveSource]).firstOrNull;
@ -87,10 +87,6 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
.indexWhere((element) => element.id == newActiveTrack.id), .indexWhere((element) => element.id == newActiveTrack.id),
); );
isFetchingSegments = true;
isFetchingSegments = false;
updatePalette(); updatePalette();
}); });
@ -114,7 +110,8 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
listenTo2Percent(int percent) async { listenTo2Percent(int percent) async {
if (isPreSearching || if (isPreSearching ||
audioPlayer.currentSource == null || audioPlayer.currentSource == null ||
audioPlayer.nextSource == null) return; audioPlayer.nextSource == null ||
isPlayable(audioPlayer.nextSource!)) return;
try { try {
isPreSearching = true; isPreSearching = true;
@ -125,19 +122,6 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
if (track != null) { if (track != null) {
state = state.copyWith(tracks: mergeTracks([track], state.tracks)); 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) { if (oldTrack != null && track != null) {
@ -148,29 +132,34 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
} }
} finally { } finally {
isPreSearching = false; isPreSearching = false;
if (percent > 98 && !audioPlayer.isPlaying) {
await audioPlayer.resume();
}
} }
} }
audioPlayer.percentCompletedStream(2).listen(listenTo2Percent); audioPlayer.percentCompletedStream(2).listen(listenTo2Percent);
bool isFetchingSegments = false;
audioPlayer.positionStream.listen((position) async { audioPlayer.positionStream.listen((position) async {
if (preferences.searchMode == SearchMode.youtubeMusic || if ((preferences.youtubeApiType == YoutubeApiType.piped &&
preferences.searchMode == SearchMode.youtubeMusic) ||
!preferences.skipNonMusic) return; !preferences.skipNonMusic) return;
final notSameSegmentId =
currentSegments?.source != audioPlayer.currentSource;
if (currentSegments == null || if (currentSegments == null ||
currentSegments!.source != state.activeTrack!.id! && (notSameSegmentId && !isFetchingSegments)) {
!isFetchingSegments) {
isFetchingSegments = true; isFetchingSegments = true;
currentSegments = ( try {
source: audioPlayer.currentSource!, currentSegments = (
segments: await getAndCacheSkipSegments( source: audioPlayer.currentSource!,
(state.activeTrack as SpotubeTrack).ytTrack.id, segments: await getAndCacheSkipSegments(
), (state.activeTrack as SpotubeTrack).ytTrack.id,
); ),
isFetchingSegments = false; );
} finally {
isFetchingSegments = false;
}
} }
final (source: _, :segments) = currentSegments!; final (source: _, :segments) = currentSegments!;
@ -354,6 +343,10 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
} }
Future<void> addTracksAtFirst(Iterable<Track> tracks) async { Future<void> addTracksAtFirst(Iterable<Track> tracks) async {
if (state.tracks.length == 1) {
return addTracks(tracks);
}
tracks = blacklist.filter(tracks).toList() as List<Track>; tracks = blacklist.filter(tracks).toList() as List<Track>;
final destIndex = state.active != null ? state.active! + 1 : 0; final destIndex = state.active != null ? state.active! + 1 : 0;
final newTracks = state.tracks.toList()..insertAll(destIndex, tracks); final newTracks = state.tracks.toList()..insertAll(destIndex, tracks);
@ -492,12 +485,15 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
Future<List<SkipSegment>> getAndCacheSkipSegments(String id) async { Future<List<SkipSegment>> getAndCacheSkipSegments(String id) async {
if (!preferences.skipNonMusic || if (!preferences.skipNonMusic ||
preferences.searchMode != SearchMode.youtube) return []; (preferences.youtubeApiType == YoutubeApiType.piped &&
preferences.searchMode == SearchMode.youtubeMusic)) return [];
try { try {
final cached = await SkipSegment.box.get(id); final cached = await SkipSegment.box.get(id);
if (cached != null && cached.isNotEmpty) { if (cached != null && cached.isNotEmpty) {
return List.castFrom<dynamic, SkipSegment>(cached); return List.castFrom<dynamic, SkipSegment>(
(cached as List).map((json) => SkipSegment.fromJson(json)).toList(),
);
} }
final res = await get(Uri( final res = await get(Uri(
@ -519,6 +515,11 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
)); ));
if (res.body == "Not Found") { if (res.body == "Not Found") {
Catcher.reportCheckedError(
"[SponsorBlock] no skip segments found for $id\n"
"${res.request?.url}",
StackTrace.current,
);
return List.castFrom<dynamic, SkipSegment>([]); return List.castFrom<dynamic, SkipSegment>([]);
} }
@ -537,7 +538,7 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
await SkipSegment.box.put( await SkipSegment.box.put(
id, id,
segments, segments.map((e) => e.toJson()).toList(),
); );
return List.castFrom<dynamic, SkipSegment>(segments); return List.castFrom<dynamic, SkipSegment>(segments);
} catch (e, stack) { } catch (e, stack) {

View File

@ -270,7 +270,8 @@ class MkPlayerWithState extends Player {
FutureOr<void> insert(int index, Media media) { FutureOr<void> insert(int index, Media media) {
if (_playlist == null || if (_playlist == null ||
index < 0 || index < 0 ||
index > _playlist!.medias.length - 1) { (_playlist!.medias.length > 1 &&
index > _playlist!.medias.length - 1)) {
return null; return null;
} }