Lint a video against TikTok, Reels, Feed and Shorts limits in Python

A 24-line Python check for duration, file size and average bitrate against the limits TikTok, Meta and YouTube publish, plus where Sume jobs fit before it.

4 min readSume
All posts

What the check covers

Most upload rejections come from three numbers: length, file size and, for TikTok, average bitrate. This script checks those for five targets using the limits on each platform's own page, read 2026-10-09. It makes no network calls, so you can run it on a file's reported duration and size before you spend an upload or a Sume job.

Limits encoded in the script, from the platform pages read 2026-10-09
TargetMax lengthMax sizeMin bitrate
TikTok non-Spark ad10 minutes (600 s)500 MB516 kbps
Instagram Reels ad15 minutes (900 s)4 GBnot listed
Instagram Feed ad60 minutes (3,600 s)4 GBnot listed
Facebook Feed ad241 minutes (14,460 s)4 GBnot listed
YouTube Short3 minutes (180 s)not listednot listed

The script

Run it with plain Python 3. Sizes use decimal megabytes, so the average bitrate is megabytes times 8,000 divided by seconds. The 4 GB cap is written as 4,000 MB, which is a conservative reading because the platform pages do not say whether GB is decimal or binary.

LIMITS = {  # source: platform pages read 2026-10-09
    "tiktok_ad": {"max_s": 600, "max_mb": 500, "min_kbps": 516},
    "reels_ad": {"max_s": 900, "max_mb": 4000},
    "ig_feed_ad": {"max_s": 3600, "max_mb": 4000},
    "fb_feed_ad": {"max_s": 14460, "max_mb": 4000},
    "youtube_short": {"max_s": 180},
}

def lint(target, seconds, size_mb):
    rule = LIMITS[target]
    problems = []
    if seconds > rule["max_s"]:
        problems.append(f"{seconds}s is over {rule['max_s']}s")
    if "max_mb" in rule and size_mb > rule["max_mb"]:
        problems.append(f"{size_mb} MB is over {rule['max_mb']} MB")
    kbps = size_mb * 8000 / seconds
    if kbps < rule.get("min_kbps", 0):
        problems.append(f"average {kbps:.0f} kbps is under {rule['min_kbps']}")
    return problems or ["ok"]

print(lint("tiktok_ad", 600, 600))
print(lint("tiktok_ad", 600, 30))
print(lint("youtube_short", 181, 40))

What it prints

The three sample calls return a size problem for a 600 MB, 10-minute TikTok file, a bitrate problem for a 30 MB, 10-minute file (30 x 8,000 / 600 = 400 kbps, under the 516 floor), and a length problem for a 181-second Short. A file that passes everything returns ok.

Where Sume fits before the check

Get the duration and presence of audio with video inspect, which returns a probe for a clip that is already on Sume's media host. Size is a property of the delivered file, so read it from the artifact you download. If the length is wrong, a video trim job cuts a new MP4 for $0.02, and the jobs follow the usual submit, poll and read pattern described on the jobs and results page.

The script does not check geometry, container, frame rate or audio codec, all of which these platforms also list. Add those as the platforms' pages require; the Meta pages, for example, list H.264, square pixels, fixed frame rate and stereo AAC at 128 kbps or higher.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume