Skip to content

Bring spots up to streaming level - #307

Merged
ralyodio merged 2 commits into
masterfrom
ads-video-loudness
Sep 25, 2026
Merged

ralyodio merged 2 commits into
masterfrom
ads-video-loudness

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Renders were landing around -30 dB mean. A synthesised read comes back quiet and a five second spot has no room to ride the gain, so the advert arrived audible only to someone who had already turned everything up for the programme — which is the one moment it must not ask them to.

Measured on a real render pulled from the queue:

mean true peak
before -30.0 dB —
after -20.0 dB -1.6 dB

-16 LUFS is what streaming platforms normalise to, so a spot now arrives at the same loudness as whatever it interrupted.

Two details that are the point rather than incidental:

  • The true-peak ceiling matters as much as the target. Without it, lifting a quiet source pushes its peaks into clipping, and a clipped voice is worse than a quiet one.
  • On the bed path it normalises the finished mix, not the voice on its own. Normalising the voice first would move it relative to the bed and undo the -16 dB the bed was deliberately placed at. A test asserts the filter order.

A silent spot gains no audio filter at all.

🤖 Generated with Claude Code

Renders were landing around -30 dB mean. A synthesised read comes back quiet and
a five second spot has no room to ride the gain, so the advert arrived audible
only to someone who had already turned everything up for the programme, which is
the one moment it must not ask them to.

-16 LUFS is what streaming platforms normalise to, so a spot now arrives at the
same loudness as whatever it interrupted. Measured on a real render from the
queue: -30.0 dB mean before, -20.0 after, true peak -1.6.

The true-peak ceiling matters as much as the target: without it, lifting a quiet
source pushes its peaks into clipping, and a clipped voice is worse than a quiet
one.

On the bed path it normalises the finished mix rather than the voice on its own,
which would have moved the voice relative to the bed and undone the -16 dB the
bed was deliberately placed at.
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

48 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 31 | LOW: 15

Severity Rule Location
HIGH tls-verification-disabled lib/onion.ts:48
HIGH secret-generic-credential lib/sp/platforms/facebook.ts:32
MEDIUM js-unescaped-html-sink app/(app)/dashboard/admin/email-broadcast/EmailBroadcastForm.tsx:125
MEDIUM js-unescaped-html-sink app/(app)/dashboard/projects/[id]/autoblog/articles/[articleId]/page.tsx:214
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:67
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:97
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:104
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:110
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:186
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:190
MEDIUM js-unescaped-html-sink app/c/[project]/[slug]/page.tsx:77
MEDIUM js-unescaped-html-sink app/c/[project]/page.tsx:57
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:228
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:285
MEDIUM js-unescaped-html-sink app/layout.tsx:129
MEDIUM js-open-redirect app/login/form.tsx:39
MEDIUM js-unescaped-html-sink app/r/[token]/page.tsx:176
MEDIUM js-open-redirect app/signup/form.tsx:43
MEDIUM js-open-redirect components/billing/buy-credits-modal.tsx:98
MEDIUM js-unescaped-html-sink components/json-ld.tsx:8
MEDIUM js-unescaped-html-sink components/report/markdown-view.tsx:15
MEDIUM js-unescaped-html-sink lib/careers/page-templates.ts:198
MEDIUM js-dynamic-code-execution lib/crawl-limits.ts:67
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:41
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:324
MEDIUM redos-nested-quantifier lib/lx/articleGen.ts:99
MEDIUM redos-nested-quantifier lib/tracker/agent-gate.ts:61
MEDIUM sh-remote-script-execution prober/deploy/provision.sh:30
MEDIUM sql-template-interpolation scripts/detect-slot-themes.ts:31
MEDIUM sql-template-interpolation scripts/purge-constructed-keywords.ts:163
MEDIUM sql-template-interpolation scripts/purge-offniche-keywords.ts:124
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:14
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:24
LOW secret-generic-credential app/(marketing)/docs/autoblog-webhook/page.tsx:145
LOW secret-generic-credential lib/sp/platforms/linkedin.ts:25
LOW js-dynamic-code-execution tests/careers-page-templates.test.ts:21
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:19
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:69
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:51
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:52
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:20
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:24
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:25
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:26
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:31
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:35
LOW secret-generic-credential tests/contract/posthog-integration.test.ts:13
LOW secret-generic-credential tests/lead-campaign.test.ts:16

Snippets are redacted; ThreatCrush never prints matched credential material.

The assertion pinned -af to exactly "apad", which loudness normalisation
legitimately changes. What it meant to protect is that a spot without a bed
stays on a simple filter rather than switching to the mixer, and that the pad
still runs before anything else.
@ralyodio
ralyodio merged commit 016ed03 into master Sep 25, 2026
10 checks passed
@ralyodio
ralyodio deleted the ads-video-loudness branch September 25, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant