🐛 Bug fixes on playback
This commit is contained in:
parent
031cab75e0
commit
41e248f8cc
@ -50,10 +50,11 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
void _initializeProviders(BuildContext context) async {
|
void _initializeProviders(BuildContext context) async {
|
||||||
Get.lazyPut(() => SpotifyProvider());
|
Get.lazyPut(() => SpotifyProvider());
|
||||||
Get.lazyPut(() => AudioPlayerProvider());
|
|
||||||
Get.lazyPut(() => ActiveSourcedTrackProvider());
|
Get.lazyPut(() => ActiveSourcedTrackProvider());
|
||||||
Get.lazyPut(() => SourcedTrackProvider());
|
Get.lazyPut(() => SourcedTrackProvider());
|
||||||
Get.lazyPut(() => ServerPlaybackRoutesProvider());
|
|
||||||
Get.lazyPut(() => PlaybackServerProvider());
|
Get.put(AudioPlayerProvider());
|
||||||
|
Get.put(ServerPlaybackRoutesProvider());
|
||||||
|
Get.put(PlaybackServerProvider());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:media_kit/media_kit.dart' hide Track;
|
import 'package:media_kit/media_kit.dart' hide Track;
|
||||||
import 'package:rhythm_box/services/audio_player/state.dart';
|
import 'package:rhythm_box/services/audio_player/state.dart';
|
||||||
import 'package:rhythm_box/services/local_track.dart';
|
import 'package:rhythm_box/services/local_track.dart';
|
||||||
import 'package:rhythm_box/services/sourced_track/sourced_track.dart';
|
import 'package:rhythm_box/services/server/sourced_track.dart';
|
||||||
import 'package:spotify/spotify.dart' hide Playlist;
|
import 'package:spotify/spotify.dart' hide Playlist;
|
||||||
import 'package:rhythm_box/services/audio_player/audio_player.dart';
|
import 'package:rhythm_box/services/audio_player/audio_player.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
@ -20,10 +21,49 @@ class AudioPlayerProvider extends GetxController {
|
|||||||
collections: [],
|
collections: [],
|
||||||
));
|
));
|
||||||
|
|
||||||
AudioPlayerProvider() {
|
List<StreamSubscription<Object>>? _subscriptions;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
SharedPreferences.getInstance().then((ins) {
|
SharedPreferences.getInstance().then((ins) {
|
||||||
_prefs = ins;
|
_prefs = ins;
|
||||||
|
_syncSavedState();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_subscriptions = [
|
||||||
|
audioPlayer.playingStream.listen((playing) async {
|
||||||
|
state.value = state.value.copyWith(playing: playing);
|
||||||
|
}),
|
||||||
|
audioPlayer.loopModeStream.listen((loopMode) async {
|
||||||
|
state.value = state.value.copyWith(loopMode: loopMode);
|
||||||
|
}),
|
||||||
|
audioPlayer.shuffledStream.listen((shuffled) async {
|
||||||
|
state.value = state.value.copyWith(shuffled: shuffled);
|
||||||
|
}),
|
||||||
|
audioPlayer.playlistStream.listen((playlist) async {
|
||||||
|
state.value = state.value.copyWith(playlist: playlist);
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
state.value = AudioPlayerState(
|
||||||
|
loopMode: audioPlayer.loopMode,
|
||||||
|
playing: audioPlayer.isPlaying,
|
||||||
|
playlist: audioPlayer.playlist,
|
||||||
|
shuffled: audioPlayer.isShuffled,
|
||||||
|
collections: [],
|
||||||
|
);
|
||||||
|
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
if (_subscriptions != null) {
|
||||||
|
for (final subscription in _subscriptions!) {
|
||||||
|
subscription.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _syncSavedState() async {
|
Future<void> _syncSavedState() async {
|
||||||
@ -35,6 +75,29 @@ class AudioPlayerProvider extends GetxController {
|
|||||||
// TODO Sync saved playlist
|
// TODO Sync saved playlist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> addCollections(List<String> collectionIds) async {
|
||||||
|
state.value = state.value.copyWith(collections: [
|
||||||
|
...state.value.collections,
|
||||||
|
...collectionIds,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> addCollection(String collectionId) async {
|
||||||
|
await addCollections([collectionId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removeCollections(List<String> collectionIds) async {
|
||||||
|
state.value = state.value.copyWith(
|
||||||
|
collections: state.value.collections
|
||||||
|
.where((element) => !collectionIds.contains(element))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removeCollection(String collectionId) async {
|
||||||
|
await removeCollections([collectionId]);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> load(
|
Future<void> load(
|
||||||
List<Track> tracks, {
|
List<Track> tracks, {
|
||||||
int initialIndex = 0,
|
int initialIndex = 0,
|
||||||
@ -46,11 +109,14 @@ class AudioPlayerProvider extends GetxController {
|
|||||||
// because of timeout
|
// because of timeout
|
||||||
final intendedActiveTrack = medias.elementAt(initialIndex);
|
final intendedActiveTrack = medias.elementAt(initialIndex);
|
||||||
if (intendedActiveTrack.track is! LocalTrack) {
|
if (intendedActiveTrack.track is! LocalTrack) {
|
||||||
await SourcedTrack.fetchFromTrack(track: intendedActiveTrack.track);
|
await Get.find<SourcedTrackProvider>()
|
||||||
|
.fetch(RhythmMedia(intendedActiveTrack.track));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (medias.isEmpty) return;
|
if (medias.isEmpty) return;
|
||||||
|
|
||||||
|
await removeCollections(state.value.collections);
|
||||||
|
|
||||||
await audioPlayer.openPlaylist(
|
await audioPlayer.openPlaylist(
|
||||||
medias.map((s) => s as Media).toList(),
|
medias.map((s) => s as Media).toList(),
|
||||||
initialIndex: initialIndex,
|
initialIndex: initialIndex,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:media_kit/media_kit.dart' hide Track;
|
import 'package:media_kit/media_kit.dart' hide Track;
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:rhythm_box/platform.dart';
|
import 'package:rhythm_box/platform.dart';
|
||||||
import 'package:rhythm_box/services/local_track.dart';
|
import 'package:rhythm_box/services/local_track.dart';
|
||||||
|
import 'package:rhythm_box/services/server/server.dart';
|
||||||
import 'package:spotify/spotify.dart' hide Playlist;
|
import 'package:spotify/spotify.dart' hide Playlist;
|
||||||
import 'package:rhythm_box/services/audio_player/custom_player.dart';
|
import 'package:rhythm_box/services/audio_player/custom_player.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@ -20,7 +22,7 @@ part 'audio_player_impl.dart';
|
|||||||
class RhythmMedia extends mk.Media {
|
class RhythmMedia extends mk.Media {
|
||||||
final Track track;
|
final Track track;
|
||||||
|
|
||||||
static int serverPort = 0;
|
static int get serverPort => Get.find<PlaybackServerProvider>().port;
|
||||||
|
|
||||||
RhythmMedia(
|
RhythmMedia(
|
||||||
this.track, {
|
this.track, {
|
||||||
|
@ -58,8 +58,8 @@ class ServerPlaybackRoutesProvider {
|
|||||||
},
|
},
|
||||||
headers: res.headers.map,
|
headers: res.headers.map,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e, stackTrace) {
|
||||||
log('[PlaybackSever] Error: $e');
|
log('[PlaybackSever] Error: $e; Trace:\n $stackTrace');
|
||||||
return Response.internalServerError();
|
return Response.internalServerError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ import 'package:shelf/shelf_io.dart';
|
|||||||
import 'package:shelf_router/shelf_router.dart';
|
import 'package:shelf_router/shelf_router.dart';
|
||||||
|
|
||||||
class PlaybackServerProvider extends GetxController {
|
class PlaybackServerProvider extends GetxController {
|
||||||
|
final int port = Random().nextInt(17500) + 5000;
|
||||||
|
|
||||||
HttpServer? _server;
|
HttpServer? _server;
|
||||||
Router? _router;
|
Router? _router;
|
||||||
|
|
||||||
@ -26,8 +28,6 @@ class PlaybackServerProvider extends GetxController {
|
|||||||
pipeline.addMiddleware(logRequests());
|
pipeline.addMiddleware(logRequests());
|
||||||
}
|
}
|
||||||
|
|
||||||
final port = Random().nextInt(17500) + 5000;
|
|
||||||
|
|
||||||
RhythmMedia.serverPort = port;
|
RhythmMedia.serverPort = port;
|
||||||
|
|
||||||
_router = Router();
|
_router = Router();
|
||||||
|
@ -1,17 +1,36 @@
|
|||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:rhythm_box/providers/audio_player.dart';
|
||||||
import 'package:rhythm_box/services/audio_player/audio_player.dart';
|
import 'package:rhythm_box/services/audio_player/audio_player.dart';
|
||||||
import 'package:rhythm_box/services/local_track.dart';
|
import 'package:rhythm_box/services/local_track.dart';
|
||||||
import 'package:rhythm_box/services/sourced_track/sourced_track.dart';
|
import 'package:rhythm_box/services/sourced_track/sourced_track.dart';
|
||||||
|
import 'package:spotify/spotify.dart';
|
||||||
|
|
||||||
class SourcedTrackProvider extends GetxController {
|
class SourcedTrackProvider extends GetxController {
|
||||||
|
Rx<SourcedTrack?> sourcedTrack = Rx(null);
|
||||||
|
|
||||||
Future<SourcedTrack?> fetch(RhythmMedia? media) async {
|
Future<SourcedTrack?> fetch(RhythmMedia? media) async {
|
||||||
final track = media?.track;
|
final track = media?.track;
|
||||||
if (track == null || track is LocalTrack) {
|
if (track == null || track is LocalTrack) {
|
||||||
|
sourcedTrack.value = null;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final sourcedTrack = await SourcedTrack.fetchFromTrack(track: track);
|
final AudioPlayerProvider playback = Get.find();
|
||||||
|
|
||||||
return sourcedTrack;
|
ever(playback.state.value.tracks.obs, (List<Track> tracks) {
|
||||||
|
if (tracks.isEmpty || tracks.none((element) => element.id == track.id)) {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sourcedTrack.value = await SourcedTrack.fetchFromTrack(track: track);
|
||||||
|
|
||||||
|
return sourcedTrack.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalidate() {
|
||||||
|
sourcedTrack.value = null;
|
||||||
|
fetch(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user