mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
feat: show loading when track metadata is being fetched, android, ios, macos enable shuffling
This commit is contained in:
parent
a0744630ba
commit
bf59570251
@ -82,9 +82,7 @@ Future<void> main(List<String> rawArgs) async {
|
||||
|
||||
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
||||
|
||||
if (DesktopTools.platform.isWindows || DesktopTools.platform.isLinux) {
|
||||
MediaKit.ensureInitialized();
|
||||
}
|
||||
MediaKit.ensureInitialized();
|
||||
|
||||
await DesktopTools.ensureInitialized(
|
||||
DesktopWindowOptions(
|
||||
|
@ -31,10 +31,10 @@ class PlayerView extends HookConsumerWidget {
|
||||
final theme = Theme.of(context);
|
||||
final auth = ref.watch(AuthenticationNotifier.provider);
|
||||
final currentTrack = ref.watch(ProxyPlaylistNotifier.provider.select(
|
||||
(value) => value?.activeTrack,
|
||||
(value) => value.activeTrack,
|
||||
));
|
||||
final isLocalTrack = ref.watch(ProxyPlaylistNotifier.provider.select(
|
||||
(value) => value?.activeTrack is LocalTrack,
|
||||
(value) => value.activeTrack is LocalTrack,
|
||||
));
|
||||
final breakpoint = useBreakpoints();
|
||||
|
||||
|
@ -20,12 +20,12 @@ import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
/// * [x] Prefetch next track as [SpotubeTrack] on 80% of current track
|
||||
/// * [ ] Mixed Queue containing both [SpotubeTrack] and [LocalTrack]
|
||||
/// * [ ] Modification of the Queue
|
||||
/// * [ ] Add track at the end
|
||||
/// * [x] Add track at the end
|
||||
/// * [ ] Add track at the beginning
|
||||
/// * [ ] Remove track
|
||||
/// * [x] Remove track
|
||||
/// * [ ] Reorder track
|
||||
/// * [ ] Caching and loading of cache of tracks
|
||||
/// * [ ] Shuffling
|
||||
/// * [x] Shuffling
|
||||
/// * [x] loop => playlist, track, none
|
||||
/// * [ ] Alternative Track Source
|
||||
/// * [x] Blacklisting of tracks and artist
|
||||
@ -65,30 +65,19 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
return;
|
||||
}
|
||||
|
||||
print('=============== Active Track Changed ===============');
|
||||
|
||||
print('Current tracks: ${state.tracks.map((e) => e.name).toList()}');
|
||||
print('newIndexedTrack: ${newActiveTrack.name}');
|
||||
|
||||
notificationService.addTrack(newActiveTrack);
|
||||
state = state.copyWith(
|
||||
active: state.tracks
|
||||
.toList()
|
||||
.indexWhere((element) => element.id == newActiveTrack.id),
|
||||
);
|
||||
print('New active: ${state.active}');
|
||||
|
||||
print('=============== ----- ===============');
|
||||
if (preferences.albumColorSync) {
|
||||
updatePalette();
|
||||
}
|
||||
});
|
||||
|
||||
audioPlayer.shuffledStream.listen((event) {
|
||||
print('=============== Shuffled ===============');
|
||||
|
||||
print('oldTracks: ${state.tracks.map((e) => e.name).toList()}');
|
||||
|
||||
final newlyOrderedTracks = mapSourcesToTracks(audioPlayer.sources);
|
||||
|
||||
print(
|
||||
@ -98,10 +87,6 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
(element) => element.id == state.activeTrack?.id,
|
||||
);
|
||||
|
||||
print('newActiveIndex $newActiveIndex');
|
||||
|
||||
print('=============== ----- ===============');
|
||||
|
||||
if (newActiveIndex == -1) return;
|
||||
|
||||
state = state.copyWith(
|
||||
@ -157,14 +142,10 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
}
|
||||
|
||||
Future<SpotubeTrack?> ensureSourcePlayable(String source) async {
|
||||
print("======== Ensure Source Playable =========");
|
||||
print("source: $source");
|
||||
|
||||
if (isPlayable(source)) return null;
|
||||
|
||||
final track = mapSourcesToTracks([source]).firstOrNull;
|
||||
|
||||
print("nthTrack: ${track?.name}");
|
||||
if (track == null || track is LocalTrack) {
|
||||
return null;
|
||||
}
|
||||
@ -174,8 +155,6 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
_ => await SpotubeTrack.fetchFromTrack(track, preferences),
|
||||
};
|
||||
|
||||
print("======== ----- =========");
|
||||
|
||||
await audioPlayer.replaceSource(
|
||||
source,
|
||||
nthFetchedTrack.ytUri,
|
||||
@ -256,9 +235,14 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
Future<void> jumpTo(int index) async {
|
||||
final oldTrack =
|
||||
mapSourcesToTracks([audioPlayer.currentSource!]).firstOrNull;
|
||||
state = state.copyWith(active: index);
|
||||
await audioPlayer.pause();
|
||||
final track = await ensureSourcePlayable(audioPlayer.sources[index]);
|
||||
if (track != null) {
|
||||
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
|
||||
state = state.copyWith(
|
||||
tracks: mergeTracks([track], state.tracks),
|
||||
active: index,
|
||||
);
|
||||
}
|
||||
await audioPlayer.jumpTo(index);
|
||||
|
||||
@ -300,9 +284,20 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
Future<void> next() async {
|
||||
if (audioPlayer.nextSource == null) return;
|
||||
final oldTrack = mapSourcesToTracks([audioPlayer.nextSource!]).firstOrNull;
|
||||
state = state.copyWith(
|
||||
active: state.tracks
|
||||
.toList()
|
||||
.indexWhere((element) => element.id == oldTrack?.id),
|
||||
);
|
||||
await audioPlayer.pause();
|
||||
final track = await ensureSourcePlayable(audioPlayer.nextSource!);
|
||||
if (track != null) {
|
||||
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
|
||||
state = state.copyWith(
|
||||
tracks: mergeTracks([track], state.tracks),
|
||||
active: state.tracks
|
||||
.toList()
|
||||
.indexWhere((element) => element.id == track.id),
|
||||
);
|
||||
}
|
||||
await audioPlayer.skipToNext();
|
||||
|
||||
@ -318,9 +313,20 @@ class ProxyPlaylistNotifier extends StateNotifier<ProxyPlaylist>
|
||||
if (audioPlayer.previousSource == null) return;
|
||||
final oldTrack =
|
||||
mapSourcesToTracks([audioPlayer.previousSource!]).firstOrNull;
|
||||
state = state.copyWith(
|
||||
active: state.tracks
|
||||
.toList()
|
||||
.indexWhere((element) => element.id == oldTrack?.id),
|
||||
);
|
||||
await audioPlayer.pause();
|
||||
final track = await ensureSourcePlayable(audioPlayer.previousSource!);
|
||||
if (track != null) {
|
||||
state = state.copyWith(tracks: mergeTracks([track], state.tracks));
|
||||
state = state.copyWith(
|
||||
tracks: mergeTracks([track], state.tracks),
|
||||
active: state.tracks
|
||||
.toList()
|
||||
.indexWhere((element) => element.id == track.id),
|
||||
);
|
||||
}
|
||||
await audioPlayer.skipToPrevious();
|
||||
if (oldTrack != null && track != null) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter_desktop_tools/flutter_desktop_tools.dart';
|
||||
import 'package:spotube/services/audio_player/mk_state_player.dart';
|
||||
import 'package:just_audio/just_audio.dart' as ja;
|
||||
// import 'package:just_audio/just_audio.dart' as ja;
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:media_kit/media_kit.dart' as mk;
|
||||
@ -14,37 +13,38 @@ part 'audio_players_streams_mixin.dart';
|
||||
part 'audio_player_impl.dart';
|
||||
|
||||
abstract class AudioPlayerInterface {
|
||||
final MkPlayerWithState? _mkPlayer;
|
||||
final ja.AudioPlayer? _justAudio;
|
||||
final MkPlayerWithState _mkPlayer;
|
||||
// final ja.AudioPlayer? _justAudio;
|
||||
|
||||
AudioPlayerInterface()
|
||||
: _mkPlayer = _mkSupportedPlatform ? MkPlayerWithState() : null,
|
||||
_justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null {
|
||||
_mkPlayer?.streams.error.listen((event) {
|
||||
AudioPlayerInterface() : _mkPlayer = MkPlayerWithState()
|
||||
// _mkPlayer = _mkSupportedPlatform ? MkPlayerWithState() : null,
|
||||
// _justAudio = !_mkSupportedPlatform ? ja.AudioPlayer() : null
|
||||
{
|
||||
_mkPlayer.streams.error.listen((event) {
|
||||
Catcher.reportCheckedError(event, StackTrace.current);
|
||||
});
|
||||
}
|
||||
|
||||
/// Whether the current platform supports the audioplayers plugin
|
||||
static final bool _mkSupportedPlatform =
|
||||
DesktopTools.platform.isWindows || DesktopTools.platform.isLinux;
|
||||
static const bool _mkSupportedPlatform = true;
|
||||
// DesktopTools.platform.isWindows || DesktopTools.platform.isLinux;
|
||||
|
||||
bool get mkSupportedPlatform => _mkSupportedPlatform;
|
||||
|
||||
Future<Duration?> get duration async {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.state.duration;
|
||||
} else {
|
||||
return _justAudio!.duration;
|
||||
}
|
||||
return _mkPlayer.state.duration;
|
||||
// if (mkSupportedPlatform) {
|
||||
// } else {
|
||||
// return _justAudio!.duration;
|
||||
// }
|
||||
}
|
||||
|
||||
Future<Duration?> get position async {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.state.position;
|
||||
} else {
|
||||
return _justAudio!.position;
|
||||
}
|
||||
return _mkPlayer.state.position;
|
||||
// if (mkSupportedPlatform) {
|
||||
// } else {
|
||||
// return _justAudio!.position;
|
||||
// }
|
||||
}
|
||||
|
||||
Future<Duration?> get bufferedPosition async {
|
||||
@ -57,78 +57,87 @@ abstract class AudioPlayerInterface {
|
||||
}
|
||||
|
||||
bool get hasSource {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playlist.medias.isNotEmpty;
|
||||
} else {
|
||||
return _justAudio!.audioSource != null;
|
||||
}
|
||||
return _mkPlayer.playlist.medias.isNotEmpty;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return _mkPlayer.playlist.medias.isNotEmpty;
|
||||
// } else {
|
||||
// return _justAudio!.audioSource != null;
|
||||
// }
|
||||
}
|
||||
|
||||
// states
|
||||
bool get isPlaying {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.state.playing;
|
||||
} else {
|
||||
return _justAudio!.playing;
|
||||
}
|
||||
return _mkPlayer.state.playing;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return _mkPlayer.state.playing;
|
||||
// } else {
|
||||
// return _justAudio!.playing;
|
||||
// }
|
||||
}
|
||||
|
||||
bool get isPaused {
|
||||
if (mkSupportedPlatform) {
|
||||
return !_mkPlayer!.state.playing;
|
||||
} else {
|
||||
return !isPlaying;
|
||||
}
|
||||
return !_mkPlayer.state.playing;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return !_mkPlayer.state.playing;
|
||||
// } else {
|
||||
// return !isPlaying;
|
||||
// }
|
||||
}
|
||||
|
||||
bool get isStopped {
|
||||
if (mkSupportedPlatform) {
|
||||
return !hasSource;
|
||||
} else {
|
||||
return _justAudio!.processingState == ja.ProcessingState.idle;
|
||||
}
|
||||
return !hasSource;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return !hasSource;
|
||||
// } else {
|
||||
// return _justAudio!.processingState == ja.ProcessingState.idle;
|
||||
// }
|
||||
}
|
||||
|
||||
Future<bool> get isCompleted async {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.state.completed;
|
||||
} else {
|
||||
return _justAudio!.processingState == ja.ProcessingState.completed;
|
||||
}
|
||||
return _mkPlayer.state.completed;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return _mkPlayer.state.completed;
|
||||
// } else {
|
||||
// return _justAudio!.processingState == ja.ProcessingState.completed;
|
||||
// }
|
||||
}
|
||||
|
||||
Future<bool> get isShuffled async {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.shuffled;
|
||||
} else {
|
||||
return _justAudio!.shuffleModeEnabled;
|
||||
}
|
||||
return _mkPlayer.shuffled;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return _mkPlayer.shuffled;
|
||||
// } else {
|
||||
// return _justAudio!.shuffleModeEnabled;
|
||||
// }
|
||||
}
|
||||
|
||||
Future<PlaybackLoopMode> get loopMode async {
|
||||
if (mkSupportedPlatform) {
|
||||
return PlaybackLoopMode.fromPlaylistMode(_mkPlayer!.loopMode);
|
||||
} else {
|
||||
return PlaybackLoopMode.fromLoopMode(_justAudio!.loopMode);
|
||||
}
|
||||
return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);
|
||||
// if (mkSupportedPlatform) {
|
||||
// return PlaybackLoopMode.fromPlaylistMode(_mkPlayer.loopMode);
|
||||
// } else {
|
||||
// return PlaybackLoopMode.fromLoopMode(_justAudio!.loopMode);
|
||||
// }
|
||||
}
|
||||
|
||||
/// Returns the current volume of the player, between 0 and 1
|
||||
double get volume {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.state.volume / 100;
|
||||
} else {
|
||||
return _justAudio!.volume;
|
||||
}
|
||||
return _mkPlayer.state.volume / 100;
|
||||
// if (mkSupportedPlatform) {
|
||||
// return _mkPlayer.state.volume / 100;
|
||||
// } else {
|
||||
// return _justAudio!.volume;
|
||||
// }
|
||||
}
|
||||
|
||||
bool get isBuffering {
|
||||
if (mkSupportedPlatform) {
|
||||
// audioplayers doesn't have the capability to get buffering state
|
||||
return false;
|
||||
} else {
|
||||
return _justAudio!.processingState == ja.ProcessingState.buffering ||
|
||||
_justAudio!.processingState == ja.ProcessingState.loading;
|
||||
}
|
||||
return false;
|
||||
// if (mkSupportedPlatform) {
|
||||
// // audioplayers doesn't have the capability to get buffering state
|
||||
// return false;
|
||||
// } else {
|
||||
// return _justAudio!.processingState == ja.ProcessingState.buffering ||
|
||||
// _justAudio!.processingState == ja.ProcessingState.loading;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,15 @@ final audioPlayer = SpotubeAudioPlayer();
|
||||
class SpotubeAudioPlayer extends AudioPlayerInterface
|
||||
with SpotubeAudioPlayersStreams {
|
||||
Object _resolveUrlType(String url) {
|
||||
if (mkSupportedPlatform) {
|
||||
return mk.Media(url);
|
||||
} else {
|
||||
if (url.startsWith("https")) {
|
||||
return ja.AudioSource.uri(Uri.parse(url));
|
||||
} else {
|
||||
return ja.AudioSource.file(url);
|
||||
}
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return mk.Media(url);
|
||||
// } else {
|
||||
// if (url.startsWith("https")) {
|
||||
// return ja.AudioSource.uri(Uri.parse(url));
|
||||
// } else {
|
||||
// return ja.AudioSource.file(url);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> preload(String url) async {
|
||||
@ -29,63 +29,63 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
|
||||
|
||||
Future<void> play(String url) async {
|
||||
final urlType = _resolveUrlType(url);
|
||||
if (mkSupportedPlatform && urlType is mk.Media) {
|
||||
await _mkPlayer?.open(urlType, play: true);
|
||||
} else {
|
||||
if (_justAudio?.audioSource is ja.ProgressiveAudioSource &&
|
||||
(_justAudio?.audioSource as ja.ProgressiveAudioSource)
|
||||
.uri
|
||||
.toString() ==
|
||||
url) {
|
||||
await _justAudio?.play();
|
||||
} else {
|
||||
await _justAudio?.stop();
|
||||
await _justAudio?.setAudioSource(
|
||||
urlType as ja.AudioSource,
|
||||
preload: true,
|
||||
);
|
||||
await _justAudio?.play();
|
||||
}
|
||||
}
|
||||
// if (mkSupportedPlatform && urlType is mk.Media) {
|
||||
await _mkPlayer.open(urlType as mk.Media, play: true);
|
||||
// } else {
|
||||
// if (_justAudio?.audioSource is ja.ProgressiveAudioSource &&
|
||||
// (_justAudio?.audioSource as ja.ProgressiveAudioSource)
|
||||
// .uri
|
||||
// .toString() ==
|
||||
// url) {
|
||||
// await _justAudio?.play();
|
||||
// } else {
|
||||
// await _justAudio?.stop();
|
||||
// await _justAudio?.setAudioSource(
|
||||
// urlType as ja.AudioSource,
|
||||
// preload: true,
|
||||
// );
|
||||
// await _justAudio?.play();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> pause() async {
|
||||
await _mkPlayer?.pause();
|
||||
await _justAudio?.pause();
|
||||
await _mkPlayer.pause();
|
||||
// await _justAudio?.pause();
|
||||
}
|
||||
|
||||
Future<void> resume() async {
|
||||
await _mkPlayer?.play();
|
||||
await _justAudio?.play();
|
||||
await _mkPlayer.play();
|
||||
// await _justAudio?.play();
|
||||
}
|
||||
|
||||
Future<void> stop() async {
|
||||
await _mkPlayer?.stop();
|
||||
await _justAudio?.stop();
|
||||
await _justAudio?.setShuffleModeEnabled(false);
|
||||
await _justAudio?.setLoopMode(ja.LoopMode.off);
|
||||
await _mkPlayer.stop();
|
||||
// await _justAudio?.stop();
|
||||
// await _justAudio?.setShuffleModeEnabled(false);
|
||||
// await _justAudio?.setLoopMode(ja.LoopMode.off);
|
||||
}
|
||||
|
||||
Future<void> seek(Duration position) async {
|
||||
await _mkPlayer?.seek(position);
|
||||
await _justAudio?.seek(position);
|
||||
await _mkPlayer.seek(position);
|
||||
// await _justAudio?.seek(position);
|
||||
}
|
||||
|
||||
/// Volume is between 0 and 1
|
||||
Future<void> setVolume(double volume) async {
|
||||
assert(volume >= 0 && volume <= 1);
|
||||
await _mkPlayer?.setVolume(volume * 100);
|
||||
await _justAudio?.setVolume(volume);
|
||||
await _mkPlayer.setVolume(volume * 100);
|
||||
// await _justAudio?.setVolume(volume);
|
||||
}
|
||||
|
||||
Future<void> setSpeed(double speed) async {
|
||||
await _mkPlayer?.setRate(speed);
|
||||
await _justAudio?.setSpeed(speed);
|
||||
await _mkPlayer.setRate(speed);
|
||||
// await _justAudio?.setSpeed(speed);
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _mkPlayer?.dispose();
|
||||
await _justAudio?.dispose();
|
||||
await _mkPlayer.dispose();
|
||||
// await _justAudio?.dispose();
|
||||
}
|
||||
|
||||
// Playlist related
|
||||
@ -97,28 +97,28 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
|
||||
}) async {
|
||||
assert(tracks.isNotEmpty);
|
||||
assert(initialIndex <= tracks.length - 1);
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.open(
|
||||
mk.Playlist(
|
||||
tracks.map(mk.Media.new).toList(),
|
||||
index: initialIndex,
|
||||
),
|
||||
play: autoPlay,
|
||||
);
|
||||
} else {
|
||||
await _justAudio!.setAudioSource(
|
||||
ja.ConcatenatingAudioSource(
|
||||
useLazyPreparation: true,
|
||||
children:
|
||||
tracks.map((e) => ja.AudioSource.uri(Uri.parse(e))).toList(),
|
||||
),
|
||||
preload: true,
|
||||
initialIndex: initialIndex,
|
||||
);
|
||||
if (autoPlay) {
|
||||
await _justAudio!.play();
|
||||
}
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.open(
|
||||
mk.Playlist(
|
||||
tracks.map(mk.Media.new).toList(),
|
||||
index: initialIndex,
|
||||
),
|
||||
play: autoPlay,
|
||||
);
|
||||
// } else {
|
||||
// await _justAudio!.setAudioSource(
|
||||
// ja.ConcatenatingAudioSource(
|
||||
// useLazyPreparation: true,
|
||||
// children:
|
||||
// tracks.map((e) => ja.AudioSource.uri(Uri.parse(e))).toList(),
|
||||
// ),
|
||||
// preload: true,
|
||||
// initialIndex: initialIndex,
|
||||
// );
|
||||
// if (autoPlay) {
|
||||
// await _justAudio!.play();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
List<SpotubeTrack> resolveTracksForSource(List<SpotubeTrack> tracks) {
|
||||
@ -130,108 +130,108 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
|
||||
}
|
||||
|
||||
List<String> get sources {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playlist.medias.map((e) => e.uri).toList();
|
||||
} else {
|
||||
return _justAudio!.sequenceState?.effectiveSequence
|
||||
.map((e) => (e as ja.UriAudioSource).uri.toString())
|
||||
.toList() ??
|
||||
<String>[];
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.playlist.medias.map((e) => e.uri).toList();
|
||||
// } else {
|
||||
// return _justAudio!.sequenceState?.effectiveSequence
|
||||
// .map((e) => (e as ja.UriAudioSource).uri.toString())
|
||||
// .toList() ??
|
||||
// <String>[];
|
||||
// }
|
||||
}
|
||||
|
||||
String? get currentSource {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer!.playlist.index)
|
||||
?.uri;
|
||||
} else {
|
||||
return (_justAudio?.sequenceState?.effectiveSequence
|
||||
.elementAtOrNull(_justAudio!.sequenceState!.currentIndex)
|
||||
as ja.UriAudioSource?)
|
||||
?.uri
|
||||
.toString();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer.playlist.index)
|
||||
?.uri;
|
||||
// } else {
|
||||
// return (_justAudio?.sequenceState?.effectiveSequence
|
||||
// .elementAtOrNull(_justAudio!.sequenceState!.currentIndex)
|
||||
// as ja.UriAudioSource?)
|
||||
// ?.uri
|
||||
// .toString();
|
||||
// }
|
||||
}
|
||||
|
||||
String? get nextSource {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer!.playlist.index + 1)
|
||||
?.uri;
|
||||
} else {
|
||||
return (_justAudio?.sequenceState?.effectiveSequence
|
||||
.elementAtOrNull(_justAudio!.sequenceState!.currentIndex + 1)
|
||||
as ja.UriAudioSource?)
|
||||
?.uri
|
||||
.toString();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer.playlist.index + 1)
|
||||
?.uri;
|
||||
// } else {
|
||||
// return (_justAudio?.sequenceState?.effectiveSequence
|
||||
// .elementAtOrNull(_justAudio!.sequenceState!.currentIndex + 1)
|
||||
// as ja.UriAudioSource?)
|
||||
// ?.uri
|
||||
// .toString();
|
||||
// }
|
||||
}
|
||||
|
||||
String? get previousSource {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer!.playlist.index - 1)
|
||||
?.uri;
|
||||
} else {
|
||||
return (_justAudio?.sequenceState?.effectiveSequence
|
||||
.elementAtOrNull(_justAudio!.sequenceState!.currentIndex - 1)
|
||||
as ja.UriAudioSource?)
|
||||
?.uri
|
||||
.toString();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.playlist.medias
|
||||
.elementAtOrNull(_mkPlayer.playlist.index - 1)
|
||||
?.uri;
|
||||
// } else {
|
||||
// return (_justAudio?.sequenceState?.effectiveSequence
|
||||
// .elementAtOrNull(_justAudio!.sequenceState!.currentIndex - 1)
|
||||
// as ja.UriAudioSource?)
|
||||
// ?.uri
|
||||
// .toString();
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> skipToNext() async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.next();
|
||||
} else {
|
||||
await _justAudio!.seekToNext();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.next();
|
||||
// } else {
|
||||
// await _justAudio!.seekToNext();
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> skipToPrevious() async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.previous();
|
||||
} else {
|
||||
await _justAudio!.seekToPrevious();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.previous();
|
||||
// } else {
|
||||
// await _justAudio!.seekToPrevious();
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> jumpTo(int index) async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.jump(index);
|
||||
} else {
|
||||
await _justAudio!.seek(Duration.zero, index: index);
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.jump(index);
|
||||
// } else {
|
||||
// await _justAudio!.seek(Duration.zero, index: index);
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> addTrack(String url) async {
|
||||
final urlType = _resolveUrlType(url);
|
||||
if (mkSupportedPlatform && urlType is mk.Media) {
|
||||
await _mkPlayer!.add(urlType);
|
||||
} else {
|
||||
await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
.add(urlType as ja.AudioSource);
|
||||
}
|
||||
// if (mkSupportedPlatform && urlType is mk.Media) {
|
||||
await _mkPlayer.add(urlType as mk.Media);
|
||||
// } else {
|
||||
// await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
// .add(urlType as ja.AudioSource);
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> removeTrack(int index) async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.remove(index);
|
||||
} else {
|
||||
await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
.removeAt(index);
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.remove(index);
|
||||
// } else {
|
||||
// await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
// .removeAt(index);
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> moveTrack(int from, int to) async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.move(from, to);
|
||||
} else {
|
||||
await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
.move(from, to);
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.move(from, to);
|
||||
// } else {
|
||||
// await (_justAudio!.audioSource as ja.ConcatenatingAudioSource)
|
||||
// .move(from, to);
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> replaceSource(
|
||||
@ -242,54 +242,54 @@ class SpotubeAudioPlayer extends AudioPlayerInterface
|
||||
final oldSourceIndex = sources.indexOf(oldSource);
|
||||
if (oldSourceIndex == -1) return;
|
||||
|
||||
if (mkSupportedPlatform) {
|
||||
_mkPlayer!.replace(oldSource, newSource);
|
||||
} else {
|
||||
final playlist = _justAudio!.audioSource as ja.ConcatenatingAudioSource;
|
||||
// if (mkSupportedPlatform) {
|
||||
_mkPlayer.replace(oldSource, newSource);
|
||||
// } else {
|
||||
// final playlist = _justAudio!.audioSource as ja.ConcatenatingAudioSource;
|
||||
|
||||
print('oldSource: $oldSource');
|
||||
print('newSource: $newSource');
|
||||
final oldSourceIndexInPlaylist =
|
||||
_justAudio?.sequenceState?.effectiveSequence.indexWhere(
|
||||
(e) => (e as ja.UriAudioSource).uri.toString() == oldSource,
|
||||
);
|
||||
// print('oldSource: $oldSource');
|
||||
// print('newSource: $newSource');
|
||||
// final oldSourceIndexInPlaylist =
|
||||
// _justAudio?.sequenceState?.effectiveSequence.indexWhere(
|
||||
// (e) => (e as ja.UriAudioSource).uri.toString() == oldSource,
|
||||
// );
|
||||
|
||||
print('oldSourceIndexInPlaylist: $oldSourceIndexInPlaylist');
|
||||
// print('oldSourceIndexInPlaylist: $oldSourceIndexInPlaylist');
|
||||
|
||||
// ignores non existing source
|
||||
if (oldSourceIndexInPlaylist == null || oldSourceIndexInPlaylist == -1) {
|
||||
return;
|
||||
}
|
||||
// // ignores non existing source
|
||||
// if (oldSourceIndexInPlaylist == null || oldSourceIndexInPlaylist == -1) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
await playlist.removeAt(oldSourceIndexInPlaylist);
|
||||
await playlist.insert(
|
||||
oldSourceIndexInPlaylist,
|
||||
ja.AudioSource.uri(Uri.parse(newSource)),
|
||||
);
|
||||
}
|
||||
// await playlist.removeAt(oldSourceIndexInPlaylist);
|
||||
// await playlist.insert(
|
||||
// oldSourceIndexInPlaylist,
|
||||
// ja.AudioSource.uri(Uri.parse(newSource)),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> clearPlaylist() async {
|
||||
if (mkSupportedPlatform) {
|
||||
_mkPlayer!.stop();
|
||||
} else {
|
||||
await (_justAudio!.audioSource as ja.ConcatenatingAudioSource).clear();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
_mkPlayer.stop();
|
||||
// } else {
|
||||
// await (_justAudio!.audioSource as ja.ConcatenatingAudioSource).clear();
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> setShuffle(bool shuffle) async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.setShuffle(shuffle);
|
||||
} else {
|
||||
await _justAudio!.setShuffleModeEnabled(shuffle);
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.setShuffle(shuffle);
|
||||
// } else {
|
||||
// await _justAudio!.setShuffleModeEnabled(shuffle);
|
||||
// }
|
||||
}
|
||||
|
||||
Future<void> setLoopMode(PlaybackLoopMode loop) async {
|
||||
if (mkSupportedPlatform) {
|
||||
await _mkPlayer!.setPlaylistMode(loop.toPlaylistMode());
|
||||
} else {
|
||||
await _justAudio!.setLoopMode(loop.toLoopMode());
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
await _mkPlayer.setPlaylistMode(loop.toPlaylistMode());
|
||||
// } else {
|
||||
// await _justAudio!.setLoopMode(loop.toLoopMode());
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -3,42 +3,42 @@ part of 'audio_player.dart';
|
||||
mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {
|
||||
// stream getters
|
||||
Stream<Duration> get durationStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.streams.duration.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.durationStream
|
||||
.where((event) => event != null)
|
||||
.map((event) => event!)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.streams.duration.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.durationStream
|
||||
// .where((event) => event != null)
|
||||
// .map((event) => event!)
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<Duration> get positionStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.streams.position.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.positionStream.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.streams.position.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.positionStream.asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<Duration> get bufferedPositionStream {
|
||||
if (mkSupportedPlatform) {
|
||||
// audioplayers doesn't have the capability to get buffered position
|
||||
return _mkPlayer!.streams.buffer.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.bufferedPositionStream.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
// audioplayers doesn't have the capability to get buffered position
|
||||
return _mkPlayer.streams.buffer.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.bufferedPositionStream.asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<void> get completedStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.streams.completed.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.playerStateStream
|
||||
.where(
|
||||
(event) => event.processingState == ja.ProcessingState.completed)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.streams.completed.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.playerStateStream
|
||||
// .where(
|
||||
// (event) => event.processingState == ja.ProcessingState.completed)
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
/// Stream that emits when the player is almost (%) complete
|
||||
@ -57,92 +57,92 @@ mixin SpotubeAudioPlayersStreams on AudioPlayerInterface {
|
||||
}
|
||||
|
||||
Stream<bool> get playingStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.streams.playing.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.playingStream.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.streams.playing.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.playingStream.asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<bool> get shuffledStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.shuffleStream.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.shuffleModeEnabledStream.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.shuffleStream.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.shuffleModeEnabledStream.asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<PlaybackLoopMode> get loopModeStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.loopModeStream
|
||||
.map(PlaybackLoopMode.fromPlaylistMode)
|
||||
.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.loopModeStream
|
||||
.map(PlaybackLoopMode.fromLoopMode)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.loopModeStream
|
||||
.map(PlaybackLoopMode.fromPlaylistMode)
|
||||
.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.loopModeStream
|
||||
// .map(PlaybackLoopMode.fromLoopMode)
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<double> get volumeStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.streams.volume
|
||||
.map((event) => event / 100)
|
||||
.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.volumeStream.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.streams.volume
|
||||
.map((event) => event / 100)
|
||||
.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.volumeStream.asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<bool> get bufferingStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return Stream.value(false).asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.playerStateStream
|
||||
.map(
|
||||
(event) =>
|
||||
event.processingState == ja.ProcessingState.buffering ||
|
||||
event.processingState == ja.ProcessingState.loading,
|
||||
)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return Stream.value(false).asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.playerStateStream
|
||||
// .map(
|
||||
// (event) =>
|
||||
// event.processingState == ja.ProcessingState.buffering ||
|
||||
// event.processingState == ja.ProcessingState.loading,
|
||||
// )
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<AudioPlaybackState> get playerStateStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.playerStateStream.asBroadcastStream();
|
||||
} else {
|
||||
return _justAudio!.playerStateStream
|
||||
.map(AudioPlaybackState.fromJaPlayerState)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.playerStateStream.asBroadcastStream();
|
||||
// } else {
|
||||
// return _justAudio!.playerStateStream
|
||||
// .map(AudioPlaybackState.fromJaPlayerState)
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<int> get currentIndexChangedStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.indexChangeStream;
|
||||
} else {
|
||||
return _justAudio!.sequenceStateStream
|
||||
.map((event) => event?.currentIndex ?? -1)
|
||||
.asBroadcastStream();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.indexChangeStream;
|
||||
// } else {
|
||||
// return _justAudio!.sequenceStateStream
|
||||
// .map((event) => event?.currentIndex ?? -1)
|
||||
// .asBroadcastStream();
|
||||
// }
|
||||
}
|
||||
|
||||
Stream<String> get activeSourceChangedStream {
|
||||
if (mkSupportedPlatform) {
|
||||
return _mkPlayer!.indexChangeStream
|
||||
.map((event) {
|
||||
return _mkPlayer!.playlist.medias.elementAtOrNull(event)?.uri;
|
||||
})
|
||||
.where((event) => event != null)
|
||||
.cast<String>();
|
||||
} else {
|
||||
return _justAudio!.sequenceStateStream
|
||||
.map((event) {
|
||||
return (event?.currentSource as ja.UriAudioSource?)?.uri.toString();
|
||||
})
|
||||
.where((event) => event != null)
|
||||
.cast<String>();
|
||||
}
|
||||
// if (mkSupportedPlatform) {
|
||||
return _mkPlayer.indexChangeStream
|
||||
.map((event) {
|
||||
return _mkPlayer.playlist.medias.elementAtOrNull(event)?.uri;
|
||||
})
|
||||
.where((event) => event != null)
|
||||
.cast<String>();
|
||||
// } else {
|
||||
// return _justAudio!.sequenceStateStream
|
||||
// .map((event) {
|
||||
// return (event?.currentSource as ja.UriAudioSource?)?.uri.toString();
|
||||
// })
|
||||
// .where((event) => event != null)
|
||||
// .cast<String>();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
// import 'package:just_audio/just_audio.dart';
|
||||
import 'package:mpris_service/mpris_service.dart';
|
||||
|
||||
/// An unified loop mode for both [LoopMode] and [PlaylistMode]
|
||||
@ -9,27 +9,27 @@ enum PlaybackLoopMode {
|
||||
one,
|
||||
none;
|
||||
|
||||
static PlaybackLoopMode fromLoopMode(LoopMode loopMode) {
|
||||
switch (loopMode) {
|
||||
case LoopMode.all:
|
||||
return PlaybackLoopMode.all;
|
||||
case LoopMode.one:
|
||||
return PlaybackLoopMode.one;
|
||||
case LoopMode.off:
|
||||
return PlaybackLoopMode.none;
|
||||
}
|
||||
}
|
||||
// static PlaybackLoopMode fromLoopMode(LoopMode loopMode) {
|
||||
// switch (loopMode) {
|
||||
// case LoopMode.all:
|
||||
// return PlaybackLoopMode.all;
|
||||
// case LoopMode.one:
|
||||
// return PlaybackLoopMode.one;
|
||||
// case LoopMode.off:
|
||||
// return PlaybackLoopMode.none;
|
||||
// }
|
||||
// }
|
||||
|
||||
LoopMode toLoopMode() {
|
||||
switch (this) {
|
||||
case PlaybackLoopMode.all:
|
||||
return LoopMode.all;
|
||||
case PlaybackLoopMode.one:
|
||||
return LoopMode.one;
|
||||
case PlaybackLoopMode.none:
|
||||
return LoopMode.off;
|
||||
}
|
||||
}
|
||||
// LoopMode toLoopMode() {
|
||||
// switch (this) {
|
||||
// case PlaybackLoopMode.all:
|
||||
// return LoopMode.all;
|
||||
// case PlaybackLoopMode.one:
|
||||
// return LoopMode.one;
|
||||
// case PlaybackLoopMode.none:
|
||||
// return LoopMode.off;
|
||||
// }
|
||||
// }
|
||||
|
||||
static PlaybackLoopMode fromPlaylistMode(PlaylistMode mode) {
|
||||
switch (mode) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
// import 'package:just_audio/just_audio.dart';
|
||||
|
||||
/// An unified playback state enum
|
||||
enum AudioPlaybackState {
|
||||
@ -8,21 +8,21 @@ enum AudioPlaybackState {
|
||||
buffering,
|
||||
stopped;
|
||||
|
||||
static AudioPlaybackState fromJaPlayerState(PlayerState state) {
|
||||
if (state.playing) {
|
||||
return AudioPlaybackState.playing;
|
||||
}
|
||||
// static AudioPlaybackState fromJaPlayerState(PlayerState state) {
|
||||
// if (state.playing) {
|
||||
// return AudioPlaybackState.playing;
|
||||
// }
|
||||
|
||||
switch (state.processingState) {
|
||||
case ProcessingState.idle:
|
||||
return AudioPlaybackState.stopped;
|
||||
case ProcessingState.ready:
|
||||
return AudioPlaybackState.paused;
|
||||
case ProcessingState.completed:
|
||||
return AudioPlaybackState.completed;
|
||||
case ProcessingState.loading:
|
||||
case ProcessingState.buffering:
|
||||
return AudioPlaybackState.buffering;
|
||||
}
|
||||
}
|
||||
// switch (state.processingState) {
|
||||
// case ProcessingState.idle:
|
||||
// return AudioPlaybackState.stopped;
|
||||
// case ProcessingState.ready:
|
||||
// return AudioPlaybackState.paused;
|
||||
// case ProcessingState.completed:
|
||||
// return AudioPlaybackState.completed;
|
||||
// case ProcessingState.loading:
|
||||
// case ProcessingState.buffering:
|
||||
// return AudioPlaybackState.buffering;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ import audio_session
|
||||
import catcher
|
||||
import device_info_plus
|
||||
import flutter_secure_storage_macos
|
||||
import just_audio
|
||||
import local_notifier
|
||||
import media_kit_libs_macos_audio
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import screen_retriever
|
||||
@ -32,8 +32,8 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
CatcherPlugin.register(with: registry.registrar(forPlugin: "CatcherPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||
LocalNotifierPlugin.register(with: registry.registrar(forPlugin: "LocalNotifierPlugin"))
|
||||
MediaKitLibsMacosAudioPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosAudioPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||
|
48
pubspec.lock
48
pubspec.lock
@ -966,30 +966,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.6.2"
|
||||
just_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: just_audio
|
||||
sha256: "7e6d31508dacd01a066e3889caf6282e5f1eb60707c230203b21a83af5c55586"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.32"
|
||||
just_audio_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: just_audio_platform_interface
|
||||
sha256: eff112d5138bea3ba544b6338b1e0537a32b5e1425e4d0dc38f732771cda7c84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
just_audio_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: just_audio_web
|
||||
sha256: "89d8db6f19f3821bb6bf908c4bfb846079afb2ab575b783d781a6bf119e3abaf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.7"
|
||||
jwt_decode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1062,6 +1038,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.7+1"
|
||||
media_kit_libs_android_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: media_kit_libs_android_audio
|
||||
sha256: e16292bbb1d737ce026fa68154b2fcf5c6f88d6fa752bdb4c0d079c98a82b523
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
media_kit_libs_ios_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: media_kit_libs_ios_audio
|
||||
sha256: bb18ed87e8a155fc1d2ee4bf59462ca04d02a0eeb38d0b454facee6d32441ce7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
media_kit_libs_linux:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1070,6 +1062,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
media_kit_libs_macos_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: media_kit_libs_macos_audio
|
||||
sha256: b9f4a2995396fd5cc243901e618c0586d4f1781eecf2302999b77d6faee8b250
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
media_kit_libs_windows_audio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -55,12 +55,14 @@ dependencies:
|
||||
intl: ^0.18.0
|
||||
introduction_screen: ^3.0.2
|
||||
json_annotation: ^4.8.1
|
||||
just_audio: ^0.9.32
|
||||
logger: ^1.1.0
|
||||
media_kit: ^0.0.7+1
|
||||
media_kit_libs_windows_audio: ^1.0.3
|
||||
media_kit_libs_linux: ^1.0.2
|
||||
media_kit_native_event_loop: ^1.0.3
|
||||
media_kit_libs_android_audio: ^1.0.4
|
||||
media_kit_libs_ios_audio: ^1.0.4
|
||||
media_kit_libs_linux: ^1.0.2
|
||||
media_kit_libs_macos_audio: ^1.0.5
|
||||
media_kit_libs_windows_audio: ^1.0.3
|
||||
metadata_god: ^0.4.1
|
||||
mime: ^1.0.2
|
||||
mpris_service:
|
||||
|
Loading…
Reference in New Issue
Block a user