src/Cli/Program.cs
+13
-4
diff --git a/src/Cli/Program.cs b/src/Cli/Program.cs
index 297b471..c04afa7 100644
@@ -1,4 +1,5 @@
using System.Threading;
using System;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Slopper.Domain;
@@ -16,8 +17,16 @@ using var app = builder.Build();
await app.StartAsync(CancellationToken.None);
using var scope = app.Services.CreateScope();
var clipGenerator = scope.ServiceProvider.GetRequiredService<ClipGenerator>();
await clipGenerator.Generate(CancellationToken.None);
// using var scope = app.Services.CreateScope();
// var clipGenerator = scope.ServiceProvider.GetRequiredService<ClipGenerator>();
// await clipGenerator.Generate(CancellationToken.None);
var clipExtractor = app.Services.GetRequiredService<IClipExtractor>();
await clipExtractor.ExtractClip(
new(Guid.NewGuid(), args[0], new Subtitles.Embedded(2)),
TimeSpan.FromSeconds(11),
TimeSpan.FromSeconds(2),
args[1],
CancellationToken.None
);
await app.StopAsync(CancellationToken.None);
src/Cli/packages.lock.json
+0
-6
diff --git a/src/Cli/packages.lock.json b/src/Cli/packages.lock.json
index 5238b59..f8c58ac 100644
@@ -38,12 +38,6 @@
"Microsoft.Extensions.Options": "11.0.0-preview.3.26207.106"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[11.0.0-preview.2.26159.112, )",
"resolved": "11.0.0-preview.2.26159.112",
"contentHash": "TnwQtmgvXJ+Moj8F0X41gNiLvXvBjYuWycwC0BUlYM3NHP0jzBAe8jWGuxlPNxh/XGDA7oOcwcpTLGcVJNwOYQ=="
},
"Instances": {
"type": "Transitive",
"resolved": "3.0.2",
src/Domain/packages.lock.json
+0
-6
diff --git a/src/Domain/packages.lock.json b/src/Domain/packages.lock.json
index 9890edc..a63ab9a 100644
@@ -46,12 +46,6 @@
"Microsoft.Extensions.Primitives": "11.0.0-preview.3.26207.106"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[11.0.0-preview.2.26159.112, )",
"resolved": "11.0.0-preview.2.26159.112",
"contentHash": "TnwQtmgvXJ+Moj8F0X41gNiLvXvBjYuWycwC0BUlYM3NHP0jzBAe8jWGuxlPNxh/XGDA7oOcwcpTLGcVJNwOYQ=="
},
"Microsoft.Extensions.Configuration": {
"type": "Transitive",
"resolved": "11.0.0-preview.3.26207.106",
src/Infrastructure/Ai/packages.lock.json
+0
-6
diff --git a/src/Infrastructure/Ai/packages.lock.json b/src/Infrastructure/Ai/packages.lock.json
index a2eb8c9..17984d4 100644
@@ -35,12 +35,6 @@
"Microsoft.Extensions.Options": "11.0.0-preview.3.26207.106"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[11.0.0-preview.2.26159.112, )",
"resolved": "11.0.0-preview.2.26159.112",
"contentHash": "TnwQtmgvXJ+Moj8F0X41gNiLvXvBjYuWycwC0BUlYM3NHP0jzBAe8jWGuxlPNxh/XGDA7oOcwcpTLGcVJNwOYQ=="
},
"OllamaSharp": {
"type": "Direct",
"requested": "[5.4.25, )",
src/Infrastructure/Database/packages.lock.json
+0
-6
diff --git a/src/Infrastructure/Database/packages.lock.json b/src/Infrastructure/Database/packages.lock.json
index 70b819b..bf3436e 100644
@@ -66,12 +66,6 @@
"Microsoft.Extensions.Logging.Abstractions": "11.0.0-preview.3.26207.106"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[11.0.0-preview.2.26159.112, )",
"resolved": "11.0.0-preview.2.26159.112",
"contentHash": "TnwQtmgvXJ+Moj8F0X41gNiLvXvBjYuWycwC0BUlYM3NHP0jzBAe8jWGuxlPNxh/XGDA7oOcwcpTLGcVJNwOYQ=="
},
"Humanizer.Core": {
"type": "Transitive",
"resolved": "2.14.1",
src/Infrastructure/Ffmpeg/ClipExtractor.cs
+22
-3
diff --git a/src/Infrastructure/Ffmpeg/ClipExtractor.cs b/src/Infrastructure/Ffmpeg/ClipExtractor.cs
index 29baba5..13c958d 100644
@@ -85,6 +85,7 @@ internal sealed partial class ClipExtractor(ILogger<ClipExtractor> logger) : ICl
CancellationToken cancellationToken
)
{
var subtitleOptions = await CreateSubtitleOptions(media, cancellationToken);
var args = FFMpegArguments
.FromFileInput(media.Path)
.OutputToFile(
@@ -109,7 +110,7 @@ internal sealed partial class ClipExtractor(ILogger<ClipExtractor> logger) : ICl
.Add("[blurred]crop", "1080:1920:(iw - 1080) / 2:0[cropped]")
.Add("[cropped][sharp]overlay", "0:(H - h) / 2");
filter.HardBurnSubtitle(CreateSubtitleOptions(media));
filter.HardBurnSubtitle(subtitleOptions);
})
.WithFastStart()
.WithVideoCodec(VideoCodec.LibX264)
@@ -124,18 +125,36 @@ internal sealed partial class ClipExtractor(ILogger<ClipExtractor> logger) : ICl
await args.ProcessAsynchronously();
}
private static SubtitleHardBurnOptions CreateSubtitleOptions(MediaItem media) =>
private async Task<SubtitleHardBurnOptions> CreateSubtitleOptions(
MediaItem media,
CancellationToken cancellationToken
) =>
(
media.Subtitles switch
{
Subtitles.External(var path) => SubtitleHardBurnOptions.Create(path),
Subtitles.Embedded(var index) => SubtitleHardBurnOptions.Create(media.Path).SetSubtitleIndex(index),
Subtitles.Embedded(var index) => await CreateEmbeddedSubtitleOptions(
media.Path,
index,
cancellationToken
),
_ => throw new ArgumentException("Unknown subtitle type"),
}
).WithParameter(
"force_style",
"FontSize=10,BorderStyle=1,Alignment=2,MarginV=80,PrimaryColour=&HFFFFFF&,BackColour=&H000000&"
);
private async Task<SubtitleHardBurnOptions> CreateEmbeddedSubtitleOptions(
string path,
int index,
CancellationToken cancellationToken
)
{
var analysis = await FFProbe.AnalyseAsync(path, cancellationToken: cancellationToken);
var subIndex = analysis.SubtitleStreams.Count(s => s.Index < index);
return SubtitleHardBurnOptions.Create(path).SetSubtitleIndex(subIndex);
}
}
file static class Extensions
src/Infrastructure/Ffmpeg/SubtitleReader.cs
+1
-2
diff --git a/src/Infrastructure/Ffmpeg/SubtitleReader.cs b/src/Infrastructure/Ffmpeg/SubtitleReader.cs
index f93c807..369fd05 100644
@@ -4,7 +4,6 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using FFMpegCore;
using FFMpegCore.Enums;
using FFMpegCore.Pipes;
using Microsoft.Extensions.Logging;
using Slopper.Domain;
@@ -35,7 +34,7 @@ internal sealed class SubtitleReader(ILogger<SubtitleReader> logger) : ISubtitle
.FromFileInput(path)
.OutputToPipe(
new StreamPipeSink(stream),
addArguments: options => options.SelectStream(index, channel: Channel.Subtitle).ForceFormat("srt")
addArguments: options => options.SelectStream(index).ForceFormat("srt")
);
logger.LogInformation("Running ffmpeg {FfmpegArguments}", args.Arguments);
await args.ProcessAsynchronously();
src/Infrastructure/Ffmpeg/packages.lock.json
+0
-6
diff --git a/src/Infrastructure/Ffmpeg/packages.lock.json b/src/Infrastructure/Ffmpeg/packages.lock.json
index a4a12f4..72c0e1e 100644
@@ -26,12 +26,6 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "11.0.0-preview.3.26207.106"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[11.0.0-preview.2.26159.112, )",
"resolved": "11.0.0-preview.2.26159.112",
"contentHash": "TnwQtmgvXJ+Moj8F0X41gNiLvXvBjYuWycwC0BUlYM3NHP0jzBAe8jWGuxlPNxh/XGDA7oOcwcpTLGcVJNwOYQ=="
},
"SubtitlesParserV2": {
"type": "Direct",
"requested": "[2.4.0, )",