mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-19 13:08:12 +02:00
SRT : la voix n'est plus jamais accélérée (atempo sans plafond, jusqu'à 2× et plus, rendait la voix incompréhensible). Un morceau plus long que son sous-titre déborde et décale les suivants ; les sous-titres suivent la voix, la vidéo s'allonge et un avertissement signale le décalage. Rythme : style par défaut « neutre », consignes Gemini sans « rythme entraînant », débit Edge des styles dynamique/promo ramené à +0 %/+3 %. Nouveau moteur « qwen » : service qwen-tts (Qwen3-TTS sur CPU, gratuit, français, ton piloté par consigne, clonage de voix depuis qwen-tts/voices). Même vérification Whisper que Gemini, généralisée ; repli qwen → gemini → edge, et une lecture sous 85 % du texte est écartée (mots sautés/faux). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Upu97wMmsRkBoj6iVM4rH6
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
/**
|
|
* Résolution des ressources d'un Reel (musique, logo, clé Gemini, nom du
|
|
* magasin), jusqu'ici recopiée dans chaque route.
|
|
*/
|
|
|
|
import { storage } from "../../storage";
|
|
import { buildMinioUrl, resolveInternalUrl } from "../minio";
|
|
|
|
/**
|
|
* URL de la musique téléchargeable par le service FFmpeg (réseau Docker
|
|
* interne : l'URL publique HTTPS n'y est pas joignable).
|
|
*/
|
|
export async function resolveMusicUrl(
|
|
musicTrackId?: string,
|
|
musicUrl?: string,
|
|
): Promise<string | undefined> {
|
|
if (musicUrl) return resolveInternalUrl(musicUrl);
|
|
if (!musicTrackId?.startsWith("internal_")) return undefined;
|
|
|
|
try {
|
|
const track = await storage.getAudioTrack(musicTrackId.slice("internal_".length));
|
|
return track ? resolveInternalUrl(track.url) : undefined;
|
|
} catch (error) {
|
|
console.error("⚠️ [Reels] Piste audio introuvable :", error);
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/** Chemin relatif (/uploads/...) du logo configuré, s'il existe. */
|
|
export async function resolveLogoPath(): Promise<string | undefined> {
|
|
try {
|
|
const config = await storage.getCloudinaryConfig();
|
|
if (config?.logoPublicId) {
|
|
return buildMinioUrl(config.cloudName, config.logoPublicId, config.publicUrl);
|
|
}
|
|
} catch (error) {
|
|
console.error("⚠️ [Reels] Configuration du logo illisible :", error);
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Clé Gemini : configuration de l'application, sinon variable d'environnement.
|
|
* Aussi transmise avec Qwen, qui se replie sur Gemini si le service local échoue.
|
|
*/
|
|
export async function resolveGeminiApiKey(ttsEngine?: string): Promise<string | undefined> {
|
|
if (ttsEngine !== "gemini" && ttsEngine !== "qwen") return undefined;
|
|
const appConfig = await storage.getAppConfig();
|
|
return appConfig?.geminiApiKey ?? process.env.GEMINI_API_KEY ?? undefined;
|
|
}
|
|
|
|
/** Nom affiché dans l'outro : celui de la page choisie, sinon de la première page de l'utilisateur. */
|
|
export async function resolveStoreName(
|
|
userId: string,
|
|
preferredPageId?: string,
|
|
): Promise<string | undefined> {
|
|
try {
|
|
if (preferredPageId) {
|
|
const page = await storage.getSocialPage(preferredPageId);
|
|
if (page) return page.pageName;
|
|
}
|
|
const pages = await storage.getSocialPages(userId);
|
|
return pages[0]?.pageName;
|
|
} catch (error) {
|
|
console.error("⚠️ [Reels] Nom du magasin introuvable :", error);
|
|
return undefined;
|
|
}
|
|
}
|