using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; using Whisper.net; using Whisper.net.Ggml; using Xabe.FFmpeg; using Microsoft.Extensions.Logging; namespace Convert_It_Online.Services { public class AudioTranscriptionService : IAudioTranscriptionService { private readonly string _modelPath; private readonly ILogger _logger; private readonly HttpClient _httpClient; public AudioTranscriptionService(ILogger logger) { _logger = logger; _httpClient = new HttpClient(); _modelPath = Path.Combine(AppContext.BaseDirectory, "Models", "ggml-base.bin"); // Garantir que a pasta Models existe var modelsDir = Path.GetDirectoryName(_modelPath); if (!Directory.Exists(modelsDir)) { Directory.CreateDirectory(modelsDir!); } } private async Task EnsureModelExistsAsync() { if (!System.IO.File.Exists(_modelPath)) { _logger.LogInformation("Baixando modelo Whisper Base..."); var downloader = new WhisperGgmlDownloader(_httpClient); using var modelStream = await downloader.GetGgmlModelAsync(GgmlType.Base); using var fileStream = System.IO.File.Create(_modelPath); await modelStream.CopyToAsync(fileStream); _logger.LogInformation("Modelo Whisper baixado com sucesso."); } } public async Task TranscribeAsync(string inputPath, string culture = "pt-BR") { await EnsureModelExistsAsync(); string tempWavPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.wav"); try { _logger.LogInformation("Convertendo áudio para WAV 16kHz Mono..."); // Configurar FFmpeg (assume que está no PATH em Linux) // Se estiver no Windows, pode precisar de FFmpeg.SetExecutablesPath var conversion = await FFmpeg.Conversions.New() .AddParameter($"-i \"{inputPath}\"") .AddParameter("-ar 16000") .AddParameter("-ac 1") .AddParameter("-c:a pcm_s16le") .SetOutput(tempWavPath) .Start(); _logger.LogInformation("Iniciando transcrição com Whisper..."); using var factory = WhisperFactory.FromPath(_modelPath); using var processor = factory.CreateBuilder() .WithLanguage(culture.Split('-')[0]) // Usa "pt", "es", etc .Build(); using var wavStream = System.IO.File.OpenRead(tempWavPath); var result = ""; await foreach (var segment in processor.ProcessAsync(wavStream)) { result += segment.Text + " "; } return result.Trim(); } catch (Exception ex) { _logger.LogError(ex, "Erro durante a transcrição de áudio."); throw; } finally { if (System.IO.File.Exists(tempWavPath)) { System.IO.File.Delete(tempWavPath); } } } } }