Skip to content

Commit

Permalink
fix: tracks doesn't change when ended
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Aug 8, 2023
1 parent e3f4344 commit aa4ac86
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 72 deletions.
115 changes: 66 additions & 49 deletions lib/provider/proxy_playlist/proxy_playlist_provider.dart
@@ -1,7 +1,6 @@
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';
Expand Down Expand Up @@ -72,37 +71,45 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
({String source, List<SkipSegment> segments})? currentSegments;

audioPlayer.activeSourceChangedStream.listen((newActiveSource) async {
final newActiveTrack =
mapSourcesToTracks([newActiveSource]).firstOrNull;
try {
final newActiveTrack =
mapSourcesToTracks([newActiveSource]).firstOrNull;

if (newActiveTrack == null ||
newActiveTrack.id == state.activeTrack?.id) {
return;
}
if (newActiveTrack == null ||
newActiveTrack.id == state.activeTrack?.id) {
return;
}

notificationService.addTrack(newActiveTrack);
state = state.copyWith(
active: state.tracks
.toList()
.indexWhere((element) => element.id == newActiveTrack.id),
);
notificationService.addTrack(newActiveTrack);
state = state.copyWith(
active: state.tracks
.toList()
.indexWhere((element) => element.id == newActiveTrack.id),
);

updatePalette();
updatePalette();
} catch (e, stackTrace) {
Catcher.reportCheckedError(e, stackTrace);
}
});

audioPlayer.shuffledStream.listen((event) {
final newlyOrderedTracks = mapSourcesToTracks(audioPlayer.sources);
try {
final newlyOrderedTracks = mapSourcesToTracks(audioPlayer.sources);

final newActiveIndex = newlyOrderedTracks.indexWhere(
(element) => element.id == state.activeTrack?.id,
);
final newActiveIndex = newlyOrderedTracks.indexWhere(
(element) => element.id == state.activeTrack?.id,
);

if (newActiveIndex == -1) return;
if (newActiveIndex == -1) return;

state = state.copyWith(
tracks: newlyOrderedTracks.toSet(),
active: newActiveIndex,
);
state = state.copyWith(
tracks: newlyOrderedTracks.toSet(),
active: newActiveIndex,
);
} catch (e, stackTrace) {
Catcher.reportCheckedError(e, stackTrace);
}
});

bool isPreSearching = false;
Expand Down Expand Up @@ -130,6 +137,8 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
track,
);
}
} catch (e, stackTrace) {
Catcher.reportCheckedError(e, stackTrace);
} finally {
isPreSearching = false;
}
Expand All @@ -140,37 +149,45 @@ class ProxyPlaylistNotifier extends PersistedStateNotifier<ProxyPlaylist>
bool isFetchingSegments = false;

