Sistema de Pipelines
Sistema modular y escalable para transformar contenido a través de múltiples servicios con tracking completo en base de datos.
Arquitectura
Input (Texto)
↓
[Pipeline Executor] → Crea ejecución en BD
↓
[Step 1: OpenAI Analyzer] → Extrae JSON estructurado
↓ (tracking en BD)
[Step 2: Pexels Fetcher] → Busca imágenes/videos
↓ (tracking en BD)
[Step 3: Apply Template] → Genera video JSON
↓
Output (Video JSON completo)
Cada paso se registra en la base de datos con:
- Input/Output
- Duración (ms)
- Costo (USD)
- Metadata (tokens, API calls, etc.)
Base de Datos
PipelineExecution
- Registro de cada ejecución de pipeline
- Estado global (PENDING, RUNNING, COMPLETED, FAILED)
- Input original y output final
- Duración y costo total
PipelineStep
- Cada paso del pipeline
- Input/output específico del paso
- Duración y costo individual
- Metadata del servicio (tokens, llamadas API, etc.)
Pipelines Disponibles
1. Press Release to Video (press-release-to-video)
Convierte una nota de prensa en un video narrado con imágenes y videos relevantes.
Input:
{
text: "Texto de la nota de prensa...",
// Opcional
ttsProvider?: "polly" | "elevenlabs",
voice?: string,
languageCode?: string
}
Steps:
- analyze-content (OpenAI) - Extrae título, resumen, búsquedas, keywords
- fetch-media (Pexels) - Busca 3 videos (landscape)
- apply-template (Internal) - Aplica template 'narrated-content'
Output:
{
title: "...",
summary: "...",
searchQueries: [...],
keywords: [...],
images: [...],
videos: [...],
videoJson: { output: {...}, timeline: [...] }
}
2. Press Release to Video Vertical (press-release-to-video-vertical)
Convierte una nota de prensa en un video vertical 9:16 para redes sociales.
Input:
{
text: "Texto de la nota de prensa...",
// Opcional
ttsProvider?: "polly" | "elevenlabs",
voice?: string,
languageCode?: string
}
Steps:
- analyze-content (OpenAI) - Extrae título, resumen, búsquedas, keywords
- fetch-media (Pexels) - Busca 3 videos (portrait)
- apply-template (Internal) - Aplica template 'narrated-content-vertical'
Output: Igual que press-release-to-video pero en formato 9:16
3. Comunicae to Video (comunicae-to-video)
Convierte un artículo de Comunicae en un video narrado usando las imágenes del artículo.
Input:
{
url: "https://comunicae.es/notas-de-prensa/{slug}",
// Opcional
ttsProvider?: "polly" | "elevenlabs",
voice?: string,
languageCode?: string
}
Steps:
- fetch-comunicae (Comunicae API) - Obtiene datos del artículo
- analyze-content (OpenAI) - Genera búsquedas para Pexels
- fetch-media (Pexels) - Busca 3 videos (landscape)
- apply-template (Internal) - Aplica template 'narrated-content'
Output:
{
title: "...",
text: "...",
images: [...], // Imágenes del artículo
videos: [...], // Videos de Pexels
videoJson: { output: {...}, timeline: [...] }
}
4. Comunicae to Video Vertical (comunicae-to-video-vertical)
Convierte un artículo de Comunicae en un video vertical 9:16.
Input:
{
url: "https://comunicae.es/notas-de-prensa/{slug}",
// Opcional
ttsProvider?: "polly" | "elevenlabs",
voice?: string,
languageCode?: string
}
Steps:
- fetch-comunicae (Comunicae API) - Obtiene datos del artículo
- analyze-content (OpenAI) - Genera búsquedas para Pexels
- fetch-media (Pexels) - Busca 3 videos (portrait)
- apply-template (Internal) - Aplica template 'narrated-content-vertical'
Output: Igual que comunicae-to-video pero en formato 9:16
Uso
Desde código
import { pipelineExecutor, pipelineRegistry } from '~/services/pipeline';
const pipeline = pipelineRegistry.get('press-release-to-video');
const result = await pipelineExecutor.execute(
pipeline,
{ text: "Mi nota de prensa..." },
{ userId: "user_123" }
);
if (result.status === 'COMPLETED') {
console.log('Video JSON:', result.output.videoJson);
console.log('Total cost:', result.totalCost);
console.log('Duration:', result.totalDuration, 'ms');
}
Desde API
POST /api/pipeline/test
Ejemplo 1: Press Release (texto)
{
"pipelineId": "press-release-to-video",
"input": {
"text": "Comunicae anuncia el lanzamiento de su nueva plataforma...",
"ttsProvider": "elevenlabs",
"voice": "Rachel"
},
"userId": "user_123"
}
Ejemplo 2: Comunicae (URL)
{
"pipelineId": "comunicae-to-video",
"input": {
"url": "https://comunicae.es/notas-de-prensa/globamatic-media-facilita-la-conservacion-de",
"ttsProvider": "polly",
"voice": "Lucia",
"languageCode": "es-ES"
},
"userId": "user_123"
}
Response:
{
"success": true,
"result": {
"executionId": "clxxx...",
"status": "COMPLETED",
"output": {
"title": "...",
"text": "...",
"images": [...],
"videos": [...],
"videoJson": {...}
},
"totalDuration": 4523,
"totalCost": 0.0124,
"steps": [...]
}
}
Ver estado de ejecución
import { pipelineTracker } from '~/services/pipeline';
const execution = await pipelineTracker.getExecution('exec_id');
console.log('Status:', execution.status);
console.log('Steps:', execution.steps.length);
// Estadísticas
const stats = await pipelineTracker.getExecutionStats('exec_id');
console.log('Completed steps:', stats.completedSteps);
console.log('Failed steps:', stats.failedSteps);
console.log('Total cost:', stats.totalCost);
Crear Nuevo Pipeline
1. Crear el Step (si es necesario)
// app/services/pipeline/steps/my-service.step.ts
import type { PipelineStepConfig } from '../types';
export function createMyServiceStep(config: MyConfig): PipelineStepConfig {
return {
name: 'my-step',
service: 'my-service',
async execute(input: any, context) {
// Lógica del paso
const result = await myService.process(input);
return {
output: result,
metadata: { apiCalls: 1 },
cost: 0.05,
};
},
estimateCost(input) {
return 0.05;
},
retryable: true,
timeout: 30000,
};
}
2. Crear el Pipeline
// app/services/pipeline/pipelines/my-pipeline.ts
import type { Pipeline } from '../types';
import { createOpenAIAnalyzerStep } from '../steps/openai-analyzer.step';
import { createMyServiceStep } from '../steps/my-service.step';
export const myPipeline: Pipeline = {
id: 'my-pipeline',
name: 'My Pipeline',
description: 'Description...',
version: '1.0.0',
steps: [
createOpenAIAnalyzerStep({ contentType: 'article' }),
createMyServiceStep({ option: 'value' }),
],
};
3. Registrar en Registry
// app/services/pipeline/registry.server.ts
import { myPipeline } from './pipelines/my-pipeline';
constructor() {
this.register(pressReleaseToVideoPipeline);
this.register(myPipeline); // ← Añadir aquí
}
Steps Disponibles
createOpenAIAnalyzerStep
Analiza contenido con OpenAI y extrae JSON estructurado.
Config:
contentType: 'press-release' | 'ad' | 'social-post' | 'article'model: 'gpt-4o' | 'gpt-4o-mini' (default: 'gpt-4o')temperature: 0-1 (default: 0.3)
Input: { text: string }
Output: JSON estructurado según contentType
Costo: ~$0.01-0.03 por análisis (depende del tamaño)
createPexelsFetcherStep
Busca imágenes y videos en Pexels.
Config:
imageCount: número de imágenes (default: 5)videoCount: número de videos (default: 3)orientation: 'landscape' | 'portrait' | 'square'size: 'large' | 'medium' | 'small'
Input: { searchQueries: string[] }
Output: { images: string[], videos: string[] }
Costo: Gratis (API de Pexels)
createApplyTemplateStep
Aplica un template de video con los datos.
Config:
templateId: ID del template (ej: 'narrated-content')dataMapping: Mapeo de campos input → template
Input: Datos para el template
Output: { videoJson: {...} }
Costo: Gratis (proceso interno)
Monitorización
Todas las ejecuciones se guardan en la BD y puedes consultarlas:
// Ver todas las ejecuciones de un pipeline
const executions = await pipelineTracker.getExecutionsForPipeline(
'press-release-to-video',
50 // limit
);
// Ver estadísticas
for (const exec of executions) {
const stats = await pipelineTracker.getExecutionStats(exec.id);
console.log(`${exec.id}: ${stats.completedSteps}/${stats.totalSteps} steps, $${stats.totalCost}`);
}
Ejemplo Completo: Nota de Prensa → Video
const pressRelease = `
Comunicae anuncia el lanzamiento de VideoMaker AI, una revolucionaria
plataforma que permite crear videos profesionales a partir de texto usando
inteligencia artificial. La plataforma integra TTS, subtítulos automáticos
y búsqueda inteligente de contenido visual.
`;
const pipeline = pipelineRegistry.get('press-release-to-video');
const result = await pipelineExecutor.execute(
pipeline,
{ text: pressRelease },
{ userId: 'user_123' }
);
// Resultado:
// {
// executionId: "clxxx...",
// status: "COMPLETED",
// output: {
// title: "Comunicae lanza VideoMaker AI",
// summary: "Plataforma revolucionaria para crear videos con IA...",
// searchQueries: ["AI video creation", "professional videos", "text to speech"],
// keywords: ["videomaker", "AI", "TTS"],
// images: [
// "https://images.pexels.com/...",
// "https://images.pexels.com/...",
// ],
// videos: [
// "https://videos.pexels.com/...",
// ],
// videoJson: {
// output: { width: 1920, height: 1080, fps: 30 },
// timeline: [...]
// }
// },
// totalDuration: 4523, // ms
// totalCost: 0.0124, // USD
// steps: [
// { name: "analyze-content", status: "COMPLETED", duration: 2341, cost: 0.0124 },
// { name: "fetch-media", status: "COMPLETED", duration: 1895, cost: 0 },
// { name: "apply-template", status: "COMPLETED", duration: 287, cost: 0 }
// ]
// }
Precios Estimados
| Pipeline | Costo Promedio | Duración |
|---|---|---|
| press-release-to-video | $0.01-0.03 | 3-5s |
| press-release-to-video-vertical | $0.01-0.03 | 3-5s |
| comunicae-to-video | $0.01-0.03 | 3-5s |
| comunicae-to-video-vertical | $0.01-0.03 | 3-5s |
Desglose:
- Comunicae API: $0 (gratis)
- OpenAI GPT-5-mini: $0.01-0.03 (depende del texto)
- Pexels API: $0 (gratis)
- Template: $0 (interno)
- TTS (Polly): Incluido en análisis
- TTS (ElevenLabs): Variable según uso
Próximos Pipelines
Ideas para futuros pipelines:
- ad-to-social - Convierte anuncio en posts para redes sociales
- article-to-video - Artículo → video educativo
- product-to-ad - Descripción de producto → video publicitario
- text-to-podcast - Texto → podcast con múltiples voces