Skip to content

feat(core): audible videos in preview web audio, audio groups, meters and carve (2/8) - #4814

Merged
vanceingalls merged 13 commits into
mainfrom
aov/02-audible-video-audio-engine
Oct 2, 2026
Merged

vanceingalls merged 13 commits into
mainfrom
aov/02-audible-video-audio-engine

Conversation

@vanceingalls

@vanceingalls vanceingalls commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

An audible <video> now takes part in the audio engine the same way an <audio> does: it can join audio groups (preview and render), gets the audio fx section, shows the meters, and can be a carve voice.

Changes

  • core: isAudibleVideoElement predicate (@hyperframes/core/audible-video). Only data-has-audio="true" counts as audible in the runtime and lint.
  • runtime: preview routes a <video> into Web Audio (extending fix(core): a video's sound plays at its boosted volume in the preview #4746's joinsWebAudio) when its volume is > 1 or it has data-fx-chain, data-automation or data-audio-group. A plain video at unity is not routed.
  • core / engine: audio groups include audible videos. The mixer honours hidden groups for auto-detected video audio.
  • editing affordances: the audio fx section is offered on audible videos.
  • studio: meters show when a project has an audible video. Audible videos can be carve voices and can join audio groups (track header group UI). The keep-sound cutout keeps the authored src and loop and reports its status honestly.

Testing

Static gates on the layer tip: bun install, bun run build, tsc --noEmit for every touched package (0 errors), oxlint and oxfmt --check on files changed vs main (clean), gen:skills-manifest --check (in sync), scripts/comment-ratchet.mjs (ok).

  • core 3785, lint 752, sdk 565, studio 6220. All pass.
  • engine 2007 pass; same env-only libaom-av1 failure as on main.

Notes

Part of the audio-on-video stack. See the bottom PR for the overview.

🤖 Generated with Claude Code

Before

before

After

after

Design panel on a video with sound: Audio FX row added.

@vanceingalls
vanceingalls added this pull request to stack #4822 October 1, 2026 01:24

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At f7bcd36fd38821885a46a01eb5edb3df740f6e44 against #4813’s exact head, the new audible-video Web Audio/group path has two preview mismatches: ramped grouped videos bypass the group processor despite export applying it, and video-only native audio turns on meters that read silence. Both concrete combinations are inline. The changed-comment check is also red on an introduced 46-line block in webAudioRoute.ts; shorten it or follow the repository’s explicit exception rule. Other reviewed audio group/export paths and CI checks looked sound, but no live-browser audio comparison was run. No merge/release action. — Jerrai

Comment thread packages/core/src/runtime/init.ts Outdated
(Number.parseFloat(el.dataset.volume ?? "") > 1 ||
el.hasAttribute("data-fx-chain") ||
el.hasAttribute("data-automation") ||
el.hasAttribute("data-audio-group")));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This newly routes grouped audible videos toward Web Audio, but the schedule pass at init.ts:4813 still continues for every rate-automation lane before media-element capture. A ramped video in a group therefore plays native audio without that group's fader/mute/FX in preview, while the export collector now attaches the group and rate curve (audioMixer.ts:610–623,645–651). Please handle this combination or disallow it consistently, and add a ramped-group preview/export regression.

