scanAudioFiles function

Future<List<String>> scanAudioFiles(
  1. String root, {
  2. required Future<List<String>> list(
    1. String path
    ),
  3. required Future<bool> isDirectory(
    1. String path
    ),
  4. void onProgress(
    1. int checked
    )?,
  5. int maxDepth = 32,
})

Recursively finds audio files under root, sorted by path.

list and isDirectory are injected so the scan goes through Lumide's permission-checked file system. Hidden entries are skipped, and entries with an audio extension are assumed to be files, which saves a round trip per track. onProgress is called every 50 entries.

Implementation

Future<List<String>> scanAudioFiles(
  String root, {
  required Future<List<String>> Function(String path) list,
  required Future<bool> Function(String path) isDirectory,
  void Function(int checked)? onProgress,
  int maxDepth = 32,
}) async {
  final found = <String>[];
  var checked = 0;

  Future<void> visit(String dir, int depth) async {
    for (final entry in await list(dir)) {
      if (p.basename(entry).startsWith('.')) continue;
      checked++;
      if (onProgress != null && checked % 50 == 0) onProgress(checked);

      if (isAudioFile(entry)) {
        found.add(entry);
      } else if (depth < maxDepth && await isDirectory(entry)) {
        await visit(entry, depth + 1);
      }
    }
  }

  await visit(root, 0);
  found.sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
  return found;
}