Fast Forward Moving Picture Experts Group Used

This commit is contained in:
Mike Phares 2024-10-30 17:33:36 -07:00
parent 924bd14c31
commit 2f75667f20
4 changed files with 54 additions and 45 deletions

View File

@ -31,17 +31,18 @@ internal static class Get
return new(results);
}
internal static Action<string> SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection)
internal static Action<string> SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(bool, FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection)
{
return file =>
{
rename.Tick();
FileInfo fileInfo;
FilePath? ffmpegFilePath;
ExifDirectory exifDirectory;
ReadOnlyCollection<string>? ffmpegFiles;
DeterministicHashCode deterministicHashCode;
FileHolder fileHolder = FileHolder.Get(file);
bool fastForwardMovingPictureExpertsGroupUsed;
FilePath? fastForwardMovingPictureExpertsGroupFilePath;
ReadOnlyCollection<string>? fastForwardMovingPictureExpertsGroupFiles;
FilePath filePath = FilePath.Get(renameConfiguration.MetadataConfiguration, fileHolder, index: null);
string key = $"{Path.Combine(fileHolder.DirectoryName ?? throw new NotSupportedException(), fileHolder.NameWithoutExtension)}";
if (distinct.Contains(key))
@ -50,22 +51,23 @@ internal static class Get
{
if (filePath.Id is not null)
{
ffmpegFiles = null;
fastForwardMovingPictureExpertsGroupFiles = null;
deterministicHashCode = new(null, filePath.Id, null);
}
else
{
ffmpegFiles = rename.ConvertAndGetFfmpegFiles(renameConfiguration, filePath);
ffmpegFilePath = ffmpegFiles.Count == 0 ? null : FilePath.Get(renameConfiguration.MetadataConfiguration, FileHolder.Get(ffmpegFiles[0]), index: null);
deterministicHashCode = ffmpegFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(ffmpegFilePath);
fastForwardMovingPictureExpertsGroupFiles = rename.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(renameConfiguration, filePath);
fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(renameConfiguration.MetadataConfiguration, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), index: null);
deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(fastForwardMovingPictureExpertsGroupFilePath);
}
fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0;
(fileInfo, exifDirectory) = metadata.GetMetadataCollection(renameConfiguration.MetadataConfiguration, filePath, deterministicHashCode);
lock (collection)
collection.Add(new(filePath, fileInfo, exifDirectory, new([])));
if (ffmpegFiles is not null)
collection.Add(new(fastForwardMovingPictureExpertsGroupUsed, filePath, fileInfo, exifDirectory, new([])));
if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null)
{
foreach (string ffmpegFile in ffmpegFiles)
File.Delete(ffmpegFile);
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
}
}

View File

