File size: 2,419 Bytes
e417aa9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""Build structured video context and system prompts from analysis results."""

import logging

logger = logging.getLogger(__name__)


def _fmt_time(seconds: float) -> str:
    """Format seconds as MM:SS."""
    m = int(seconds // 60)
    s = int(seconds % 60)
    return f"{m:02d}:{s:02d}"


def build_video_context(
    video_metadata: dict,
    frame_analyses: list[dict],
    transcript_segments: list[dict],
) -> str:
    """Assemble a structured text document combining metadata, visual analysis, and transcript.

    Returns the full context string.
    """
    meta = video_metadata
    lines = [
        "VIDEO METADATA:",
        (
            f"Duration: {meta['duration_seconds']:.1f}s | "
            f"Resolution: {meta['width']}x{meta['height']} | "
            f"FPS: {meta['fps']:.1f}"
        ),
        "",
        "VISUAL ANALYSIS (sampled every 5 seconds):",
    ]

    if frame_analyses:
        for fa in sorted(frame_analyses, key=lambda x: x["timestamp"]):
            lines.append(f"[{_fmt_time(fa['timestamp'])}] {fa['description']}")
    else:
        lines.append("No visual analysis available.")

    lines.append("")
    lines.append("AUDIO TRANSCRIPT:")

    if transcript_segments:
        for seg in transcript_segments:
            start = _fmt_time(seg["start"])
            end = _fmt_time(seg["end"])
            lines.append(f"[{start} - {end}] {seg['text']}")
    elif not meta.get("has_audio"):
        lines.append("No audio track detected.")
    else:
        lines.append("No speech detected in audio.")

    context = "\n".join(lines)
    logger.info("Built video context (%d chars)", len(context))
    return context


def build_chat_system_prompt(video_context: str) -> str:
    """Return a system prompt that grounds the LLM in the provided video context."""
    return (
        "You are a Video Intelligence Assistant. Your role is to answer questions "
        "about a specific video based solely on the analysis data provided below.\n\n"
        "Guidelines:\n"
        "- Always reference specific timestamps (e.g., [01:23]) when relevant.\n"
        "- Keep answers concise and grounded in the video content.\n"
        "- If something cannot be determined from the analysis, say: "
        "'I couldn't detect that in the video.'\n"
        "- Do not speculate beyond what is described in the analysis.\n\n"
        f"VIDEO ANALYSIS DATA:\n{video_context}"
    )