Skip to content

Commit

Permalink
Load audio metadata in an isolate (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier authored Jun 25, 2023
1 parent 6cf0f02 commit eb62bb5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 54 deletions.
2 changes: 0 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:flutter/material.dart';
import 'package:media_kit/media_kit.dart';
import 'package:metadata_god/metadata_god.dart';
import 'package:mpris_service/mpris_service.dart';
import 'package:musicpod/app/common/constants.dart';
import 'package:musicpod/musicpod.dart';
Expand All @@ -18,7 +17,6 @@ Future<void> main() async {
await YaruWindowTitleBar.ensureInitialized();
WidgetsFlutterBinding.ensureInitialized();
MediaKit.ensureInitialized();
MetadataGod.initialize();

final mpris = await MPRIS.create(
busName: 'org.mpris.MediaPlayer2.musicpod',
Expand Down
121 changes: 69 additions & 52 deletions lib/service/local_audio_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:metadata_god/metadata_god.dart';
import 'package:mime_type/mime_type.dart';
import 'package:musicpod/app/common/constants.dart';
Expand Down Expand Up @@ -38,69 +39,85 @@ class LocalAudioService {
_audiosController.add(true);
}

final _failedImports = <String>[];
Future<List<String>> init() async {
_failedImports.clear();
_directory = await readSetting(kDirectoryProperty);
_directory ??= getUserDirectory('MUSIC')?.path;

if (_directory != null) {
final allFileSystemEntities = Set<FileSystemEntity>.from(
await _getFlattenedFileSystemEntities(path: directory!),
);
final result = await compute(_init, directory);

final onlyFiles = <FileSystemEntity>[];
_audios = result.$2;

for (var fileSystemEntity in allFileSystemEntities) {
if (!await FileSystemEntity.isDirectory(fileSystemEntity.path) &&
_validType(fileSystemEntity.path)) {
onlyFiles.add(fileSystemEntity);
}
_audiosController.add(true);
_directoryController.add(true);

return result.$1;
}
}

FutureOr<(List<String>, Set<Audio>?)> _init(String? directory) async {
MetadataGod.initialize();

Set<Audio>? newAudios;
List<String> failedImports = [];

if (directory != null) {
newAudios = {};

final allFileSystemEntities = Set<FileSystemEntity>.from(
await _getFlattenedFileSystemEntities(path: directory),
);

final onlyFiles = <FileSystemEntity>[];

for (var fileSystemEntity in allFileSystemEntities) {
if (!await FileSystemEntity.isDirectory(fileSystemEntity.path) &&
_validType(fileSystemEntity.path)) {
onlyFiles.add(fileSystemEntity);
}
}
for (var e in onlyFiles) {
try {
final metadata = await MetadataGod.readMetadata(file: e.path);
final audio = _createAudio(e.path, metadata);

audios = {};
for (var e in onlyFiles) {
try {
final metadata = await MetadataGod.readMetadata(file: e.path);

final audio = Audio(
path: e.path,
audioType: AudioType.local,
artist: metadata.artist ?? '',
title: metadata.title ?? e.path,
album: metadata.album == null
? ''
: '${metadata.album} ${metadata.discTotal != null && metadata.discTotal! > 1 ? metadata.discNumber : ''}',
albumArtist: metadata.albumArtist,
discNumber: metadata.discNumber,
discTotal: metadata.discTotal,
durationMs: metadata.durationMs,
fileSize: metadata.fileSize,
genre: metadata.genre,
pictureData: metadata.picture?.data,
pictureMimeType: metadata.picture?.mimeType,
trackNumber: metadata.trackNumber,
year: metadata.year,
);

audios?.add(audio);
} catch (error) {
_failedImports.add(e.path);
}
newAudios.add(audio);
} catch (error) {
failedImports.add(e.path);
}
}
_audiosController.add(true);
_directoryController.add(true);
return _failedImports;
}

bool _validType(String path) => mime(path)?.contains('audio') ?? false;
return (failedImports, newAudios);
}

Future<List<FileSystemEntity>> _getFlattenedFileSystemEntities({
required String path,
}) async {
return await Directory(path)
.list(recursive: true, followLinks: false)
.toList();
}
Audio _createAudio(String path, Metadata metadata) {
return Audio(
path: path,
audioType: AudioType.local,
artist: metadata.artist ?? '',
title: metadata.title ?? path,
album: metadata.album == null
? ''
: '${metadata.album} ${metadata.discTotal != null && metadata.discTotal! > 1 ? metadata.discNumber : ''}',
albumArtist: metadata.albumArtist,
discNumber: metadata.discNumber,
discTotal: metadata.discTotal,
durationMs: metadata.durationMs,
fileSize: metadata.fileSize,
genre: metadata.genre,
pictureData: metadata.picture?.data,
pictureMimeType: metadata.picture?.mimeType,
trackNumber: metadata.trackNumber,
year: metadata.year,
);
}

bool _validType(String path) => mime(path)?.contains('audio') ?? false;

Future<List<FileSystemEntity>> _getFlattenedFileSystemEntities({
required String path,
}) async {
return await Directory(path)
.list(recursive: true, followLinks: false)
.toList();
}

0 comments on commit eb62bb5

Please sign in to comment.