# Video analyseren met de Gemini API [[TOC]] ## Videoanalyse met Gemini Gemini verwerkt video door frames te bemonsteren (standaard 1 fps) en de audio-track te analyseren als geintegreerde multimodale input. Dit maakt analyses mogelijk die zowel visuele als auditieve informatie combineren: wat er gezegd wordt, wat er te zien is, en hoe die twee zich tot elkaar verhouden. Typische toepassingen: beveiligingsvideo doorzoeken, content-moderatie, educatieve video doorzoekbaar maken, productdemonstraties automatisch documenteren, en sport- of media-analyse. :::info title="Nieuwe SDK sinds Gemini 2.0" De voorbeelden hieronder gebruiken de unified `google-genai` SDK. De oudere `google-generativeai` SDK met `genai.configure()` en `genai.upload_file()` is afgeschaft: vanaf releases na 24 juni 2026 zitten die modules er niet meer in. Migreer naar `from google import genai` met een expliciete `client`. Installeren doe je met `pip install google-genai`. ::: ## Video uploaden en verwerken Upload het bestand via de Files API. Een upload heeft even verwerkingstijd nodig voordat je er een prompt op kunt loslaten, dus poll je op de status tot het bestand `ACTIVE` is. ```python from google import genai import time import os client = genai.Client(api_key=os.environ["GEMINI_API_KEY"]) video_file = client.files.upload(file="productdemo.mp4") print(f"Upload gestart: {video_file.name}") while video_file.state.name == "PROCESSING": print("Video wordt verwerkt...") time.sleep(10) video_file = client.files.get(name=video_file.name) if video_file.state.name == "FAILED": raise RuntimeError("Verwerking mislukt") print(f"Status: {video_file.state.name}") print(f"URI: {video_file.uri}") ``` Videoverwerking duurt langer dan audio of afbeeldingen. Geupload materiaal blijft standaard 48 uur beschikbaar via de Files API. ## Video samenvatten ```python response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, """Geef een gestructureerde samenvatting van deze video: - Onderwerp en doel van de video - Tijdlijn van hoofdonderwerpen (met tijdstempels) - Belangrijkste inzichten of conclusies - Aanbevolen doelgroep""", ], ) print(response.text) ``` ## YouTube-URL meesturen zonder te uploaden Je kunt een publieke YouTube-URL nu rechtstreeks meesturen in plaats van eerst te downloaden en uploaden. Dat scheelt een hele uploadstap. ```python from google.genai import types response = client.models.generate_content( model="gemini-3.5-flash", contents=types.Content( parts=[ types.Part( file_data=types.FileData(file_uri="https://www.youtube.com/watch?v=VIDEO_ID") ), types.Part(text="Vat deze video samen in vijf bullets met tijdstempels."), ] ), ) print(response.text) ``` :::warn title="Beperkingen YouTube-URL" Alleen publieke (niet-verborgen) video's werken, en op de gratis laag geldt een dagelijks plafond aan YouTube-minuten. Voor privevideo's of strakke controle over caching upload je het bestand zelf via de Files API. ::: ## Specifieke scenes opzoeken ```python response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, "Op welke tijdstempels wordt het installatieproces gedemonstreerd? Geef een beschrijving per stap.", ], ) print(response.text) ``` :::tip title="Vraag altijd om tijdstempels" Wil je specifieke scenes terugvinden, vraag dan expliciet om tijdstempels. Gemini geeft die in MM:SS-formaat terug, dat je direct kunt gebruiken om naar het juiste moment in een videospeler te springen. ::: ## Alleen een fragment analyseren Je hoeft niet de hele video te laten verwerken. Met `video_metadata` knip je een fragment uit en kun je desgewenst de bemonsteringssnelheid (fps) verhogen, bijvoorbeeld om snelle handelingen beter te volgen. ```python from google.genai import types response = client.models.generate_content( model="gemini-3.5-flash", contents=types.Content( parts=[ types.Part( file_data=types.FileData(file_uri=video_file.uri, mime_type="video/mp4"), video_metadata=types.VideoMetadata( start_offset="120s", end_offset="180s", fps=5, ), ), types.Part(text="Beschrijf stap voor stap wat er in dit fragment gebeurt."), ] ), ) print(response.text) ``` ## Visuele gebeurtenissen detecteren ```python response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, """Detecteer en rapporteer: 1. Alle scene-overgangen (tijdstempel plus beschrijving) 2. Tekst die op scherm verschijnt 3. Personen die in beeld komen (beschrijving, geen identificatie) 4. Objecten of producten die prominent zichtbaar zijn Formaat: JSON-array per categorie.""", ], ) print(response.text) ``` ## Content-moderatie voor video ```python import json def moderate_video(video_path: str) -> dict: video_file = client.files.upload(file=video_path) while video_file.state.name == "PROCESSING": time.sleep(10) video_file = client.files.get(name=video_file.name) response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, """Analyseer deze video op ongepaste inhoud. Geef een score 0-100 voor elk van de volgende categorieen: - geweld (0=geen, 100=extreem) - expliciete inhoud (0=geen, 100=extreem) - hatelijke uitspraken (0=geen, 100=extreem) - misleidende informatie (0=geen, 100=zeker) Geef ook tijdstempels van problematische fragmenten. Formaat: JSON.""", ], config=types.GenerateContentConfig(response_mime_type="application/json"), ) return json.loads(response.text) ``` Gebruik `response_mime_type="application/json"` zodat het model gegarandeerd geldige JSON teruggeeft in plaats van tekst met code-fences eromheen. ## Transcriptie met video-context Anders dan pure audioverwerking kan Gemini bij video ook de context gebruiken van wat er zichtbaar is: ```python response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, """Maak een transcriptie van alles wat gezegd wordt. Voeg toe wat er tegelijk op scherm te zien is als dat relevant is voor de context. Gebruik formaat: [tijdstempel] [AUDIO] tekst / [BEELD] beschrijving""", ], ) print(response.text) ``` ## Video doorzoekbaar maken ```python import json def create_video_index(video_path: str) -> list: video_file = client.files.upload(file=video_path) while video_file.state.name == "PROCESSING": time.sleep(10) video_file = client.files.get(name=video_file.name) response = client.models.generate_content( model="gemini-3.5-flash", contents=[ video_file, """Maak een doorzoekbare index van deze video. Maak voor elk onderwerp of elke scene een entry met: - start_time (MM:SS) - end_time (MM:SS) - topic (korte titel) - description (1-2 zinnen) - keywords (array van zoekwoorden) Retourneer een JSON-array.""", ], config=types.GenerateContentConfig(response_mime_type="application/json"), ) return json.loads(response.text) ``` ## Ondersteunde formaten en limieten De onderstaande waarden gelden voor de Gemini API per juni 2026. Limieten en tokenkosten kunnen per model verschillen, dus controleer bij twijfel de officiele documentatie. | Aspect | Waarde | |---|---| | Formaten | MP4, MPEG, MOV, AVI, FLV, MPG, WMV, WebM, 3GPP | | Max bestandsgrootte (Files API) | 2 GB op de gratis laag, 20 GB op een betaalde laag | | Max duur per verzoek (1M-context) | circa 1 uur op standaardresolutie, tot 3 uur op lage resolutie | | Bemonstering | standaard 1 frame per seconde (instelbaar via `fps`) | | Tokenkosten | circa 300 tokens per seconde op standaardresolutie, circa 100 op lage resolutie | | Audio | circa 32 tokens per seconde | :::tip title="Lage mediaresolutie voor lange video's" Wil je een lange video in een keer verwerken, zet de mediaresolutie dan op laag. Dat verlaagt het tokengebruik fors (van circa 300 naar circa 100 tokens per seconde) en verdrievoudigt de hoeveelheid video die in het contextvenster past, ten koste van wat fijne visuele details. ::: :::faq ### Hoe lang duurt het verwerken van een video? Dat hangt af van de lengte en het bestand, maar verwerking gebeurt op de achtergrond nadat de upload klaar is. Poll op de bestandsstatus tot die `ACTIVE` is voordat je een prompt verstuurt; bij `FAILED` is de verwerking mislukt en moet je opnieuw uploaden. ### Kan ik een fragment of een hogere framerate kiezen? Ja. Via `video_metadata` stel je `start_offset` en `end_offset` in om alleen een deel te analyseren, en met `fps` verhoog je de bemonstering boven de standaard 1 frame per seconde, handig bij snelle handelingen. ### Kan ik een YouTube-URL meesturen in plaats van te uploaden? Ja, je kunt een publieke YouTube-URL nu rechtstreeks als `file_uri` meesturen. Op de gratis laag geldt een dagelijks plafond aan YouTube-minuten en alleen publieke video's werken. Voor privemateriaal upload je het bestand via de Files API. ### Werkt videoanalyse ook voor live streams? Nee, de Files API verwerkt opgenomen video. Voor real-time analyse gebruik je de Gemini Live API, die via een websocket-verbinding continu beeld en audio verwerkt. ### Hoe houd ik het tokengebruik onder controle bij lange video's? Zet de mediaresolutie op laag, knip met `video_metadata` alleen het relevante fragment uit, en wees specifiek in je prompt zodat het model geen onnodig lange output genereert. ### Welk model gebruik ik het beste? Voor de meeste video-analyse is `gemini-3.5-flash` een goede balans tussen snelheid en kwaliteit. Heb je nog meer redeneervermogen nodig voor complexe analyses, kijk dan naar de Pro-variant van dezelfde generatie zodra die voor jouw project beschikbaar is. :::