/** The meters appear only for a project with at least one audio clip, audible video or group. */
export function hasProjectAudio(elements: readonly TimelineElement[]): boolean {
return elements.some(
(el) => isAudioTimelineElement(el) || el.hasAudio === true || el.audioGroup !== undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enables meters for a project containing only a plain audible video, but at unity with no FX/group that video deliberately remains on native output (init.test.ts:5287–5294), not a Web Audio source. WebAudioTransport.readLevels() reads only the master/group taps, so the visible meters sit at zero while the video is audibly playing. Please either meter native video output too or avoid advertising a meter for that unsupported route; test a video-only unity-gain preview.

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Edit accuracy: 951 passing here, 951 on the base branch

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (2)

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact f11504920c2b6e07446db55da57682ebd305b405. The earlier audio-code holds are repaired: rate-ramped grouped media now reaches Web Audio capture before the decoded-buffer-only rate restriction, and runtime routing plus Studio meter visibility share the eligibility rule, so a plain native-unity video no longer advertises unreadable meters. New regressions exercise the ramp/group capture and meter/native branches. Comments and runtime checks are green; I found no remaining code blocker in this delta, but have not run a live preview/export audio comparison.

The required Studio/player Before/After capture check still fails, and no explicit per-PR evidence waiver has been routed. Accordingly I am not approving this revision; the prior CHANGES_REQUESTED decision remains until capture evidence or waiver is provided and the live head is rechecked. The stack's other holds remain separate. No merge/release action. — Jerrai

@vanceingalls
vanceingalls force-pushed the aov/02-audible-video-audio-engine branch from f115049 to d195097 Compare October 1, 2026 09:47

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At exact d195097ec8d190218f2442fdc023347de3333700, the latest meter-visibility change uses the same Web Audio eligibility as the audible-video routing; the previous ramped-group and native-unity meter code holds were repaired on the predecessor. Current-head relevant tests, Comments and file-size checks ran green. I found no new code blocker in this bounded successor review. I am not approving: the Studio and player captures job ran and failed for missing Before/After visual evidence, with no per-PR waiver. My earlier CHANGES_REQUESTED review therefore still governs GitHub. Provide current-revision Studio/player captures or an explicit waiver; hosted test passes do not substitute for rendered audio/visual validation. No live playback, merge or release by this reviewer. — Jerrai

@vanceingalls
vanceingalls force-pushed the aov/02-audible-video-audio-engine branch from d195097 to cd13d54 Compare October 1, 2026 20:01

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed #4814 at cd13d54b against stacked parent #4813 aefd6415. The prior audible-video Web Audio eligibility/preview-meter repair remains in the shared predicate; the three PR-scope blobs changed since my earlier tip include main’s GSAP duration-floor work alongside this routing. No new blocker found in those sampled paths. The required Studio/player Before/After captures check is still FAILED and no per-PR waiver is recorded, so no approval; the edit-accuracy and Comments checks are green. No local tests, playback or render. — Jerrai

@vanceingalls
vanceingalls force-pushed the aov/02-audible-video-audio-engine branch from cd13d54 to 71244f6 Compare October 1, 2026 23:32

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed this layer against the exact #4813 head. Its 44-file layer patch is blob-identical to the prior code-cleared revision across the rebase. Ramped grouped video is captured before the decoded-buffer-only rate restriction; meter visibility shares the Web Audio eligibility predicate, excluding native-unity video. The earlier changed-comment hold is also clear, and the capture check passes. This supersedes my earlier code hold, not any pending or failing CI merge gate. — Jerrai

Base automatically changed from aov/01-sound-on-video to main October 2, 2026 00:10
@mintlify

mintlify Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Oct 2, 2026, 2:10 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@jerrai-bot-heygen jerrai-bot-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-pinned after #4813's squash to exact 6147f6ee9. Four-way comparison of the old approved parent→head and new main→head reports the same 44 changed paths with byte-identical per-file patch hunks. The new main and old parent have identical blobs for all 44 layer paths, so this rebase neither lost a layer edit nor reconciled a concurrent edit on those paths. The audible-group/Web Audio meter fix remains in this layer. Capture check succeeded; remaining CI is a separate merge gate. This is a code approval only, not a merge or release authorization. — Jerrai

@vanceingalls
vanceingalls added this pull request to the merge queue Oct 2, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 2, 2026
vanceingalls and others added 7 commits October 1, 2026 18:53
…ector

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eview

An audible <video> joins the Web Audio schedule, hidden-toggle and
group-capture passes when it needs a gain el.volume cannot express: a
boost above unity, an fx chain, automation, or an audio group. A plain
audible video at unity stays on native output. The clock master stays
audio-only; a video whose capture fails stays on native output (never
decoded, never failed closed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
resolveAudioGroups, audioGroupOf, group render ids, the engine mixer and
the audio_group_no_members lint rule accept an audible <video>. A hidden
group drops its video members from the mix; muted videos stay inert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EditableElementFacts gains hasAudio; studio and sdk derive it from muted and data-has-audio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drops the video refusal; grouping and group audition count audible videos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vanceingalls and others added 6 commits October 1, 2026 18:53
Muted videos that declare data-has-audio are no longer mixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…utout sound

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…review

A rate lane skipped Web Audio entirely, so a ramped video or audio clip in a
group played native output without the group's fader, mute or FX while the
export applied them. Only the decoded-buffer fallback cannot follow a rate
curve; the media-element capture can, so the skip now guards that fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plain audible video at unity stays on native output, which the meters
cannot read, so it no longer advertises them. The runtime's join rule and the
meter gate now share audibleVideoNeedsWebAudio (core/audible-video).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vanceingalls
vanceingalls force-pushed the aov/02-audible-video-audio-engine branch from 6147f6e to 3c9913e Compare October 2, 2026 02:05
@vanceingalls
vanceingalls added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit 3c299ac Oct 2, 2026
86 checks passed
@vanceingalls
vanceingalls deleted the aov/02-audible-video-audio-engine branch October 2, 2026 02:43

This branch was successfully deployed

1 active deployment
staging - docs — 3c9913e3 Deployed Oct 2, 2026 by mintlify[bot]
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.

2 participants