Demand Gen video under 10 seconds: no in-stream; upload 1 to 5 videos

Demand Gen needs 5 seconds minimum, but videos under 10 seconds can't serve on YouTube in-stream. Upload 1 to 5 per ad; crop a 9:16 master on Sume.

6 min readSume
All posts

A Demand Gen video can be as short as 5 seconds, but Google's help page says videos under 10 seconds are ineligible to serve on YouTube in-stream. Make the cut at 10 seconds or longer, and the page suggests more than 15 seconds to help maximize reach. You upload 1 to 5 videos per ad, and each must already be on YouTube.

This post adds the in-stream cutoff and the video count to the sizes and 4:5 cut already in Demand Gen video specs. Facts come from Google's video assets specifications for Demand Gen and Demand Gen specs and format requirements pages, read 2026-10-03.

What do the two Google pages say about length and count?

The two pages agree on the principle but state it differently, so both are in the table.

Demand Gen video asset facts (Google Ads Help, read 2026-10-03)
TopicWhat the page saysPage
Minimum length5 secondsVideo assets specifications
In-stream eligibilityVideos under 10 seconds are ineligible for YouTube in-streamVideo assets specifications
How many videosUpload 1 to 5 videos per adVideo assets specifications
Reach adviceUse videos longer than 15 seconds to help maximize reachVideo assets specifications
Length per orientation10 to 60 seconds for horizontal, vertical and squareSpecs and format requirements
Sizes at HD1:1 1080 x 1080, 16:9 1920 x 1080, 4:5 1080 x 1350; 9:16 is recommended for YouTube ShortsVideo assets specifications
SourceYou cannot upload an offline video; use a video already uploaded to YouTubeVideo assets specifications

Which length should I cut?

If you want in-stream inventory, 10 seconds is the floor on Google's page, and a 5 to 9 second clip trades that away. A 6-second hook is fine for other placements, but do not count on it for in-stream. Longer than 15 seconds is Google's reach advice, and 60 seconds is the top of the 10 to 60 range on the format requirements page.

On Sume, the length you can generate depends on the model. The video router docs say seedance-2.5 accepts 4 to 30 seconds at 480p, 720p and 1080p, and other models have their own ranges, with the rest capped at 15 seconds. For a master longer than 15 seconds, pin a model with a longer documented range, and read the model's supported_durations from the catalog before you submit. A 10 to 15 second clip works on most models and still clears the in-stream floor.

How do I get 4:5 and 1:1 from one 9:16 master?

Start from a 1080 x 1920 vertical master. Sume's video filter crops by fractions of the frame, so the two derived sizes are simple. A 1080 x 1350 crop is the full width and 1350 of the 1920 rows, and a 1080 x 1080 crop is 1080 of the 1920 rows. The 16:9 version is the exception: a landscape window inside a vertical frame is a thin strip, so generate that one natively.

Confirm the master is really 1080 x 1920 first, because the fractions assume it. The filter endpoint also has a free check, POST /v1/video-filter/check, that validates the program before any encode, so run it once on each crop before you pay for it.

Crops keep the source pixels. A 1080 x 1350 crop of a 1080 x 1920 frame removes about 30% of the height, so keep key text and faces inside the middle band when you design the vertical master. If the 4:5 or 1:1 look wrong, regenerate with a prompt that frames the subject centrally instead of nudging the crop.

Crop fractions from a 1080 x 1920 master (arithmetic on the sizes Google lists, read 2026-10-03)
TargetPixelsxywidthheight
4:51080 x 135000.148437510.703125
1:11080 x 108000.2187510.5625
import json, os, urllib.request

API = "https://api.sume.com/v1/video-filter"
MASTER = "https://media.sume.com/artifacts/artf_demo/master-9x16.mp4"
CROPS = {"4x5": (0.1484375, 0.703125), "1x1": (0.21875, 0.5625)}

for name, (y, h) in CROPS.items():
    body = json.dumps({"video_url": MASTER, "ops": [
        {"op": "crop", "x": 0, "y": y, "width": 1, "height": h}]}).encode()
    req = urllib.request.Request(API, data=body, method="POST", headers={
        "Authorization": "Bearer " + os.environ["SUME_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "demand-gen-" + name})
    with urllib.request.urlopen(req) as res:
        print(name, res.status)

What about the other half of the job?

Sume produces the MP4s; Google Ads takes only videos that live on YouTube (the upload rule is in this post). Upload each cut to YouTube, then pick them in the ad. Sume does not run the Demand Gen campaign, and it does not predict which cut Google will serve where. If you want to compare versions fairly, hold everything but one variable constant.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume