The AI video looks finished in the editor. The export progress bar reaches 100 percent. That still leaves a separate question: does the actual file meet the delivery contract, and can its selected media streams decode through to the end?
Build a small local gate that checks dimensions, square pixels, expected container duration and required audio, then performs a decode pass. This is useful before handing a business promo to a client or uploading it. It supplements watching the finished video; it cannot judge the story, voice or brand.
Write the contract before checking the file
Fictional Orbit Studio prepares an AI-assisted product teaser. For this deliberately tiny test, its delivery contract is one 192×108 video stream, square pixels, roughly two seconds, and one audio stream. The unusual low resolution makes the fixtures quick to generate. Replace these authored example requirements with your actual delivery specification; they are not a social platform’s recommended settings.
Keep “audio stream exists” separate from “the soundtrack is correct.” A silent track can satisfy the first condition. Likewise, stored dimensions do not establish that captions are readable or that a platform will display the intended crop.
Use metadata and decoding as separate checks
FFprobe’s official 8.1.1 documentation describes machine-readable media information and selective entries. Here, its JSON supplies stream types, dimensions, pixel shape and container duration. Those fields let the program reject an obvious contract mismatch without rendering a new deliverable.
Then the checker maps the video and optional audio into an FFmpeg null output. It does not use stream copy: the selected streams are decoded, with no output video saved. FFmpeg’s official documentation describes explicit stream selection and -xerror, which stops on errors. The wrapper also rejects error-level stderr rather than treating a zero exit alone as success.
| Actual fixture or contract | Observed decision | Reason |
|---|---|---|
| Two-second test pattern with tone | Pass | Metadata matched; selected video/audio decoded |
| Same size, no audio; audio required | Reject | Required stream absent |
| No audio; silent delivery explicitly allowed | Pass | Video decoded under a different contract |
| Landscape file; portrait dimensions expected | Reject | Dimensions mismatch |
| Two-second file; twelve seconds expected | Reject | Container duration mismatch |
| Text file named fake.mp4 | Reject | Probe failed; extension did not make it media |
Save the checker
Prerequisites: Python 3.14 and FFmpeg/FFprobe on PATH. This run used the existing Windows Gyan full build 8.1.1; the tests need its libx264 video encoder, AAC audio encoder and lavfi test sources. No Python packages or model downloads are needed. Install binaries from a source you trust under your normal software policy; the code does not install them for you.
Save this as delivery.py. It accepts an existing local file up to 50 MB, one video, at most one audio and no other stream types. Container duration must be within 0.10 seconds of the expected value. These are explicit example policies. Missing metadata, tool failures and timeouts are failures to investigate, not approvals.
"""Local two-stream media delivery check, not creative or platform approval."""
from pathlib import Path
import json
import math
import shutil
import subprocess
def tool(name):
found = shutil.which(name)
if not found:
raise RuntimeError(f'{name} must be installed and on PATH')
return found
def check(path, width=192, height=108, seconds=2, require_audio=True):
if any(type(n) is not int or n <= 0 for n in (width, height)):
raise ValueError('Expected dimensions must be positive integers')
if type(seconds) not in (int, float) or not math.isfinite(seconds) or seconds <= 0:
raise ValueError('Expected seconds must be positive and finite')
if type(require_audio) is not bool:
raise ValueError('require_audio must be boolean')
source = Path(path).resolve(strict=True)
if not source.is_file() or not 0 < source.stat().st_size <= 50_000_000:
raise ValueError('Use a nonempty local file up to 50 MB')
probe = subprocess.run([tool('ffprobe'), '-v', 'error', '-show_entries',
'stream=codec_type,width,height,sample_aspect_ratio:format=duration',
'-of', 'json', str(source)], capture_output=True, text=True, timeout=30)
if probe.returncode or probe.stderr.strip():
raise ValueError('Probe failed: ' + probe.stderr.strip())
info = json.loads(probe.stdout)
streams = info.get('streams', [])
video = [s for s in streams if s.get('codec_type') == 'video']
audio = [s for s in streams if s.get('codec_type') == 'audio']
if len(video) != 1 or len(audio) > 1 or len(streams) != len(video) + len(audio):
raise ValueError('Policy requires one video, at most one audio, no other streams')
if require_audio and not audio:
raise ValueError('Required audio stream missing')
v = video[0]
if (v.get('width'), v.get('height')) != (width, height):
raise ValueError('Dimensions do not match the delivery contract')
if v.get('sample_aspect_ratio') != '1:1':
raise ValueError('Policy requires explicit square pixels')
duration = float(info.get('format', {}).get('duration', 'nan'))
if not math.isfinite(duration) or abs(duration - seconds) > 0.10:
raise ValueError('Container duration outside 0.10 second tolerance')
decode = subprocess.run([tool('ffmpeg'), '-v', 'error', '-xerror', '-nostdin',
'-i', str(source), '-map', '0:v:0', '-map', '0:a:0?', '-f', 'null', '-'],
capture_output=True, text=True, timeout=120)
if decode.returncode or decode.stderr.strip():
raise ValueError('Decode failed: ' + decode.stderr.strip())
return {'passed': True, 'width': width, 'height': height,
'sample_aspect_ratio': '1:1', 'container_seconds': duration,
'audio_present': bool(audio), 'selected_streams_decoded': True}
Run the example, including the bad deliveries
Save the tests as test_delivery.py. They generate two short MP4 files in a new temporary directory and delete that directory on normal test cleanup. Your real videos are not modified.
from pathlib import Path
import json
import subprocess
import tempfile
import unittest
from delivery import check, tool
class DeliveryTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.tmp = tempfile.TemporaryDirectory(prefix='orbit-video-')
cls.addClassCleanup(cls.tmp.cleanup)
cls.root = Path(cls.tmp.name)
for sound, name in ((True, 'sound.mp4'), (False, 'silent.mp4')):
args = [tool('ffmpeg'), '-v', 'error', '-nostdin', '-f', 'lavfi',
'-i', 'testsrc2=size=192x108:rate=24:duration=2']
if sound:
args += ['-f', 'lavfi', '-i', 'sine=frequency=440:sample_rate=48000:duration=2']
args += ['-c:v', 'libx264', '-pix_fmt', 'yuv420p']
if sound:
args += ['-c:a', 'aac']
args += [str(cls.root / name)]
r = subprocess.run(args, capture_output=True, text=True, timeout=60)
if r.returncode:
raise RuntimeError(r.stderr)
(cls.root / 'fake.mp4').write_text('not a video', encoding='utf-8')
def test_complete_delivery(self):
r = check(self.root / 'sound.mp4')
self.assertTrue(r['selected_streams_decoded'])
self.assertTrue(r['audio_present'])
print('SAMPLE_RESULT=' + json.dumps(r, sort_keys=True))
def test_missing_audio(self):
with self.assertRaisesRegex(ValueError, 'audio stream missing'):
check(self.root / 'silent.mp4')
def test_silent_contract(self):
self.assertFalse(check(self.root / 'silent.mp4', require_audio=False)['audio_present'])
def test_wrong_dimensions(self):
with self.assertRaisesRegex(ValueError, 'Dimensions'):
check(self.root / 'sound.mp4', width=108, height=192)
def test_wrong_duration(self):
with self.assertRaisesRegex(ValueError, 'duration'):
check(self.root / 'sound.mp4', seconds=12)
def test_fake_container(self):
with self.assertRaisesRegex(ValueError, 'Probe failed'):
check(self.root / 'fake.mp4')
def test_missing_file(self):
with self.assertRaises(FileNotFoundError):
check(self.root / 'absent.mp4')
def test_invalid_contract(self):
for kwargs in ({'width': True}, {'seconds': float('nan')}, {'require_audio': 'yes'}):
with self.subTest(kwargs=kwargs):
with self.assertRaises(ValueError): check(self.root / 'sound.mp4', **kwargs)
if __name__ == '__main__':
unittest.main()
In the folder containing both files, run:
python -X utf8 -m unittest -v test_delivery.py
Eight test methods passed: the complete fixture, required missing audio, explicitly optional audio, wrong dimensions, wrong duration, fake media, a missing file and invalid contract values. The final article’s files were extracted and this exact test command was executed again in a disposable reader directory. The successful fixture’s SAMPLE_RESULT was:
{
"audio_present": true,
"container_seconds": 2.0,
"height": 108,
"passed": true,
"sample_aspect_ratio": "1:1",
"selected_streams_decoded": true,
"width": 192
}
For your own file, call check from a local Python program with the agreed width, height, duration and audio policy. A long real clip can exceed the 120-second decode timeout; that result requires a deliberately adjusted processing budget, not bypassing the decode. A returned record is a technical checkpoint for this policy, not permission to upload or send.
Keep a delivery record that survives the chat
Store the source export identity, checker version, exact contract, tool versions and check result with the campaign handoff. Hash the final delivery file in your real process so a later re-export cannot inherit an earlier file’s pass. Hashing and a durable release ledger are recommendations here; this example does not implement them.
After any edit or re-export, check the actual replacement file. Watch the whole result at its intended display size and listen to the soundtrack. Confirm the ending, caption placement, spoken words, product details and selected creative version. Those judgments are separate from the automated stream check. For adjacent workflows, see building a promo with FFmpeg and the creative campaign release review.
What a pass does not establish
The gate does not check constant frame rate, per-frame timing, rotation/display matrices, color/HDR behavior, loudness, silence, audio/video synchronization, visual artifacts, codec acceptance on a particular platform, or creative approval. The duration is container metadata, not an independently counted presentation timeline. A decoder can conceal some damaged data without reporting an error; this is not a proof of perfect file integrity.
The tests exercise a valid full decode and meaningful contract/probe rejections. They do not inject every possible compressed-payload corruption, exercise the non-square-pixel or multi-stream rejection branches, or validate playback in a browser, phone, editor or delivery platform. The local-file limit and subprocess timeout are operational bounds, not a sandbox for hostile media. Use your established isolation and update practices for untrusted files.
No AI generation service, client campaign, upload, paid API or production delivery system was exercised. The business and requirements are fictional. Jason Ead publishes AlgoThoughts AI News and connects practical creative engineering with My Biz Heroes: websites, automation, workflows, AI tools and training. Explore Jason’s work. The cover is generated conceptual art; the interior table reports the actual fixture results.
