**Title:** Regression: `videoMetadata` clipping on YouTube URLs no longer clips **audio** (frames still clipped) — ~20× token inflation on long videos
**Environment**
- API: `generativelanguage.googleapis.com` `v1beta` `generateContent`(and Batch API — both affected identically)
- SDK: `google-genai` 2.16.0 (Python)
- Models tested: `gemini-3.1-flash-lite`, `gemini-3.7-flash` — identical behavior
- Two API keys from two different GCP projects — identical behavior
- Regression window: between **2026-08-18 06:00 UTC** (last known-good production run) and **2026-08-19 12:00 UTC** (first bad run). No client-side changes in between (same SDK version, same request builder).
**Summary**
When passing a YouTube URL via `FileData(file_uri=…)` together with
`VideoMetadata(start_offset=…, end_offset=…)`, the clipping interval is now
applied to **video frames only**. The **audio track of the entire video** is
included in every request regardless of the offsets. Until ~Aug 18 the same
requests were correctly clipped to the window (both frames and audio).
Uploading the same media through the **File API is not affected** — offsets
clip both frames and audio correctly there.
**Repro (public 19s video, `media_resolution=LOW`)**
```python
from google import genai
from google.genai import types
client = genai.Client(api_key=“…”)
part = types.Part(
file_data=types.FileData(file_uri=“xxx”), # 19s
video_metadata=types.VideoMetadata(start_offset=“5s”, end_offset=“10s”), # 5s window
)
resp = client.models.generate_content(
model=“gemini-3.1-flash-lite”,
contents=[types.Content(parts=[part, types.Part(text=“Describe what you see and hear.”)])],
config=types.GenerateContentConfig(
media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW),
)
print(resp.usage_metadata)
```
- **Expected** (5s window @ LOW): ≈ 5 s × (66 frame-tok + audio-tok) ≈ **~500 tokens**
- **Actual**: `prompt_token_count=816`, `VIDEO=794` ≈ 5 s × 66 **+ 19 s × 25**
→ window frames + **full-video audio**
**The arithmetic holds exactly across every video we tested:**
| Video (public) | Length | Window | VIDEO tokens | = window×66 + full×25 |
|---|---|---|---|---|
| jNQXAC9IVRw | 19 s | 5 s | 794 | 330 + 464 ✓ |
| dQw4w9WgXcQ | 213 s | 10 s | 5,989 | 660 + 5,325 ✓ |
| (livestream VOD) | 7,650 s | 60 s | 195,214 | 3,960 + ~191,250 ✓ |
| (livestream VOD) | 7,650 s | 10 s | 191,914 | 660 + ~191,250 ✓ |
Note the last two rows: shrinking the window from 60 s to 10 s removes exactly
50 × 66 frame tokens — offsets *are* reaching the server and *are* applied to
frames. Only the audio ignores them.
**Control — File API is clean:** the same 10 s window on a 60 s file uploaded
via the File API yields `VIDEO=910` ≈ 10 s × 91 — frames *and* audio clipped.
**Ruled out:** model (lite = flash, token-identical), video source (2005 upload,
music video, livestream archives — all affected), explicit `mime_type` on
`FileData` (with/without — identical), API key / GCP project (two projects —
identical).
**Impact**
- Windowed pipelines over long videos pay ~20× input tokens per call
(e.g. 198k instead of ~9k for a 90 s window on a 2 h video), silently. - Worse than cost: judgment corruption. Prompts scoped to a window
(“evaluate this moment”) now receive the entire stream’s audio as context,
which changes model verdicts. Our detection pipeline’s verification stage
went from a ~19 % rejection rate to rejecting **101/101** candidates,
because “is this second a top-10 moment?” was suddenly evaluated against
the whole 2-hour stream it could hear.
**Questions**
- Is this an intentional behavior change or a regression? We could not find
any changelog entry. - We notice clipping intervals are documented under the Legacy
generateContent docs but absent from the Interactions API docs — is
clipping being deprecated? If so, what is the recommended way to analyze a
time window of a YouTube video without paying full-video audio tokens?
repro.py(附件用,完整可跑版)
```python
“”“Repro: YouTube URL + videoMetadata offsets → full-video audio tokens.
Usage: GEMINI_API_KEY=… python repro.py”“”
import os
from google import genai
from google.genai import types
client = genai.Client(api_key=os.environ[“GEMINI_API_KEY”])
CASES = [
(“xxxx_url”, 19, (5, 10)),
(“xxxx_url”, 213, (10, 20)),
]
for url, dur, (a, b) in CASES:
part = types.Part(
file_data=types.FileData(file_uri=url),
video_metadata=types.VideoMetadata(start_offset=f"{a}s", end_offset=f"{b}s"))
resp = client.models.generate_content(
model=“gemini-3.1-flash-lite”,
contents=[types.Content(parts=[part, types.Part(text=“Describe what you see and hear.”)])],
config=types.GenerateContentConfig(
media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW))
um = resp.usage_metadata
win = b - a
print(f"{url} len={dur}s window={win}s"
f" prompt_tokens={um.prompt_token_count}"
f" expected≈{win*98} got_formula≈{win*66 + dur*25}")