-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFrameExtractor.cs
More file actions
42 lines (34 loc) · 1.27 KB
/
Copy pathFrameExtractor.cs
File metadata and controls
42 lines (34 loc) · 1.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using FFMpegCore;
using FFMpegCore.Pipes;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace SubtitleExtractor;
public sealed class FrameExtractor
{
public async IAsyncEnumerable<(TimeSpan Timestamp, Image<Rgba32> Frame)> ExtractAsync(
string videoPath,
double fps)
{
var options = new FFOptions() { BinaryFolder = "c:\\Tools\\" };
var mediaInfo = await FFProbe.AnalyseAsync(videoPath, options);
double duration = mediaInfo.Duration.TotalSeconds;
double interval = 1.0 / fps;
for (double t = 0; t < duration; t += interval)
{
var timestamp = TimeSpan.FromSeconds(t);
using var ms = new MemoryStream();
var sink = new StreamPipeSink(ms);
await FFMpegArguments
.FromFileInput(videoPath, false, o => o.Seek(timestamp))
.OutputToPipe(sink, o => o
.WithVideoCodec("png")
.ForceFormat("image2pipe")
.WithFrameOutputCount(1))
.ProcessAsynchronously(true, options);
ms.Position = 0;
if (ms.Length == 0) continue;
var image = Image.Load<Rgba32>(ms);
yield return (timestamp, image);
}
}
}