diff --git a/VoidCat/Services/Files/CompressContent.cs b/VoidCat/Services/Files/CompressContent.cs
new file mode 100644
index 0000000..cf79e34
--- /dev/null
+++ b/VoidCat/Services/Files/CompressContent.cs
@@ -0,0 +1,65 @@
+using FFMpegCore;
+
+namespace VoidCat.Services.Files;
+
+///
+/// Service which utilizes ffmpeg to strip metadata from media
+/// and compress media to reduce storage costs
+///
+public class CompressContent
+{
+ private readonly ILogger _logger;
+
+ public CompressContent(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ public async Task TryCompressMedia(string input, string output, CancellationToken cts)
+ {
+ try
+ {
+ string? outMime = null;
+ switch (Path.GetExtension(input))
+ {
+ case ".jpg":
+ case ".jpeg":
+ case ".gif":
+ case ".png":
+ case ".bmp":
+ case ".tiff":
+ {
+ output = Path.ChangeExtension(output, ".webp");
+ outMime = "image/webp";
+ break;
+ }
+ }
+
+ var ffmpeg = FFMpegArguments
+ .FromFileInput(input)
+ .OutputToFile(output, true, o =>
+ {
+ o.WithoutMetadata();
+ })
+ .CancellableThrough(cts);
+
+ _logger.LogInformation("Running: {command}", ffmpeg.Arguments);
+ var result = await ffmpeg.ProcessAsynchronously();
+ return new(result, output)
+ {
+ MimeType = outMime
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Could not strip metadata");
+ }
+
+ return new(false, output);
+ }
+
+ public record CompressResult(bool Success, string OutPath)
+ {
+ public string? MimeType { get; init; }
+ }
+}
diff --git a/VoidCat/Services/Files/FileStorageStartup.cs b/VoidCat/Services/Files/FileStorageStartup.cs
index 889f446..d0dd16e 100644
--- a/VoidCat/Services/Files/FileStorageStartup.cs
+++ b/VoidCat/Services/Files/FileStorageStartup.cs
@@ -10,7 +10,7 @@ public static class FileStorageStartup
{
services.AddTransient();
services.AddTransient();
- services.AddTransient();
+ services.AddTransient();
if (settings.CloudStorage != default)
{
diff --git a/VoidCat/Services/Files/LocalDiskFileStorage.cs b/VoidCat/Services/Files/LocalDiskFileStorage.cs
index 6554d97..2748727 100644
--- a/VoidCat/Services/Files/LocalDiskFileStorage.cs
+++ b/VoidCat/Services/Files/LocalDiskFileStorage.cs
@@ -10,9 +10,9 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
{
private const string FilesDir = "files-v1";
private readonly VoidSettings _settings;
- private readonly StripMetadata _stripMetadata;
+ private readonly CompressContent _stripMetadata;
- public LocalDiskFileStore(VoidSettings settings, IAggregateStatsCollector stats, StripMetadata stripMetadata)
+ public LocalDiskFileStore(VoidSettings settings, IAggregateStatsCollector stats, CompressContent stripMetadata)
: base(stats)
{
_settings = settings;
@@ -58,9 +58,10 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
File.Move(finalPath, srcPath);
var dstPath = $"{finalPath}_dst{ext}";
- if (await _stripMetadata.TryStripMediaMetadata(srcPath, dstPath, cts))
+ var res = await _stripMetadata.TryCompressMedia(srcPath, dstPath, cts);
+ if (res.Success)
{
- File.Move(dstPath, finalPath);
+ File.Move(res.OutPath, finalPath);
File.Delete(srcPath);
// recompute metadata
@@ -71,7 +72,8 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
Metadata = vf.Metadata! with
{
Size = (ulong)fInfo.Length,
- Digest = hash.ToHex()
+ Digest = hash.ToHex(),
+ MimeType = res.MimeType ?? vf.Metadata.MimeType
}
};
}
diff --git a/VoidCat/Services/Files/StripMetadata.cs b/VoidCat/Services/Files/StripMetadata.cs
deleted file mode 100644
index a21aff4..0000000
--- a/VoidCat/Services/Files/StripMetadata.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using FFMpegCore;
-using FFMpegCore.Enums;
-using FFMpegCore.Pipes;
-using Newtonsoft.Json;
-
-namespace VoidCat.Services.Files;
-
-///
-/// Service which utilizes ffmpeg to strip metadata from media
-///
-public class StripMetadata
-{
- private readonly ILogger _logger;
-
- public StripMetadata(ILogger logger)
- {
- _logger = logger;
- }
-
- public async Task TryStripMediaMetadata(string input, string output, CancellationToken cts)
- {
- try
- {
- var ffprobe = await FFProbe.AnalyseAsync(input, cancellationToken: cts);
- if (ffprobe == default)
- {
- throw new InvalidOperationException("Could not determine media type with ffprobe");
- }
-
- _logger.LogInformation("Stripping content from {type}", ffprobe.Format.FormatName);
-
- var ffmpeg = FFMpegArguments
- .FromFileInput(input)
- .OutputToFile(output, true, o =>
- {
- o.WithoutMetadata();
- })
- .CancellableThrough(cts);
-
- _logger.LogInformation("Running: {command}", ffmpeg.Arguments);
- return await ffmpeg.ProcessAsynchronously();
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Could not strip metadata");
- }
-
- return false;
- }
-}