@ -57,9 +57,9 @@ public interface IMetadata
static double? GetDistance(double originLatitude, double originLongitude, double destinationLatitude, double destinationLongitude, int decimalPlaces = 1, DistanceUnit distanceUnit = DistanceUnit.Miles) =>
GPS.GetDistance(originLatitude, originLongitude, destinationLatitude, destinationLongitude, decimalPlaces, distanceUnit);
Action<string> TestStatic_SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection) =>
Action<string> TestStatic_SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(bool, FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection) =>
SetExifDirectoryCollection(rename, renameConfiguration, metadata, distinct, collection);
static Action<string> SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection) =>
static Action<string> SetExifDirectoryCollection(IRename rename, IRenameConfiguration renameConfiguration, A_Metadata metadata, List<string> distinct, List<(bool, FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection) =>
Get.SetExifDirectoryCollection(rename, renameConfiguration, metadata, distinct, collection);
ReadOnlyDictionary<string, List<FileHolder>> TestStatic_GetKeyValuePairs(IEnumerable<string> files) =>

View File

@ -21,9 +21,9 @@ public partial class Rename : IRename, IDisposable
private sealed record ToDo(string? Directory, FilePath FilePath, string File, bool JsonFile);
private sealed record RecordA(ExifDirectory ExifDirectory, FileInfo FileInfo, FilePath FilePath, ReadOnlyCollection<FileHolder> SidecarFiles);
private sealed record RecordA(ExifDirectory ExifDirectory, bool FastForwardMovingPictureExpertsGroupUsed, FileInfo FileInfo, FilePath FilePath, ReadOnlyCollection<FileHolder> SidecarFiles);
private sealed record RecordB(DateTime DateTime, ExifDirectory ExifDirectory, FilePath FilePath, ReadOnlyCollection<FileHolder> SidecarFiles, bool HasDateTimeOriginal, bool HasIgnoreKeyword, string JsonFile);
private sealed record RecordB(DateTime DateTime, ExifDirectory ExifDirectory, bool FastForwardMovingPictureExpertsGroupUsed, FilePath FilePath, ReadOnlyCollection<FileHolder> SidecarFiles, bool HasDateTimeOriginal, bool HasIgnoreKeyword, string JsonFile);
private ProgressBar? _ProgressBar;
@ -49,7 +49,7 @@ public partial class Rename : IRename, IDisposable
GC.SuppressFinalize(this);
}
ReadOnlyCollection<string> IRename.ConvertAndGetFfmpegFiles(IRenameConfiguration renameConfiguration, FilePath filePath)
ReadOnlyCollection<string> IRename.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(IRenameConfiguration renameConfiguration, FilePath filePath)
{
List<string> results = [];
bool isValidVideoFormatExtensions = renameConfiguration.ValidVideoFormatExtensions.Contains(filePath.ExtensionLowered);
@ -117,7 +117,7 @@ public partial class Rename : IRename, IDisposable
#pragma warning restore CA1416
private void NonParallelismAndInPlace(RenameConfiguration renameConfiguration, ReadOnlyCollection<int> ids, ExifDirectory exifDirectory, FileInfo fileInfo, FilePath filePath, ReadOnlyCollection<FileHolder> sidecarFiles)
private void NonParallelismAndInPlace(RenameConfiguration renameConfiguration, ReadOnlyCollection<int> ids, ExifDirectory exifDirectory, FileInfo fileInfo, FilePath filePath, bool fastForwardMovingPictureExpertsGroupUsed, ReadOnlyCollection<FileHolder> sidecarFiles)
{
if (exifDirectory.Id is null)
throw new NotImplementedException();
@ -148,7 +148,7 @@ public partial class Rename : IRename, IDisposable
if (renameConfiguration.InPlace)
throw new NotSupportedException($"Must use {nameof(renameConfiguration.InPlaceWithOriginalName)} when sidecar file(s) are present!");
dateTime ??= IDate.GetMinimum(exifDirectory);
RecordB recordB = new(dateTime.Value, exifDirectory, filePath, sidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, fileInfo.FullName);
RecordB recordB = new(dateTime.Value, exifDirectory, fastForwardMovingPictureExpertsGroupUsed, filePath, sidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, fileInfo.FullName);
toDoCollection.AddRange(GetSidecarFiles(metadataConfiguration, recordB, [], checkDirectory, paddedId));
}
_ = RenameFilesInDirectories(renameConfiguration, new(toDoCollection));
@ -156,7 +156,8 @@ public partial class Rename : IRename, IDisposable
File.Move(fileInfo.FullName, jsonFile, overwrite: true);
if (renameConfiguration.InPlaceWithOriginalName && ids.Count > 0)
{
string idCheck = Path.Combine(checkDirectory, ids.Contains(exifDirectory.Id.Value) ? "_ Exists _" : "_ New _");
string contains = ids.Contains(exifDirectory.Id.Value) ? "_ Exists _" : "_ New _";
string idCheck = Path.Combine(checkDirectory, contains, fastForwardMovingPictureExpertsGroupUsed ? "Video" : "Image");
if (!Directory.Exists(idCheck))
_ = Directory.CreateDirectory(idCheck);
}
@ -169,11 +170,12 @@ public partial class Rename : IRename, IDisposable
int index = -1;
FileInfo fileInfo;
FilePath filePath;
FilePath? ffmpegFilePath;
ExifDirectory exifDirectory;
List<FileHolder> sidecarFiles;
ReadOnlyCollection<string>? ffmpegFiles;
DeterministicHashCode deterministicHashCode;
bool fastForwardMovingPictureExpertsGroupUsed;
FilePath? fastForwardMovingPictureExpertsGroupFilePath;
ReadOnlyCollection<string>? fastForwardMovingPictureExpertsGroupFiles;
ReadOnlyDictionary<string, List<FileHolder>> keyValuePairs = IMetadata.GetKeyValuePairs(files);
foreach (KeyValuePair<string, List<FileHolder>> keyValuePair in keyValuePairs)
{
@ -194,16 +196,16 @@ public partial class Rename : IRename, IDisposable
continue;
if (!renameConfiguration.ForceNewId && filePath.Id is not null)
{
ffmpegFiles = null;
fastForwardMovingPictureExpertsGroupFiles = null;
deterministicHashCode = new(null, filePath.Id, null);
if (renameConfiguration.InPlaceWithOriginalName || (renameConfiguration.InPlace && filePath.DirectoryName.EndsWith(filePath.Id.Value.ToString())))
continue;
}
else
{
ffmpegFiles = rename.ConvertAndGetFfmpegFiles(renameConfiguration, filePath);
ffmpegFilePath = ffmpegFiles.Count == 0 ? null : FilePath.Get(renameConfiguration.MetadataConfiguration, FileHolder.Get(ffmpegFiles[0]), index);
deterministicHashCode = ffmpegFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(ffmpegFilePath);
fastForwardMovingPictureExpertsGroupFiles = rename.ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(renameConfiguration, filePath);
fastForwardMovingPictureExpertsGroupFilePath = fastForwardMovingPictureExpertsGroupFiles.Count == 0 ? null : FilePath.Get(renameConfiguration.MetadataConfiguration, FileHolder.Get(fastForwardMovingPictureExpertsGroupFiles[0]), index);
deterministicHashCode = fastForwardMovingPictureExpertsGroupFilePath is null ? rename.GetDeterministicHashCode(filePath) : rename.GetDeterministicHashCode(fastForwardMovingPictureExpertsGroupFilePath);
}
sidecarFiles = [];
for (int i = 0; i < keyValuePair.Value.Count; i++)
@ -219,14 +221,15 @@ public partial class Rename : IRename, IDisposable
logger?.LogWarning("<{filePath}>", filePath.FullName);
continue;
}
if (ffmpegFiles is not null)
fastForwardMovingPictureExpertsGroupUsed = fastForwardMovingPictureExpertsGroupFiles is not null && fastForwardMovingPictureExpertsGroupFiles.Count > 0;
if (fastForwardMovingPictureExpertsGroupUsed && fastForwardMovingPictureExpertsGroupFiles is not null)
{
foreach (string ffmpegFile in ffmpegFiles)
File.Delete(ffmpegFile);
foreach (string fastForwardMovingPictureExpertsGroupFile in fastForwardMovingPictureExpertsGroupFiles)
File.Delete(fastForwardMovingPictureExpertsGroupFile);
}
if (renameConfiguration.InPlace || renameConfiguration.InPlaceWithOriginalName)
NonParallelismAndInPlace(renameConfiguration, ids, exifDirectory, fileInfo, filePath, new(sidecarFiles));
results.Add(new(exifDirectory, fileInfo, filePath, new(sidecarFiles)));
NonParallelismAndInPlace(renameConfiguration, ids, exifDirectory, fileInfo, filePath, fastForwardMovingPictureExpertsGroupUsed, new(sidecarFiles));
results.Add(new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, fileInfo, filePath, new(sidecarFiles)));
}
}
return results;
@ -246,7 +249,7 @@ public partial class Rename : IRename, IDisposable
dateTime ??= IDate.GetMinimum(recordA.ExifDirectory);
keywords = IMetadata.GetKeywords(recordA.ExifDirectory);
hasIgnoreKeyword = metadataConfiguration.IgnoreRulesKeyWords.Any(l => keywords.Contains(l));
results.Add(new(dateTime.Value, recordA.ExifDirectory, recordA.FilePath, recordA.SidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, recordA.FileInfo.FullName));
results.Add(new(dateTime.Value, recordA.ExifDirectory, recordA.FastForwardMovingPictureExpertsGroupUsed, recordA.FilePath, recordA.SidecarFiles, hasDateTimeOriginal, hasIgnoreKeyword, recordA.FileInfo.FullName));
}
return new(results);
}
@ -266,13 +269,13 @@ public partial class Rename : IRename, IDisposable
else
{
List<string> distinct = [];
List<(FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection = [];
List<(bool, FilePath, FileInfo, ExifDirectory, ReadOnlyCollection<FileHolder>)> collection = [];
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = appSettingsMaxDegreeOfParallelism };
files.AsParallel().ForAll(IMetadata.SetExifDirectoryCollection(rename, renameConfiguration, metadata, distinct, collection));
if (_ProgressBar.CurrentTick != recordACollection.Count)
throw new NotSupportedException();
foreach ((FilePath filePath, FileInfo fileInfo, ExifDirectory exifDirectory, ReadOnlyCollection<FileHolder> sidecarFiles) in collection)
recordACollection.Add(new(exifDirectory, fileInfo, filePath, sidecarFiles));
foreach ((bool fastForwardMovingPictureExpertsGroupUsed, FilePath filePath, FileInfo fileInfo, ExifDirectory exifDirectory, ReadOnlyCollection<FileHolder> sidecarFiles) in collection)
recordACollection.Add(new(exifDirectory, fastForwardMovingPictureExpertsGroupUsed, fileInfo, filePath, sidecarFiles));
}
_ProgressBar.Dispose();
results = GetRecordBCollection(renameConfiguration.MetadataConfiguration, recordACollection);
@ -281,32 +284,36 @@ public partial class Rename : IRename, IDisposable
private static void VerifyIntMinValueLength(MetadataConfiguration metadataConfiguration, ReadOnlyCollection<RecordB> recordBCollection)
{
foreach ((DateTime _, ExifDirectory exifDirectory, FilePath _, ReadOnlyCollection<FileHolder> _, bool _, bool _, string _) in recordBCollection)
foreach (RecordB recordB in recordBCollection)
{
if (exifDirectory.Id is null)
if (recordB.ExifDirectory.Id is null)
continue;
if (metadataConfiguration.IntMinValueLength < exifDirectory.Id.Value.ToString().Length)
if (metadataConfiguration.IntMinValueLength < recordB.ExifDirectory.Id.Value.ToString().Length)
throw new NotSupportedException();
}
}
private static string? GetCheckDirectory(RenameConfiguration renameConfiguration, RecordB record, FilePath filePath, ReadOnlyCollection<int> ids, bool multipleDirectoriesWithFiles)
private static string? GetCheckDirectory(RenameConfiguration renameConfiguration, RecordB record, ReadOnlyCollection<int> ids, bool multipleDirectoriesWithFiles)
{
string? result;
if (filePath.DirectoryName is null)
throw new NullReferenceException(nameof(filePath.DirectoryName));
if (record.FilePath.DirectoryName is null)
throw new NullReferenceException(nameof(record.FilePath.DirectoryName));
string year = record.DateTime.Year.ToString();
string checkDirectoryName = Path.GetFileName(filePath.DirectoryName);
string checkDirectoryName = Path.GetFileName(record.FilePath.DirectoryName);
if (multipleDirectoriesWithFiles && !checkDirectoryName.Contains(year))
result = null;
else
{
string? maker = IMetadata.GetMaker(record.ExifDirectory);
string hasDateTimeOriginal = record.HasDateTimeOriginal ? "Has" : "Not";
(int seasonValue, string seasonName) = IDate.GetSeason(record.DateTime.DayOfYear);
string splat = filePath.DirectoryName[^3..][1] == '!' ? filePath.DirectoryName[^3..] : string.Empty;
string rootDirectory = renameConfiguration.MetadataConfiguration.ResultConfiguration.RootDirectory;
string splat = record.FilePath.DirectoryName[^3..][1] == '!' ? record.FilePath.DirectoryName[^3..] : string.Empty;
string fastForwardMovingPictureExpertsGroupUsed = record.FastForwardMovingPictureExpertsGroupUsed ? "Video" : "Image";
string contains = record.ExifDirectory.Id is null || ids.Contains(record.ExifDirectory.Id.Value) ? "_ Exists _" : "_ New-Destination _";
string makerSplit = string.IsNullOrEmpty(maker) ? string.IsNullOrEmpty(renameConfiguration.DefaultMaker) ? string.Empty : renameConfiguration.DefaultMaker : $" {maker.Split(' ')[0]}";
string directoryName = $"{year}.{seasonValue} {seasonName}{makerSplit}{splat}";
result = Path.Combine(renameConfiguration.MetadataConfiguration.ResultConfiguration.RootDirectory, record.ExifDirectory.Id is null || ids.Contains(record.ExifDirectory.Id.Value) ? "_ Exists _" : "_ New-Destination _", record.HasDateTimeOriginal ? "Has" : "Not", directoryName);
result = Path.Combine(rootDirectory, contains, fastForwardMovingPictureExpertsGroupUsed, hasDateTimeOriginal, directoryName);
}
return result;
}
@ -385,7 +392,7 @@ public partial class Rename : IRename, IDisposable
continue;
if (record.FilePath.DirectoryName is null)
continue;
checkDirectory = GetCheckDirectory(renameConfiguration, record, record.FilePath, ids, multipleDirectoriesWithFiles);
checkDirectory = GetCheckDirectory(renameConfiguration, record, ids, multipleDirectoriesWithFiles);
if (string.IsNullOrEmpty(checkDirectory))
continue;
checkFileExtension = record.FilePath.ExtensionLowered == jpeg ? jpg : record.FilePath.ExtensionLowered;

View File

@ -6,7 +6,7 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IRename
{
ReadOnlyCollection<string> ConvertAndGetFfmpegFiles(IRenameConfiguration renameConfiguration, FilePath filePath);
ReadOnlyCollection<string> ConvertAndGetFastForwardMovingPictureExpertsGroupFiles(IRenameConfiguration renameConfiguration, FilePath filePath);
DeterministicHashCode GetDeterministicHashCode(FilePath filePath);
void Tick();