2021-04-26 19:28:32 +02:00
|
|
|
import 'dart:io';
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
import 'package:audiotagger/audiotagger.dart';
|
|
|
|
import 'package:path_provider/path_provider.dart';
|
2021-02-26 22:07:18 +01:00
|
|
|
|
|
|
|
import '../models/album_model.dart';
|
|
|
|
import '../models/artist_model.dart';
|
|
|
|
import '../models/song_model.dart';
|
|
|
|
import 'local_music_fetcher.dart';
|
|
|
|
import 'settings_data_source.dart';
|
|
|
|
|
|
|
|
class LocalMusicFetcherImpl implements LocalMusicFetcher {
|
2021-04-26 19:28:32 +02:00
|
|
|
LocalMusicFetcherImpl(this._settingsDataSource, this._audiotagger);
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
final Audiotagger _audiotagger;
|
2021-02-26 22:07:18 +01:00
|
|
|
final SettingsDataSource _settingsDataSource;
|
|
|
|
|
|
|
|
@override
|
2021-04-26 19:28:32 +02:00
|
|
|
Future<Map<String, List>> getLocalMusic() async {
|
|
|
|
final musicDirectories = await _settingsDataSource.getLibraryFolders();
|
|
|
|
final libDir = Directory(musicDirectories.first);
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
final List<SongModel> songs = [];
|
|
|
|
final List<AlbumModel> albums = [];
|
|
|
|
final Map<String, int> albumIdMap = {};
|
|
|
|
final Map<String, String> albumArtMap = {};
|
|
|
|
final List<ArtistModel> artists = [];
|
|
|
|
final Set<String> artistSet = {};
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
final Directory dir = await getApplicationSupportDirectory();
|
|
|
|
await for (final entity in libDir.list(recursive: true, followLinks: false)) {
|
|
|
|
if (entity is File && entity.path.endsWith('.mp3')) {
|
|
|
|
final tags = await _audiotagger.readTags(path: entity.path);
|
|
|
|
final audioFile = await _audiotagger.readAudioFile(path: entity.path);
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
final albumString = '${tags.album}___${tags.albumArtist}__${tags.year}';
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
int albumId;
|
|
|
|
String albumArtPath;
|
|
|
|
if (!albumIdMap.containsKey(albumString)) {
|
|
|
|
albumId = albumIdMap.length;
|
|
|
|
albumIdMap[albumString] = albumId;
|
|
|
|
|
|
|
|
final albumArt = await _audiotagger.readArtwork(path: entity.path);
|
|
|
|
|
|
|
|
if (albumArt != null && albumArt.isNotEmpty) {
|
|
|
|
albumArtPath = '${dir.path}/$albumId';
|
|
|
|
final file = File(albumArtPath);
|
|
|
|
file.writeAsBytesSync(albumArt);
|
|
|
|
albumArtMap[albumString] = albumArtPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
albums.add(
|
|
|
|
AlbumModel.fromAudiotagger(albumId: albumId, tag: tags, albumArtPath: albumArtPath),
|
|
|
|
);
|
2021-05-02 10:52:18 +02:00
|
|
|
artistSet.add(tags.albumArtist != '' ? tags.albumArtist : tags.artist);
|
2021-04-26 19:28:32 +02:00
|
|
|
} else {
|
|
|
|
albumId = albumIdMap[albumString];
|
|
|
|
albumArtPath = albumArtMap[albumString];
|
|
|
|
}
|
2021-02-26 22:07:18 +01:00
|
|
|
|
2021-04-26 19:28:32 +02:00
|
|
|
songs.add(
|
|
|
|
SongModel.fromAudiotagger(
|
|
|
|
path: entity.path,
|
|
|
|
tag: tags,
|
|
|
|
audioFile: audioFile,
|
|
|
|
albumId: albumId,
|
|
|
|
albumArtPath: albumArtPath,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (final artist in artistSet) {
|
|
|
|
artists.add(ArtistModel(name: artist));
|
|
|
|
}
|
2021-02-26 22:07:18 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
'SONGS': songs,
|
|
|
|
'ALBUMS': albums,
|
|
|
|
'ARTISTS': artists,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|