main
Some checks failed
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-03-29 12:43:49 +03:00
parent 829413f05d
commit 85c35c73e8
41 changed files with 6127 additions and 36 deletions

View File

@@ -0,0 +1,99 @@
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SaasMediaWorker.Configuration;
using SaasMediaWorker.Models;
namespace SaasMediaWorker.Services;
/// <summary>
/// ElevenLabs TTS API Client — Metin → Ses dönüşümü.
/// Her sahnenin narrationText'ini sese çevirir.
/// </summary>
public class TtsService
{
private readonly HttpClient _httpClient;
private readonly ILogger<TtsService> _logger;
private readonly ApiSettings _settings;
public TtsService(
HttpClient httpClient,
ILogger<TtsService> logger,
IOptions<ApiSettings> settings)
{
_httpClient = httpClient;
_logger = logger;
_settings = settings.Value;
_httpClient.BaseAddress = new Uri(_settings.TtsBaseUrl);
_httpClient.DefaultRequestHeaders.Add("xi-api-key", _settings.TtsApiKey);
_httpClient.Timeout = TimeSpan.FromMinutes(2);
}
/// <summary>
/// Bir sahnenin narration metnini sese çevirir ve dosyaya kaydeder.
/// </summary>
public async Task<GeneratedMediaFile> GenerateNarrationAsync(
ScenePayload scene,
string outputDirectory,
string voiceStyle,
CancellationToken ct)
{
_logger.LogInformation(
"🎙️ TTS üretimi — Sahne {Order}: \"{Text}\"",
scene.Order,
scene.NarrationText[..Math.Min(60, scene.NarrationText.Length)]);
var voiceId = _settings.TtsVoiceId;
var requestBody = new
{
text = scene.NarrationText,
model_id = "eleven_multilingual_v2",
voice_settings = new
{
stability = 0.5,
similarity_boost = 0.75,
style = 0.3,
use_speaker_boost = true
}
};
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await _httpClient.PostAsync(
$"/text-to-speech/{voiceId}",
content, ct);
response.EnsureSuccessStatusCode();
// Ses dosyasını kaydet
var outputPath = Path.Combine(outputDirectory, $"scene_{scene.Order:D2}_narration.mp3");
await using var fileStream = File.Create(outputPath);
await response.Content.CopyToAsync(fileStream, ct);
var fileInfo = new FileInfo(outputPath);
_logger.LogInformation(
"TTS tamamlandı — Sahne {Order}: {Size} bytes",
scene.Order, fileInfo.Length);
return new GeneratedMediaFile
{
SceneId = scene.Id,
SceneOrder = scene.Order,
Type = MediaFileType.AudioNarration,
LocalPath = outputPath,
FileSizeBytes = fileInfo.Length,
DurationSeconds = scene.Duration,
MimeType = "audio/mpeg",
AiProvider = "elevenlabs"
};
}
}