Convert all images to webp

This commit is contained in:
Kieran 2023-01-30 18:35:36 +00:00
parent dc0199a3d6
commit e193127358
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
4 changed files with 73 additions and 56 deletions

View File

@ -0,0 +1,65 @@
using FFMpegCore;
namespace VoidCat.Services.Files;
/// <summary>
/// Service which utilizes ffmpeg to strip metadata from media
/// and compress media to reduce storage costs
/// </summary>
public class CompressContent
{
private readonly ILogger<CompressContent> _logger;
public CompressContent(ILogger<CompressContent> logger)
{
_logger = logger;
}
public async Task<CompressResult> 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; }
}
}

View File

@ -10,7 +10,7 @@ public static class FileStorageStartup
{ {
services.AddTransient<FileInfoManager>(); services.AddTransient<FileInfoManager>();
services.AddTransient<FileStoreFactory>(); services.AddTransient<FileStoreFactory>();
services.AddTransient<StripMetadata>(); services.AddTransient<CompressContent>();
if (settings.CloudStorage != default) if (settings.CloudStorage != default)
{ {

View File

@ -10,9 +10,9 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
{ {
private const string FilesDir = "files-v1"; private const string FilesDir = "files-v1";
private readonly VoidSettings _settings; 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) : base(stats)
{ {
_settings = settings; _settings = settings;
@ -58,9 +58,10 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
File.Move(finalPath, srcPath); File.Move(finalPath, srcPath);
var dstPath = $"{finalPath}_dst{ext}"; 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); File.Delete(srcPath);
// recompute metadata // recompute metadata
@ -71,7 +72,8 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
Metadata = vf.Metadata! with Metadata = vf.Metadata! with
{ {
Size = (ulong)fInfo.Length, Size = (ulong)fInfo.Length,
Digest = hash.ToHex() Digest = hash.ToHex(),
MimeType = res.MimeType ?? vf.Metadata.MimeType
} }
}; };
} }

View File

@ -1,50 +0,0 @@
using FFMpegCore;
using FFMpegCore.Enums;
using FFMpegCore.Pipes;
using Newtonsoft.Json;
namespace VoidCat.Services.Files;
/// <summary>
/// Service which utilizes ffmpeg to strip metadata from media
/// </summary>
public class StripMetadata
{
private readonly ILogger<StripMetadata> _logger;
public StripMetadata(ILogger<StripMetadata> logger)
{
_logger = logger;
}
public async Task<bool> 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;
}
}