Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'package:flutter/material.dart';
- import 'package:soundscape/shared/managers/backend_manager.dart';
- import 'package:soundscape/shared/managers/polygons_manager.dart';
- import "package:soundscape/models/backend/songs.dart";
- import "package:soundscape/models/backend/assets.dart";
- import "package:soundscape/models/backend/artist.dart";
- class StreamMusicManager {
- static final StreamMusicManager _instance = StreamMusicManager._internal();
- factory StreamMusicManager() => _instance;
- StreamMusicManager._internal();
- Map<String, dynamic> _currentMusicPath = {};
- Map<String, dynamic> get getCurrentMusicPath => _currentMusicPath;
- String get getCurrentMusicAuthor => _currentMusicPath['author'] ?? '';
- String get getCurrentMusicTitle => _currentMusicPath['title'] ?? '';
- String get getCurrentMusicImagePath => _currentMusicPath['musicPath'] ?? '';
- String get getCurrentMusicCoverPath => _currentMusicPath['coverPath'] ?? '';
- int get getCurrentMusicIndex => _currentMusicPath['currentIndex'] ?? 0;
- final Map<String, Map<String, dynamic>> _musics = {};
- Function(String?)? onTrackEnded;
- Future<void> chooseMusic(SoundscapePolygon polygon) async {
- debugPrint("🎵 [chooseMusic] Début pour polygone: ${polygon.uuid}");
- BackendManager backendProvider = BackendManager();
- if (backendProvider.backendIsDead) {
- debugPrint("❌ [chooseMusic] Backend mort");
- _currentMusicPath = {};
- return;
- }
- if (_musics.containsKey(polygon.uuid)) {
- debugPrint("🎵 [chooseMusic] Musique déjà configurée pour ${polygon.uuid}");
- _currentMusicPath = Map<String, dynamic>.from(_musics[polygon.uuid]!);
- debugPrint(" - _currentMusicPath: $_currentMusicPath");
- return;
- }
- try {
- if (polygon.songsUuid.isEmpty) {
- debugPrint("❌ [chooseMusic] Aucune musique dans le polygone");
- _currentMusicPath = {};
- return;
- }
- debugPrint("🎵 [chooseMusic] Chargement de la première musique: ${polygon.songsUuid[0]}");
- final firstSongObject = await getSong(polygon.songsUuid[0]);
- debugPrint("🎵 [chooseMusic] Info première chanson reçue: $firstSongObject");
- final firstFileObjectUuid = firstSongObject["file_object_uuid"];
- final firstArtistUuid = firstSongObject["artist_uuid"];
- final firstCoverUuid = firstSongObject["cover_uuid"];
- final firstAlbumUuid = firstSongObject["album_uuid"];
- if (firstFileObjectUuid == null || firstFileObjectUuid.isEmpty ||
- firstArtistUuid == null || firstArtistUuid.isEmpty ||
- firstCoverUuid == null || firstCoverUuid.isEmpty ||
- firstAlbumUuid == null || firstAlbumUuid.isEmpty) {
- debugPrint("❌ [chooseMusic] Données manquantes pour la première musique");
- _currentMusicPath = {};
- return;
- }
- debugPrint("🎵 [chooseMusic] Récupération premier asset: $firstFileObjectUuid");
- final firstResults = await Future.wait([
- getMusicAsset(firstFileObjectUuid),
- getArtist(firstArtistUuid),
- getImgAsset(firstCoverUuid),
- ]);
- final firstAsset = firstResults[0];
- final firstArtist = firstResults[1];
- final firstCoverAsset = firstResults[2];
- if (firstAsset == null || !await firstAsset.exists()) {
- debugPrint("❌ [chooseMusic] Premier asset invalide");
- _currentMusicPath = {};
- return;
- }
- final firstMusicData = {
- 'polygonId': polygon.uuid,
- 'musicPaths': [firstAsset.path],
- 'authors': [firstArtist["name"] ?? "Artiste inconnu"],
- 'titles': [firstSongObject["name"] ?? "Titre inconnu"],
- 'coverPaths': [firstCoverAsset.path],
- 'songsUuid': polygon.songsUuid,
- 'currentIndex': 0,
- 'totalTracks': polygon.songsUuid.length,
- 'isFullyLoaded': false,
- 'musicPath': firstAsset.path,
- 'author': firstArtist["name"] ?? "Artiste inconnu",
- 'title': firstSongObject["name"] ?? "Titre inconnu",
- 'coverPath': firstCoverAsset.path,
- };
- _musics[polygon.uuid] = firstMusicData;
- _currentMusicPath = Map<String, dynamic>.from(firstMusicData);
- debugPrint("✅ [chooseMusic] Première musique prête: ${firstSongObject["name"]}");
- debugPrint(" - Chemin: ${firstAsset.path}");
- if (polygon.songsUuid.length > 1) {
- debugPrint("🎵 [chooseMusic] Démarrage chargement en arrière-plan des ${polygon.songsUuid.length - 1} autres musiques");
- _loadRemainingMusicInBackground(polygon);
- } else {
- _musics[polygon.uuid]!['isFullyLoaded'] = true;
- }
- } catch (error, stackTrace) {
- debugPrint("❌ [chooseMusic] Erreur: $error");
- debugPrint("❌ [chooseMusic] StackTrace: $stackTrace");
- _currentMusicPath = {};
- }
- }
- Future<void> _loadRemainingMusicInBackground(SoundscapePolygon polygon) async {
- try {
- debugPrint("🔄 [_loadRemainingMusicInBackground] Début pour ${polygon.songsUuid.length - 1} musiques");
- List<String> allMusicPaths = List<String>.from(_musics[polygon.uuid]!['musicPaths']);
- List<String> allAuthors = List<String>.from(_musics[polygon.uuid]!['authors']);
- List<String> allTitles = List<String>.from(_musics[polygon.uuid]!['titles']);
- List<String> allCoverPaths = List<String>.from(_musics[polygon.uuid]!['coverPaths']);
- for (int i = 1; i < polygon.songsUuid.length; i++) {
- try {
- String songUuid = polygon.songsUuid[i];
- debugPrint("🔄 [Background] Chargement musique $i/${ polygon.songsUuid.length - 1}: $songUuid");
- final songObject = await getSong(songUuid);
- final fileObjectUuid = songObject["file_object_uuid"];
- final artistUuid = songObject["artist_uuid"];
- final coverUuid = songObject["cover_uuid"];
- final albumUuid = songObject["album_uuid"];
- if (fileObjectUuid == null || fileObjectUuid.isEmpty ||
- artistUuid == null || artistUuid.isEmpty ||
- coverUuid == null || coverUuid.isEmpty ||
- albumUuid == null || albumUuid.isEmpty) {
- debugPrint("❌ [Background] Données manquantes pour $songUuid");
- continue;
- }
- final results = await Future.wait([
- getMusicAsset(fileObjectUuid),
- getArtist(artistUuid),
- getImgAsset(coverUuid),
- ]);
- final asset = results[0];
- final artist = results[1];
- final cover = results[2];
- if (asset == null || !await asset.exists()) {
- debugPrint("❌ [Background] Asset invalide pour $songUuid");
- continue;
- }
- String coverPath = '';
- if (cover != null && await cover.exists()) {
- coverPath = cover.path;
- } else {
- debugPrint("⚠️ [Background] Cover manquante pour $songUuid, utilisation image par défaut");
- coverPath = 'assets/images/default_cover.png';
- }
- allMusicPaths.add(asset.path);
- allAuthors.add(artist["name"] ?? "Artiste inconnu");
- allTitles.add(songObject["name"] ?? "Titre inconnu");
- allCoverPaths.add(coverPath);
- if (_musics.containsKey(polygon.uuid)) {
- _musics[polygon.uuid]!['musicPaths'] = allMusicPaths;
- _musics[polygon.uuid]!['authors'] = allAuthors;
- _musics[polygon.uuid]!['titles'] = allTitles;
- _musics[polygon.uuid]!['coverPaths'] = allCoverPaths;
- _musics[polygon.uuid]!['totalTracks'] = allMusicPaths.length;
- }
- debugPrint("✅ [Background] Musique ajoutée: ${songObject["name"]} (${allMusicPaths.length}/${polygon.songsUuid.length})");
- } catch (e) {
- debugPrint("❌ [Background] Erreur pour musique $i: $e");
- continue;
- }
- }
- if (_musics.containsKey(polygon.uuid)) {
- _musics[polygon.uuid]!['isFullyLoaded'] = true;
- debugPrint("✅ [Background] Chargement terminé: ${allMusicPaths.length} musiques prêtes");
- }
- } catch (error) {
- debugPrint("❌ [_loadRemainingMusicInBackground] Erreur générale: $error");
- }
- }
- String getCurrentCoverPath(String polygonId) {
- if (!_musics.containsKey(polygonId)) return '';
- final musicData = _musics[polygonId]!;
- final currentIndex = musicData['currentIndex'] as int;
- return getCoverPathByIndex(polygonId, currentIndex);
- }
- List<String> getAllCoverPaths(String polygonId) {
- debugPrint("🎵 [getAllCoverPaths] Récupération des chemins de couverture pour le polygone: $polygonId");
- if (!_musics.containsKey(polygonId)) {
- debugPrint("🎵 [getAllCoverPaths] Polygone $polygonId non trouvé");
- return [];
- }
- debugPrint("🎵 [getAllCoverPaths] Polygone trouvé, extraction des chemins de couverture");
- final musicData = _musics[polygonId]!;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>?;
- if (coverPathsRaw == null) {
- debugPrint("🎵 [getAllCoverPaths] Aucune coverPaths trouvée");
- return [];
- }
- final List<String> coverPaths = coverPathsRaw
- .where((path) => path != null)
- .map((path) => path.toString())
- .toList();
- debugPrint("🎵 [getAllCoverPaths] ${coverPaths.length} chemins de couverture récupérés");
- return coverPaths;
- }
- List<Map<String, dynamic>> getFullQueue(String polygonId) {
- if (!_musics.containsKey(polygonId)) return [];
- final musicData = _musics[polygonId]!;
- final musicPathsRaw = musicData['musicPaths'] as List<dynamic>;
- final authorsRaw = musicData['authors'] as List<dynamic>;
- final titlesRaw = musicData['titles'] as List<dynamic>;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>;
- final musicPaths = musicPathsRaw.cast<String>();
- final authors = authorsRaw.cast<String>();
- final titles = titlesRaw.cast<String>();
- final coverPaths = coverPathsRaw.cast<String>();
- final currentIndex = musicData['currentIndex'] as int;
- List<Map<String, dynamic>> queue = [];
- for (int i = 0; i < musicPaths.length; i++) {
- queue.add({
- 'musicPath': musicPaths[i],
- 'author': authors[i],
- 'title': titles[i],
- 'coverPath': coverPaths[i],
- 'index': i,
- 'isCurrent': i == currentIndex,
- });
- }
- return queue;
- }
- Future<String?> getNextTrack(String polygonId) async {
- if (!_musics.containsKey(polygonId)) {
- debugPrint("❌ [getNextTrack] Polygone $polygonId non trouvé");
- return null;
- }
- final musicData = _musics[polygonId]!;
- final currentIndex = musicData['currentIndex'] as int;
- final musicPathsRaw = musicData['musicPaths'] as List<dynamic>;
- final authorsRaw = musicData['authors'] as List<dynamic>;
- final titlesRaw = musicData['titles'] as List<dynamic>;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>;
- final musicPaths = musicPathsRaw.cast<String>();
- final authors = authorsRaw.cast<String>();
- final titles = titlesRaw.cast<String>();
- final coverPaths = coverPathsRaw.cast<String>();
- final isFullyLoaded = musicData['isFullyLoaded'] as bool;
- int nextIndex = currentIndex + 1;
- if (nextIndex >= musicPaths.length && !isFullyLoaded) {
- debugPrint("🔄 [getNextTrack] Musique suivante pas encore chargée, on reste sur la courante");
- return null;
- }
- if (nextIndex >= musicPaths.length) {
- nextIndex = 0;
- }
- musicData['currentIndex'] = nextIndex;
- musicData['musicPath'] = musicPaths[nextIndex];
- musicData['author'] = authors[nextIndex];
- musicData['title'] = titles[nextIndex];
- musicData['coverPath'] = coverPaths[nextIndex];
- _currentMusicPath = Map<String, dynamic>.from(musicData);
- debugPrint("🎵 [getNextTrack] Passage à la musique suivante:");
- debugPrint(" - Index: $nextIndex/${musicPaths.length - 1}");
- debugPrint(" - Titre: ${titles[nextIndex]}");
- debugPrint(" - Cover: ${coverPaths[nextIndex]}");
- debugPrint(" - Chargement complet: $isFullyLoaded");
- return musicPaths[nextIndex];
- }
- Map<String, dynamic>? getTotalNextTrack(String polygonId) {
- debugPrint("🎵 [getTotalNextTrack] Récupération des infos de la piste suivante pour: $polygonId");
- if (!_musics.containsKey(polygonId)) {
- debugPrint("❌ [getTotalNextTrack] Polygone $polygonId non trouvé");
- return null;
- }
- final musicData = _musics[polygonId]!;
- final currentIndex = musicData['currentIndex'] as int;
- final musicPathsRaw = musicData['musicPaths'] as List<dynamic>;
- final authorsRaw = musicData['authors'] as List<dynamic>;
- final titlesRaw = musicData['titles'] as List<dynamic>;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>;
- final musicPaths = musicPathsRaw.cast<String>();
- final authors = authorsRaw.cast<String>();
- final titles = titlesRaw.cast<String>();
- final coverPaths = coverPathsRaw.cast<String>();
- final isFullyLoaded = musicData['isFullyLoaded'] as bool;
- int nextIndex = currentIndex + 1;
- if (nextIndex >= musicPaths.length && !isFullyLoaded) {
- debugPrint("🔄 [getTotalNextTrack] Piste suivante pas encore chargée");
- return null;
- }
- if (nextIndex >= musicPaths.length) {
- nextIndex = 0;
- }
- final nextTrackInfo = {
- 'polygonId': polygonId,
- 'musicPath': musicPaths[nextIndex],
- 'author': authors[nextIndex],
- 'title': titles[nextIndex],
- 'coverPath': coverPaths[nextIndex],
- 'index': nextIndex,
- 'totalTracks': musicPaths.length,
- 'isFullyLoaded': isFullyLoaded,
- 'isLastTrack': nextIndex == (musicPaths.length - 1),
- 'isFirstTrack': nextIndex == 0,
- 'willLoop': (currentIndex + 1) >= musicPaths.length
- };
- debugPrint("🎵 [getTotalNextTrack] Piste suivante trouvée:");
- debugPrint(" - Index: $nextIndex/${musicPaths.length - 1}");
- debugPrint(" - Titre: ${titles[nextIndex]}");
- debugPrint(" - Artiste: ${authors[nextIndex]}");
- debugPrint(" - Va boucler: ${nextTrackInfo['willLoop']}");
- return nextTrackInfo;
- }
- String getCoverPathByIndex(String polygonId, int index) {
- if (!_musics.containsKey(polygonId)) return '';
- final musicData = _musics[polygonId]!;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>;
- final coverPaths = coverPathsRaw.cast<String>();
- if (index >= 0 && index < coverPaths.length) {
- return coverPaths[index];
- }
- return 'assets/images/default_cover.png';
- }
- String getNextCoverPath(String polygonId) {
- if (!_musics.containsKey(polygonId)) return '';
- final musicData = _musics[polygonId]!;
- final currentIndex = musicData['currentIndex'] as int;
- final coverPathsRaw = musicData['coverPaths'] as List<dynamic>;
- final coverPaths = coverPathsRaw.cast<String>();
- int nextIndex = (currentIndex + 1) % coverPaths.length;
- return getCoverPathByIndex(polygonId, nextIndex);
- }
- Map<String, dynamic>? getLoadingStatus(String polygonId) {
- if (!_musics.containsKey(polygonId)) return null;
- final musicData = _musics[polygonId]!;
- return {
- 'isFullyLoaded': musicData['isFullyLoaded'],
- 'loadedTracks': (musicData['musicPaths'] as List).length,
- 'totalTracks': musicData['totalTracks'],
- 'currentTrack': musicData['currentIndex'] + 1,
- };
- }
- Future<void> onMusicEnded(String currentPolygonId) async {
- debugPrint("🎵 [onMusicEnded] Musique terminée pour polygone: $currentPolygonId");
- final nextTrack = await getNextTrack(currentPolygonId);
- if (nextTrack != null && onTrackEnded != null) {
- onTrackEnded!(nextTrack);
- }
- }
- bool currentEqualsToNext(SoundscapePolygon? polygon) {
- if (polygon == null) {
- _currentMusicPath = {};
- return false;
- }
- if (_musics[polygon.uuid] == null) {
- _currentMusicPath = {};
- return false;
- }
- if (_currentMusicPath["musicPath"] == _musics[polygon.uuid]!["musicPath"]) {
- return true;
- }
- return false;
- }
- Map<String, dynamic>? getQueueInfo(String polygonId) {
- if (!_musics.containsKey(polygonId)) return null;
- final musicData = _musics[polygonId]!;
- return {
- 'currentIndex': musicData['currentIndex'],
- 'totalTracks': musicData['totalTracks'],
- 'currentTitle': musicData['title'],
- 'currentAuthor': musicData['author'],
- 'currentCoverPath': musicData['coverPath'],
- };
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement