Videoverständnis in Agenten
Frames extrahieren, Videos zusammenfassen und Clips zeitlich analysieren.
Videoverständnis in Agenten ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Videoverständnis für Agenten
Die meisten LLMs können Videodateien nicht direkt verarbeiten. Agenten können Videos jedoch analysieren, indem sie repräsentative Frames extrahieren und als Bilder senden. Anschließend schließt der Agent aus der visuellen Abfolge auf Ereignisse, Veränderungen und Muster im Zeitverlauf.
OpenCV zur Frame-Extraktion installieren
OpenCV (cv2) ist die Standardbibliothek für die Videoverarbeitung in Python. Damit können Sie Videodateien öffnen, ihre Metadaten auslesen (Bildrate, Auflösung, Frame-Anzahl) und einzelne Frames als NumPy-Arrays extrahieren.
# pip install opencv-python-headless
import cv2
def get_video_metadata(video_path: str) -> dict:
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise IOError(f'Cannot open video: {video_path}')
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
duration_s = frame_count / fps if fps > 0 else 0
cap.release()
return {
'fps': round(fps, 2),
'frame_count': frame_count,
'width': width,
'height': height,
'duration_seconds': round(duration_s, 2)
}
meta = get_video_metadata('recording.mp4')
print(meta)Frames alle N Sekunden extrahieren
Für die meisten Aufgaben zum Videoverständnis benötigen Sie nicht jeden Frame. Die Entnahme eines Frames alle N Sekunden liefert eine repräsentative Zusammenfassung des Videoinhalts. Bei 1 Frame pro Sekunde erzeugt ein 60 Sekunden langes Video 60 Frames.
import cv2
import os
def extract_frames(
video_path: str,
output_dir: str,
every_n_seconds: float = 5.0
) -> list:
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_interval = int(fps * every_n_seconds)
os.makedirs(output_dir, exist_ok=True)
saved_frames = []
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
if frame_idx % frame_interval == 0:
timestamp = round(frame_idx / fps, 2)
fname = f'{output_dir}/frame_{frame_idx:06d}_{timestamp}s.jpg'
cv2.imwrite(fname, frame)
saved_frames.append({'path': fname, 'timestamp': timestamp})
frame_idx += 1
cap.release()
print(f'Extracted {len(saved_frames)} frames')
return saved_framesErkennung von Szenenwechseln
Statt gleichmäßig zu sampeln, extrahieren Sie Frames an Szenengrenzen – also an Zeitpunkten, an denen sich der visuelle Inhalt deutlich verändert. Dadurch erhalten Sie pro API-Aufruf informativere Frames. Verwenden Sie die Frame-Differenzbildung: Überschreitet die mittlere absolute Differenz zwischen aufeinanderfolgenden Frames einen Schwellenwert, ist ein Szenenwechsel aufgetreten.
import cv2
import numpy as np
def extract_scene_change_frames(
video_path: str,
output_dir: str,
diff_threshold: float = 30.0
) -> list:
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
os.makedirs(output_dir, exist_ok=True)
prev_gray = None
saved = []
frame_idx = 0
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if prev_gray is not None:
diff = np.mean(np.abs(gray.astype(float) - prev_gray.astype(float)))
if diff > diff_threshold:
ts = round(frame_idx / fps, 2)
fname = f'{output_dir}/scene_{frame_idx:06d}_{ts}s.jpg'
cv2.imwrite(fname, frame)
saved.append({'path': fname, 'timestamp': ts, 'diff': round(diff, 2)})
prev_gray = gray
frame_idx += 1
cap.release()
return savedEine Frame-Sequenz an die Vision API senden
Senden Sie mehrere extrahierte Frames in einer einzigen Nachricht an die Vision API. Geben Sie den Zeitstempel jedes Frames an, damit das Modell zeitliche Reihenfolge und Dauer berücksichtigen kann. Fordern Sie in Ihrem Prompt ausdrücklich zeitliches Schlussfolgern an.
import base64
import anthropic
def describe_video_frames(frame_info_list: list, query: str) -> str:
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
content = []
for fi in frame_info_list:
with open(fi['path'], 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
content.append({
'type': 'text',
'text': f'Frame at {fi["timestamp"]}s:'
})
content.append({
'type': 'image',
'source': {'type': 'base64', 'media_type': 'image/jpeg', 'data': b64}
})
content.append({'type': 'text', 'text': query})
response = client.messages.create(
model='claude-opus-4-5',
max_tokens=1024,
messages=[{'role': 'user', 'content': content}]
)
return response.content[0].textPrompts für zeitliches Schlussfolgern
Zeitliches Schlussfolgern erfordert eine gezielte Gestaltung des Prompts. Fordern Sie das Modell auf, Frames ausdrücklich zu vergleichen, Veränderungen zu benennen, die Dauer von Aktivitäten zu schätzen und kausale Zusammenhänge zwischen den Frames zu erkennen.
TEMPORAL_QUERY = (
'You are analysing a video sequence. The frames above are in chronological order '
'with their timestamps shown. Please:\n'
'1. Describe what changed between the first and last frame\n'
'2. Identify any notable events and when they occurred (timestamp)\n'
'3. Summarise the overall activity shown in the video\n'
'4. Estimate the total duration of the main activity\n'
'Be specific about timestamps.'
)
# More targeted temporal query:
CHANGE_DETECTION_QUERY = (
'Compare frame at {start_ts}s and frame at {end_ts}s. '
'List all visible differences in bullet points. '
'Categorise each change as: object_moved, object_added, '
'object_removed, lighting_change, or camera_move.'
)
# Usage:
query = CHANGE_DETECTION_QUERY.format(start_ts=0.0, end_ts=20.0)
if __name__ == '__main__':
print('Temporal reasoning query:')
print(TEMPORAL_QUERY)
print()
print('Change detection query:')
print(query)
Pipeline zur Videozusammenfassung
Eine vollständige Pipeline zur Videozusammenfassung besteht aus folgenden Schritten: Frames extrahieren → in Batches an das Vision-Modell senden → Zusammenfassungen pro Batch sammeln → eine abschließende Zusammenfassung erstellen. Durch Batching wird verhindert, dass das Kontextfenster überschritten wird.
def summarise_video(
video_path: str,
every_n_seconds: float = 10.0,
batch_size: int = 5
) -> str:
import anthropic
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
# Extract frames
frames = extract_frames(video_path, '/tmp/video_frames', every_n_seconds)
# Process in batches
batch_summaries = []
for i in range(0, len(frames), batch_size):
batch = frames[i:i + batch_size]
ts_range = f'{batch[0]["timestamp"]}s - {batch[-1]["timestamp"]}s'
query = f'Summarise what happens in this video segment ({ts_range}).'
summary = describe_video_frames(batch, query)
batch_summaries.append(f'[{ts_range}] {summary}')
# Synthesise
all_summaries = '\n\n'.join(batch_summaries)
result = client.messages.create(
model='claude-opus-4-5',
max_tokens=512,
messages=[{'role': 'user', 'content':
f'Here are segment-level video summaries:\n\n{all_summaries}\n\n'
'Write a single coherent summary of the entire video.'
}]
)
return result.content[0].textObjektverfolgung über mehrere Frames
Bitten Sie das Vision-Modell, bestimmte Objekte über eine Frame-Sequenz hinweg zu verfolgen. Zum Beispiel: 'Beschreiben Sie in jedem Frame die Position des roten Autos: oben links, oben rechts, Mitte, unten links, unten rechts.' Dadurch entsteht eine grobe Bewegungsbahn, ohne dass Computer-Vision-Algorithmen zur Verfolgung erforderlich sind.
def track_object_across_frames(
frames: list,
object_description: str
) -> list:
import anthropic, base64
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
trajectory = []
for fi in frames:
with open(fi['path'], 'rb') as f:
b64 = base64.standard_b64encode(f.read()).decode('utf-8')
response = client.messages.create(
model='claude-opus-4-5',
max_tokens=128,
messages=[{
'role': 'user',
'content': [
{'type': 'image', 'source': {'type': 'base64',
'media_type': 'image/jpeg', 'data': b64}},
{'type': 'text', 'text':
f'Where is the {object_description} in this frame? '
'Answer with one of: top-left, top-right, centre, '
'bottom-left, bottom-right, not-visible.'}
]
}]
)
trajectory.append({
'timestamp': fi['timestamp'],
'position': response.content[0].text.strip()
})
return trajectoryUmgang mit Frame-Anzahllimits
Die Kontextfenster von Vision-APIs begrenzen die Anzahl der Bilder, die pro Anfrage gesendet werden können (typischerweise 5–20 Bilder). Verwenden Sie bei langen Videos einen hierarchischen Ansatz: Analysieren Sie Segmente unabhängig voneinander und fügen Sie anschließend die Segmentzusammenfassungen in einem zweiten LLM-Aufruf zu einer abschließenden Zusammenfassung zusammen.
MAX_FRAMES_PER_REQUEST = 8
def hierarchical_video_analysis(frames: list, final_query: str) -> str:
import anthropic
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
# Level 1: analyse each chunk
chunk_summaries = []
for i in range(0, len(frames), MAX_FRAMES_PER_REQUEST):
chunk = frames[i:i + MAX_FRAMES_PER_REQUEST]
ts = f'{chunk[0]["timestamp"]}s-{chunk[-1]["timestamp"]}s'
summary = describe_video_frames(
chunk, f'What happens in this segment ({ts})?'
)
chunk_summaries.append(f'Segment {ts}: {summary}')
# Level 2: synthesise all chunk summaries
combined = '\n'.join(chunk_summaries)
result = client.messages.create(
model='claude-opus-4-5',
max_tokens=512,
messages=[{
'role': 'user',
'content': f'Video segments:\n{combined}\n\n{final_query}'
}]
)
return result.content[0].textAudio- und Videoanalyse kombinieren
Für ein möglichst umfassendes Verständnis kombinieren Sie die visuelle Analyse auf Frame-Ebene mit der Audiotranskription durch Whisper. Der Agent kann zu jedem Zeitstempel das Gesehene mit dem Gesagten abgleichen und so leistungsfähige Aufgaben wie Besprechungsanalysen oder die Indexierung von Tutorials ermöglichen.
def full_video_analysis(video_path: str) -> dict:
import subprocess
# Step 1: Extract audio track
audio_path = '/tmp/video_audio.mp3'
subprocess.run([
'ffmpeg', '-i', video_path, '-q:a', '0', '-map', 'a',
audio_path, '-y'
], capture_output=True)
# Step 2: Transcribe audio
transcript_data = transcribe_with_timestamps(audio_path)
# Step 3: Extract key frames
frames = extract_frames(video_path, '/tmp/key_frames', every_n_seconds=15.0)
# Step 4: Visual summary
visual_summary = hierarchical_video_analysis(
frames, 'Summarise the visual content.'
)
return {
'transcript': transcript_data['full_text'],
'transcript_segments': transcript_data['segments'],
'visual_summary': visual_summary,
'frame_count': len(frames)
}Aufräumen und Frame-Verwaltung
Extrahierte Frames können sich schnell ansammeln. Löschen Sie temporäre Frame-Dateien nach der Verarbeitung immer und implementieren Sie einen Frame-Cache, dessen Schlüssel aus einem Hash von (video_path, frame_rate) besteht, um bei wiederholten Analysen desselben Videos eine erneute Extraktion zu vermeiden.
import os
import shutil
import hashlib
FRAME_CACHE_DIR = '/tmp/frame_cache'
def get_cache_key(video_path: str, every_n_seconds: float) -> str:
content = f'{video_path}:{every_n_seconds}'
return hashlib.md5(content.encode()).hexdigest()[:12]
def get_or_extract_frames(video_path: str, every_n_seconds: float) -> list:
key = get_cache_key(video_path, every_n_seconds)
cache_dir = os.path.join(FRAME_CACHE_DIR, key)
if os.path.exists(cache_dir):
print(f'Cache hit: {key}')
files = sorted(os.listdir(cache_dir))
return [
{'path': os.path.join(cache_dir, f),
'timestamp': float(f.split('_')[-1].replace('s.jpg', ''))}
for f in files if f.endswith('.jpg')
]
return extract_frames(video_path, cache_dir, every_n_seconds)
def clear_frame_cache():
if os.path.exists(FRAME_CACHE_DIR):
shutil.rmtree(FRAME_CACHE_DIR)
print('Frame cache cleared')Wissensüberprüfung
Warum ist die Erkennung von Szenenwechseln bei der Videoanalyse dem gleichmäßigen Sampling von Frames vorzuziehen?
Zusammenfassung: Videoverständnis in Agenten
Gut gemacht! Die wichtigsten Erkenntnisse aus dieser Lektion:
- OpenCV: Frames mit
cap.read()extrahieren; alle N Sekunden oder bei Szenenwechseln samplen - Frame-Sequenzen: für den zeitlichen Kontext in chronologischer Reihenfolge mit Zeitstempeln senden
- Hierarchische Analyse: in Batches aufteilen → Segmentzusammenfassungen → abschließende Synthese
- Kombinierte Analyse: ffmpeg extrahiert Audio; Whisper transkribiert; mit visuellen Frames abgleichen
- Frame-Cache: redundante Extraktion mit einem hashbasierten Cache-Verzeichnis vermeiden
Als Nächstes: modalitätsübergreifendes Schlussfolgern – wenn der Text etwas anderes sagt als das Bild zeigt.
Häufig gestellte Fragen
Ist die Lektion „Videoverständnis in Agenten“ kostenlos?
Ja — der vollständige Text von „Videoverständnis in Agenten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Videoverständnis in Agenten“?
Frames extrahieren, Videos zusammenfassen und Clips zeitlich analysieren. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Agents zu starten?
Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Videoverständnis in Agenten“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?
Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Bild- und Textagenten mit Claude Vision und GPT-4V
- Agenten-Workflows für Audio und Text
- Videoverständnis in Agenten
- Muster für multimodales Reasoning