Merge pull request #926 from heygen-com/fix/ci-chrome-pin-and-psnr-harness

fix(ci): pin chrome-headless-shell + clamp PSNR checkpoint to a valid frame
This commit is contained in:
James Russo
2026-05-18 16:51:29 -04:00
committed by GitHub
2 changed files with 16 additions and 8 deletions
+6 -1
View File
@@ -53,7 +53,12 @@ ENV CONTAINER=true
# Install chrome-headless-shell for deterministic BeginFrame rendering.
# This lightweight Chrome binary supports HeadlessExperimental.beginFrame.
# Install to ~/.cache/puppeteer/ where resolveHeadlessShellPath() looks.
RUN npx --yes @puppeteer/browsers install chrome-headless-shell@stable \
#
# Pinned to a specific build (NOT @stable) so the regression-test golden
# baselines in packages/producer/tests/*/output/output.mp4 stay reproducible.
# Each Chrome stable bump shifts pixel output enough to fail PSNR. Bump this
# version together with regenerating baselines via `docker:test:update`.
RUN npx --yes @puppeteer/browsers install chrome-headless-shell@148.0.7778.167 \
--path /root/.cache/puppeteer \
&& find /root/.cache/puppeteer/chrome-headless-shell -name "chrome-headless-shell" -type f \
&& echo "chrome-headless-shell installed"
+10 -7
View File
@@ -1096,16 +1096,19 @@ async function runTestSuite(
videoMetadata.durationSeconds,
snapshotMetadata.durationSeconds,
);
const fps = fpsToNumber(suite.meta.renderConfig.fps);
// Container duration includes audio padding past the last video frame
// (e.g. many-cuts: 5.654s container vs 5.6s of video). At i=99 the
// raw container duration maps to a frame index past nb_frames, and
// ffmpeg's PSNR filter emits no `average:` line for a non-existent
// frame. Subtract one frame interval so the last checkpoint always
// lands on a frame the video stream actually contains.
const sampleDuration = Math.max(0, videoDuration - 1 / fps);
const minPsnrForMode = resolveMinPsnrForMode(options.mode, suite.meta.minPsnr);
for (let i = 0; i < 100; i++) {
const time = (videoDuration * i) / 100;
const psnr = psnrAtCheckpoint(
renderedOutputPath,
snapshotVideoPath,
time,
fpsToNumber(suite.meta.renderConfig.fps),
);
const time = (sampleDuration * i) / 100;
const psnr = psnrAtCheckpoint(renderedOutputPath, snapshotVideoPath, time, fps);
visualCheckpoints.push({
time,
psnr,