#v2 - Inicia testes da v2

- Adiciona rastreamento de objetos
- Facial detection
- Legenda interativa
- Cortes mais precisos
- Refinamento do Prompt
This commit is contained in:
LeoMortari
2025-11-12 11:38:09 -03:00
parent 87c6a5e27c
commit c5d3e83a5f
15 changed files with 1739 additions and 313 deletions

View File

@@ -6,7 +6,7 @@ from pathlib import Path
from typing import Any, Dict, List, Optional
from video_render.config import Settings
from video_render.llm import GeminiHighlighter, OpenRouterCopywriter
from video_render.llm import OpenRouterCopywriter
from video_render.media import MediaPreparer, VideoWorkspace
from video_render.transcription import TranscriptionResult, TranscriptionService
from video_render.utils import remove_paths, sanitize_filename
@@ -55,8 +55,7 @@ class VideoPipeline:
self.settings = settings
self.media_preparer = MediaPreparer(settings)
self.transcriber = TranscriptionService(settings)
self.highlighter = GeminiHighlighter(settings)
self.copywriter = OpenRouterCopywriter(settings)
self.llm_service = OpenRouterCopywriter(settings) # Using OpenRouter for both highlights and titles
self.renderer = VideoRenderer(settings)
def process_message(self, message: Dict[str, Any]) -> Dict[str, Any]:
@@ -65,12 +64,11 @@ class VideoPipeline:
self._prepare_workspace(context)
self._generate_transcription(context)
self._determine_highlights(context)
self._generate_titles(context)
self._render_clips(context)
return self._build_success_payload(context)
except Exception as exc:
logger.exception("Falha ao processar vídeo %s", context.job.filename)
# return self._handle_failure(context, exc)
def _parse_job(self, message: Dict[str, Any]) -> JobMessage:
filename = message.get("filename")
@@ -102,7 +100,10 @@ class VideoPipeline:
context.transcription = existing
return
transcription = self.transcriber.transcribe(context.workspace.audio_path)
transcription = self.transcriber.transcribe(
context.workspace.audio_path,
output_dir=context.workspace.workspace_dir
)
TranscriptionService.persist(transcription, context.workspace.workspace_dir)
context.transcription = transcription
@@ -111,10 +112,10 @@ class VideoPipeline:
raise RuntimeError("Transcricao nao disponivel")
try:
highlights_raw = self.highlighter.generate_highlights(context.transcription)
highlights_raw = self.llm_service.generate_highlights(context.transcription)
except Exception:
logger.exception(
"Falha ao gerar destaques com Gemini; aplicando fallback padrao."
"Falha ao gerar destaques com OpenRouter; aplicando fallback padrao."
)
context.highlight_windows = [self._build_fallback_highlight(context)]
return
@@ -130,11 +131,13 @@ class VideoPipeline:
continue
summary = str(item.get("summary", "")).strip()
title = str(item.get("title", summary[:60])).strip()
if end <= start:
logger.debug("Highlight com intervalo invalido ignorado: %s", item)
continue
windows.append(HighlightWindow(start=start, end=end, summary=summary))
windows.append(HighlightWindow(start=start, end=end, summary=summary, title=title))
if not windows:
windows.append(self._build_fallback_highlight(context))
@@ -142,17 +145,12 @@ class VideoPipeline:
context.highlight_windows = windows
def _generate_titles(self, context: PipelineContext) -> None:
if not context.highlight_windows:
return
"""DEPRECATED: Titles are now generated together with highlights.
highlight_dicts = [
{"start": window.start, "end": window.end, "summary": window.summary}
for window in context.highlight_windows
]
titles = self.copywriter.generate_titles(highlight_dicts)
for window, title in zip(context.highlight_windows, titles):
window.title = title.strip()
This method is kept for backwards compatibility but does nothing.
Titles are extracted from highlights in _determine_highlights().
"""
pass
def _build_fallback_highlight(self, context: PipelineContext) -> HighlightWindow:
if not context.transcription:
@@ -167,6 +165,7 @@ class VideoPipeline:
start=0.0,
end=max(last_end, 10.0),
summary="Sem destaque identificado; fallback automatico.",
title="Confira este momento",
)
def _render_clips(self, context: PipelineContext) -> None: