Libation/Source/LibationFileManager/AudioFileLocator.cs
2023-02-10 09:35:21 -07:00

61 lines
1.5 KiB
C#

using AAXClean;
using Dinah.Core;
using FileManager;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace LibationFileManager
{
public static class AudioFileLocator
{
private static EnumerationOptions enumerationOptions { get; } = new()
{
RecurseSubdirectories = true,
IgnoreInaccessible = true,
MatchCasing = MatchCasing.CaseInsensitive
};
public static async IAsyncEnumerable<FilePathCache.CacheEntry> FindAudiobooks(LongPath searchDirectory, [EnumeratorCancellation] CancellationToken cancellationToken)
{
ArgumentValidator.EnsureNotNull(searchDirectory, nameof(searchDirectory));
foreach (LongPath path in Directory.EnumerateFiles(searchDirectory, "*.M4B", enumerationOptions))
{
if (cancellationToken.IsCancellationRequested)
yield break;
int generation = 0;
FilePathCache.CacheEntry audioFile = default;
try
{
using var fileStream = File.OpenRead(path);
var mp4File = await Task.Run(() => new Mp4File(fileStream), cancellationToken);
generation = GC.GetGeneration(mp4File);
if (mp4File?.AppleTags?.Asin is not null)
audioFile = new FilePathCache.CacheEntry(mp4File.AppleTags.Asin, FileType.Audio, path);
}
catch(Exception ex)
{
Serilog.Log.Error(ex, "Error checking for asin in {@file}", path);
}
finally
{
GC.Collect(generation);
}
if (audioFile is not null)
yield return audioFile;
}
}
}
}