Files
dotnet-local-transcription/index.cs
T

97 lines
2.5 KiB
C#
Raw Normal View History

2025-08-08 12:15:38 -05:00
#:property BuiltInComInteropSupport=true
#:package FFMpegCore@5.2.0
#:package NAudio@2.2.1
#:package Whisper.net.AllRuntimes@1.8.1
using FFMpegCore;
using FFMpegCore.Enums;
using NAudio.Wave;
using Whisper.net;
using Whisper.net.Ggml;
if (args.Length == 0)
{
Console.WriteLine("Please provide the path to the video file.");
return;
}
var videoPath = args[0];
if (File.Exists(videoPath) is false)
{
Console.WriteLine("File does not exist: " + videoPath);
return;
}
2026-01-06 14:15:46 -06:00
var tempWavPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.wav");
2025-08-08 12:15:38 -05:00
2026-01-06 14:15:46 -06:00
try
2025-08-08 12:15:38 -05:00
{
2026-01-06 14:15:46 -06:00
await FFMpegArguments
.FromFileInput(videoPath)
.OutputToFile(tempWavPath, true, options => options
.DisableChannel(Channel.Video)
.ForceFormat("wav")
.WithAudioSamplingRate(16000)
)
.ProcessAsynchronously();
2025-08-08 12:15:38 -05:00
2026-01-06 14:15:46 -06:00
using var waveReader = new WaveFileReader(tempWavPath);
var segmentDuration = TimeSpan.FromMinutes(2);
var totalDuration = waveReader.TotalTime;
var numOfSegments = (int)Math.Ceiling(totalDuration.TotalSeconds / segmentDuration.TotalSeconds);
2025-08-08 12:15:38 -05:00
using var processor = await GetProcessor();
2026-01-06 14:15:46 -06:00
foreach (var i in Enumerable.Range(0, numOfSegments))
2025-08-08 12:15:38 -05:00
{
2026-01-06 14:15:46 -06:00
using var segmentReader = new WaveFileReader(tempWavPath);
var segment = segmentReader.ToSampleProvider()
.Skip(i * segmentDuration)
.Take(segmentDuration);
var segmentProvider = segment.ToWaveProvider16();
using var segmentStream = new MemoryStream();
WaveFileWriter.WriteWavFileToStream(segmentStream, segmentProvider);
segmentStream.Position = 0;
var durationOffset = TimeSpan.FromSeconds(i * segmentDuration.TotalSeconds);
await foreach (var result in processor.ProcessAsync(segmentStream))
{
var startTime = result.Start + durationOffset;
var endTime = result.End + durationOffset;
Console.WriteLine($"[{startTime:hh\\:mm\\:ss} - {endTime:hh\\:mm\\:ss}]: {result.Text}");
}
}
}
finally
{
// Cleanup temporary file
if (File.Exists(tempWavPath))
{
try
{
File.Delete(tempWavPath);
}
catch
{
// Best effort cleanup
}
2025-08-08 12:15:38 -05:00
}
}
static async Task<WhisperProcessor> GetProcessor()
{
using var memoryStream = new MemoryStream();
2026-01-06 14:15:46 -06:00
var model = await WhisperGgmlDownloader.Default.GetGgmlModelAsync(GgmlType.BaseEn);
2025-08-08 12:15:38 -05:00
await model.CopyToAsync(memoryStream);
var whisperFactory = WhisperFactory.FromBuffer(memoryStream.ToArray());
return whisperFactory.CreateBuilder()
2026-01-06 14:15:46 -06:00
.WithLanguage("en")
.Build();
2025-08-08 12:15:38 -05:00
}