audioPlayer.positionStream.listen((position) async {
// skipping in very first second breaks stream
if ((preferences.youtubeApiType == YoutubeApiType.piped &&
preferences.searchMode == SearchMode.youtubeMusic) ||
!preferences.skipNonMusic) return;

final notSameSegmentId =
currentSegments?.source != audioPlayer.currentSource;

if (currentSegments == null ||
(notSameSegmentId && !isFetchingSegments)) {
isFetchingSegments = true;
try {
currentSegments = (
source: audioPlayer.currentSource!,
segments: await getAndCacheSkipSegments(
(state.activeTrack as SpotubeTrack).ytTrack.id,
),
);
} finally {
try {
if (state.activeTrack == null || state.activeTrack is LocalTrack) {
isFetchingSegments = false;
return;
}
// skipping in very first second breaks stream
if ((preferences.youtubeApiType == YoutubeApiType.piped &&
preferences.searchMode == SearchMode.youtubeMusic) ||
!preferences.skipNonMusic) return;

final notSameSegmentId =
currentSegments?.source != audioPlayer.currentSource;

if (currentSegments == null ||
(notSameSegmentId && !isFetchingSegments)) {
isFetchingSegments = true;
try {
currentSegments = (
source: audioPlayer.currentSource!,
segments: await getAndCacheSkipSegments(
(state.activeTrack as SpotubeTrack).ytTrack.id,
),
);
} finally {
isFetchingSegments = false;
}
}
}

final (source: _, :segments) = currentSegments!;
if (segments.isEmpty || position < const Duration(seconds: 3)) return;
final (source: _, :segments) = currentSegments!;
if (segments.isEmpty || position < const Duration(seconds: 3)) return;

for (final segment in segments) {
if ((position.inSeconds >= segment.start &&
position.inSeconds < segment.end)) {
await audioPlayer.seek(Duration(seconds: segment.end));
for (final segment in segments) {
if ((position.inSeconds >= segment.start &&
position.inSeconds < segment.end)) {
await audioPlayer.seek(Duration(seconds: segment.end));
}
}
} catch (e, stackTrace) {
Catcher.reportCheckedError(e, stackTrace);
}
});
}();
Expand Down
2 changes: 1 addition & 1 deletion lib/services/audio_player/audio_player.dart
Expand Up @@ -20,7 +20,7 @@ abstract class AudioPlayerInterface {
// _mkPlayer = _mkSupportedPlatform ? MkPlayerWithState() : null,
// _justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null
{
_mkPlayer.streams.error.listen((event) {
_mkPlayer.stream.error.listen((event) {
Catcher.reportCheckedError(event, StackTrace.current);
});
}
Expand Down
12 changes: 6 additions & 6 deletions lib/services/audio_player/audio_players_streams_mixin.dart
Expand Up @@ -4,7 +4,7 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {
// stream getters
Stream<Duration> get durationStream {
// if (mkSupportedPlatform) {
return _mkPlayer.streams.duration;
return _mkPlayer.stream.duration;
// } else {
// return _justAudio!.durationStream
// .where((event) => event != null)
Expand All @@ -15,7 +15,7 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {

Stream<Duration> get positionStream {
// if (mkSupportedPlatform) {
return _mkPlayer.streams.position;
return _mkPlayer.stream.position;
// } else {
// return _justAudio!.positionStream;
// }
Expand All @@ -24,15 +24,15 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {
Stream<Duration> get bufferedPositionStream {
// if (mkSupportedPlatform) {
// audioplayers doesn't have the capability to get buffered position
return _mkPlayer.streams.buffer;
return _mkPlayer.stream.buffer;
// } else {
// return _justAudio!.bufferedPositionStream;
// }
}

Stream<void> get completedStream {
// if (mkSupportedPlatform) {
return _mkPlayer.streams.completed;
return _mkPlayer.stream.completed;
// } else {
// return _justAudio!.playerStateStream
// .where(
Expand All @@ -57,7 +57,7 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {

Stream<bool> get playingStream {
// if (mkSupportedPlatform) {
return _mkPlayer.streams.playing;
return _mkPlayer.stream.playing;
// } else {
// return _justAudio!.playingStream;
// }
Expand All @@ -83,7 +83,7 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {

Stream<double> get volumeStream {
// if (mkSupportedPlatform) {
return _mkPlayer.streams.volume.map((event) => event / 100);
return _mkPlayer.stream.volume.map((event) => event / 100);
// } else {
// return _justAudio!.volumeStream;
// }
Expand Down
37 changes: 21 additions & 16 deletions lib/services/audio_player/mk_state_player.dart
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:catcher/catcher.dart';
import 'package:collection/collection.dart';
import 'package:media_kit/media_kit.dart';
// ignore: implementation_imports
Expand Down Expand Up @@ -30,36 +31,40 @@ class MkPlayerWithState extends Player {
_shuffled = false,
_loopMode = PlaylistMode.none {
_subscriptions = [
streams.buffering.listen((event) {
stream.buffering.listen((event) {
_playerStateStream.add(AudioPlaybackState.buffering);
}),
streams.playing.listen((playing) {
stream.playing.listen((playing) {
if (playing) {
_playerStateStream.add(AudioPlaybackState.playing);
} else {
_playerStateStream.add(AudioPlaybackState.paused);
}
}),
streams.position.listen((position) async {
final isComplete = state.duration != Duration.zero &&
position != Duration.zero &&
state.duration.inSeconds == position.inSeconds;

if (!isComplete || _playlist == null) return;
_playerStateStream.add(AudioPlaybackState.completed);

if (loopMode == PlaylistMode.single) {
await super.open(_playlist!.medias[_playlist!.index], play: true);
} else {
await next();
await Future.delayed(const Duration(milliseconds: 250), play);
stream.completed.listen((isCompleted) async {
try {
if (!isCompleted) return;

_playerStateStream.add(AudioPlaybackState.completed);

if (loopMode == PlaylistMode.single) {
await super.open(_playlist!.medias[_playlist!.index], play: true);
} else {
await next();
await Future.delayed(const Duration(milliseconds: 250), play);
}
} catch (e, stackTrace) {
Catcher.reportCheckedError(e, stackTrace);
}
}),
streams.playlist.listen((event) {
stream.playlist.listen((event) {
if (event.medias.isEmpty) {
_playerStateStream.add(AudioPlaybackState.stopped);
}
}),
stream.error.listen((event) {
Catcher.reportCheckedError('[MediaKitError] \n$event', null);
}),
];
}

Expand Down

0 comments on commit aa4ac86

Please sign in to comment.