Analyze Video
Summarize, transcribe, or reason over videos from a URL with Google Gemini, no API key required.
Totalum exposes Google Gemini's video understanding through a single endpoint. You give it a video URL and a prompt, and it returns Gemini's response describing or analyzing the video.
For installation and usage of the Totalum SDK or API, see the Installation Guide.
No Gemini account or API key needed — Totalum handles the integration for you.
#Supported video sources
The endpoint accepts three kinds of videoUrl:
| Source | How it works | File size limit |
|---|---|---|
YouTube (youtube.com/watch?v=…, youtu.be/…, shorts, embed) | Gemini ingests the URL server-side. Nothing is downloaded by Totalum. Fastest path. | n/a |
Vimeo (vimeo.com/…) | Public videos only. Totalum resolves the progressive download URL from Vimeo's player config, then streams it to Gemini. | 100 MB |
Direct https URL to a video file (.mp4, .webm, .mov, etc.) | Totalum streams the file from the URL to Gemini. The host must serve the bytes with a video/* content-type. | 100 MB |
Only https:// URLs are accepted. http:// URLs are rejected. Private/internal IPs (localhost, *.local, *.internal, private ranges) are also blocked for security.
#Recommended video duration
Gemini's processing time scales with the length of the video. For a good user experience and to avoid timeouts, stay within these bounds:
| Source | Recommended duration | Notes |
|---|---|---|
| Direct URL | 1 second to 5 minutes | Longer videos increase the chance of download/upload timeouts, especially on slower CDNs. |
| YouTube | 1 second to 30 minutes | Up to ~1 hour can work but processing time grows to several minutes. Beyond ~1h 15m, Gemini typically rejects the URL. |
| Vimeo | 1 second to 5 minutes | Same constraints as direct URL (Vimeo is downloaded). |
Videos longer than these recommendations may still work, but you should expect:
- Multi-minute response times.
- Higher chance of
VIDEO_DOWNLOAD_TIMEOUT(direct/Vimeo) orYOUTUBE_VIDEO_UNAVAILABLE(YouTube). - More tokens billed.
#Analyze a video
const result = await totalumClient.gemini.analyzeVideo({
videoUrl: 'https://www.youtube.com/watch?v=jNQXAC9IVRw',
prompt: 'In one sentence, summarize what happens in this video.',
});
const { model, response } = result.data;
// model: the Gemini model that produced the response (e.g. 'gemini-3-flash-preview')
// response.candidates[0].content.parts[0].text: the generated text
const text = response.candidates[0].content.parts[0].text;
console.log(text);Minimal example:
const result = await totalumClient.gemini.analyzeVideo({
videoUrl: 'https://example.com/clip.mp4',
prompt: 'What products appear in this video?',
});
console.log(result.data.response.candidates[0].content.parts[0].text);#Parameters
| Field | Type | Required | Description |
|---|---|---|---|
videoUrl | string | yes | Public https URL — YouTube, Vimeo, or direct video file. |
prompt | string | yes | Free-form instruction for Gemini (e.g. "Summarize this video", "Transcribe what is said", "List every product visible"). |
highQuality | boolean | no | Use gemini-3.1-pro-preview instead of flash for harder reasoning tasks (~4× cost). Default: false. |
mimeType | string | no | MIME type hint (e.g. "video/mp4"). Only needed when the host doesn't return a video/* content-type and the URL has no recognized extension. Must start with video/. |
#Higher-quality model
For complex visual reasoning where the default flash model is not enough, set highQuality: true:
const result = await totalumClient.gemini.analyzeVideo({
videoUrl: 'https://example.com/security-camera-clip.mp4',
prompt: 'Identify every person visible and describe what each is doing.',
highQuality: true, // uses gemini-3.1-pro-preview (more expensive, more accurate)
});#Error handling
The endpoint returns the standard { errors, data } shape. On failure, errors.errorCode tells you what went wrong. The most common codes:
errorCode | Meaning |
|---|---|
MISSING_VIDEO_URL / MISSING_PROMPT | Required field is empty. |
INVALID_VIDEO_URL / INVALID_VIDEO_URL_PROTOCOL | URL is malformed or not https://. |
SSRF_BLOCKED | URL points at a private/internal IP or hostname. |
VIDEO_TOO_LARGE | File is over the 100 MB cap. |
VIDEO_URL_NOT_FOUND / VIDEO_URL_FORBIDDEN | Source host returned 404 / 403. |
VIDEO_DOWNLOAD_TIMEOUT | Source host is too slow for the configured download timeout. |
VIDEO_URL_NOT_A_VIDEO | URL did not return a video file (no video/* content-type, no recognized extension, no mimeType hint). |
YOUTUBE_VIDEO_UNAVAILABLE | YouTube video is private, deleted, age-restricted, region-locked, or longer than Gemini's limit. |
VIMEO_VIDEO_NOT_FOUND / VIMEO_VIDEO_RESTRICTED | Vimeo video doesn't exist / is private, password-protected, or domain-locked. |
VIMEO_NO_PROGRESSIVE_URL | Vimeo video is HLS/DASH-only and can't be downloaded directly. |
GEMINI_CONTENT_BLOCKED | Gemini's safety filter blocked the response. |
GEMINI_QUOTA_EXCEEDED | Gemini API quota or rate limit exceeded. |
const result = await totalumClient.gemini.analyzeVideo({
videoUrl: 'https://example.com/missing.mp4',
prompt: 'Describe this.',
});
if (result.errors) {
if (result.errors.errorCode === 'VIDEO_TOO_LARGE') {
// Tell the user to shorten or compress the video
} else if (result.errors.errorCode === 'YOUTUBE_VIDEO_UNAVAILABLE') {
// Suggest a shorter or public YouTube URL
} else {
// Generic error handling
console.error(result.errors.errorMessage);
}
}