mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
* chore(docker): pin FFmpeg 8.0.1 in the Docker images and host CI Install one pinned static BtbN build (n8.0.1-66, month-end release) in Dockerfile.test, the CLI render image, the Cloud Run image and the k8s example, and bump the host CI install-ffmpeg-linux action from 7.1.3 to the same build. Regression baselines and the shipped images now use the same FFmpeg version instead of Debian's apt ffmpeg 5.1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(producer): regenerate six regression baselines on FFmpeg 8.0.1 The Docker test image now renders with FFmpeg 8.0.1 instead of Debian's 5.1. Six fixtures fail against the 5.1 baselines; everything else passes unchanged, including vfr-screen-recording. - style-2-prod, style-10-prod: FFmpeg 8 honors the MP3 gapless header, so the probed SFX duration is 1.0s instead of 1.044898s. Regenerate output.mp4 and compiled.html. - vignelli-stacking: one checkpoint (8.06s) now shows source frame 201 of the 25fps a-roll, which is the right frame for that time; the old baseline showed frame 202. - missing-host-comp-id, variables-prod, speed-ramp: AAC encoder output differs enough to drop the RMS-envelope correlation on flat signals below 0.9. Sample correlation against the source stays at 0.9999. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cli): read the ffmpeg version from n-prefixed release builds Release-branch ffmpeg builds, including the BtbN build now pinned in CI, print "ffmpeg version n8.0.1-66-...". extractMajorVersion skipped the "n8" token and returned 0 (and 1 for n7.1.3), so the CLI telemetry smoke check failed. parseToolVersion fell back to the whole banner line. Accept an optional "n" before the version number in both. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(cli): keep the preflight comment share flat Fold the n-prefix note into the existing doc line instead of adding new comment lines, which the comment ratchet rejects. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(docker): pick the FFmpeg build per arch and fail on a bad binary Dockerfile.test, the k8s example and the Cloud Run image always extracted the amd64 archive on multiarch bases, and the piped version check passed even when the binary could not run. All four images now pick linux64 or linuxarm64 by TARGETARCH, fail on any other arch, and grep both ffmpeg and ffprobe for the pinned version. style-2-prod and style-10-prod compiled.html go back to the previous golden with only the SFX data-duration/data-end changed, instead of a full recompile that also picked up unrelated compiler output. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
86 lines
4.6 KiB
Docker
86 lines
4.6 KiB
Docker
FROM node:22.23.3-bookworm-slim
|
|
|
|
ARG HYPERFRAMES_VERSION=latest
|
|
# Set automatically by `docker build --platform` (BuildKit); selects the
|
|
# chrome-headless-shell source below (chrome-for-testing ships linux64 only,
|
|
# see https://googlechromelabs.github.io/chrome-for-testing/).
|
|
ARG TARGETARCH=amd64
|
|
# Pinned Playwright release used to fetch a known-good, arch-native
|
|
# chrome-headless-shell on arm64. chrome-for-testing publishes no linux-arm64
|
|
# build, so arm64 used to fall back to Debian's *unpinned, rolling* `chromium`
|
|
# package — whose bookworm arm64 build SIGTRAPs at startup (exit 133), breaking
|
|
# every containerized render (issue #2039). Playwright ships a pinned
|
|
# linux-arm64 headless-shell (Google's build, not Debian's). Bump deliberately.
|
|
ARG PLAYWRIGHT_VERSION=1.61.1
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
ca-certificates curl unzip xz-utils chromium \
|
|
libgbm1 libnss3 libatk-bridge2.0-0 libdrm2 libxcomposite1 \
|
|
libxdamage1 libxrandr2 libcups2 libasound2 libpangocairo-1.0-0 \
|
|
libxshmfence1 libgtk-3-0 \
|
|
fonts-liberation fonts-noto-color-emoji fonts-noto-cjk fonts-noto-core \
|
|
fonts-noto-extra fonts-noto-ui-core fonts-freefont-ttf fonts-dejavu-core \
|
|
fontconfig \
|
|
&& rm -rf /var/lib/apt/lists/* && apt-get clean && fc-cache -fv
|
|
|
|
# One pinned static FFmpeg build (BtbN n8.0.1, per arch) instead of Debian's apt
|
|
# ffmpeg, so regression baselines and the shipped images use the same version.
|
|
# Bump the URLs and sha256s together, and keep in sync with the other Dockerfiles
|
|
# and .github/actions/install-ffmpeg-linux/action.yml.
|
|
ARG FFMPEG_RELEASE=https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-02-28-12-59
|
|
ARG FFMPEG_BUILD=ffmpeg-n8.0.1-66-g27b8d1a017
|
|
ARG FFMPEG_SHA256_AMD64=26d2ecd0cefba99f9d1ea92252a3a4f743a58df4c1c3cf9f8bbaaa40b1fca5b0
|
|
ARG FFMPEG_SHA256_ARM64=d72cc324cb65dd92a9ffe699cc95ccbacfef4def8d3ad9fe2b5164a6a71b9595
|
|
RUN case "$TARGETARCH" in \
|
|
amd64) FF_ARCH=linux64; FF_SHA256="$FFMPEG_SHA256_AMD64" ;; \
|
|
arm64) FF_ARCH=linuxarm64; FF_SHA256="$FFMPEG_SHA256_ARM64" ;; \
|
|
*) echo "unsupported TARGETARCH '$TARGETARCH'" >&2; exit 1 ;; \
|
|
esac \
|
|
&& curl -fsSL -o /tmp/ffmpeg.tar.xz "$FFMPEG_RELEASE/$FFMPEG_BUILD-$FF_ARCH-gpl-8.0.tar.xz" \
|
|
&& echo "$FF_SHA256 /tmp/ffmpeg.tar.xz" | sha256sum -c - \
|
|
&& tar -xJf /tmp/ffmpeg.tar.xz -C /usr/local/bin --strip-components=2 --wildcards '*/bin/ffmpeg' '*/bin/ffprobe' \
|
|
&& rm /tmp/ffmpeg.tar.xz \
|
|
&& ffmpeg -version | grep -F "ffmpeg version ${FFMPEG_BUILD#ffmpeg-}" \
|
|
&& ffprobe -version | grep -F "ffprobe version ${FFMPEG_BUILD#ffmpeg-}"
|
|
|
|
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
|
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
|
ENV CONTAINER=true
|
|
|
|
# chrome-headless-shell unlocks BeginFrame-based deterministic capture. Install
|
|
# it on both arches from a pinned source so a build can never silently pick up a
|
|
# broken browser update:
|
|
# amd64 -> chrome-for-testing (linux64) via @puppeteer/browsers
|
|
# arm64 -> Playwright's pinned linux-arm64 headless-shell (chrome-for-testing
|
|
# has no arm64 build; Debian's rolling `chromium` SIGTRAPs — #2039)
|
|
# The wrapper script below wires whichever binary landed into
|
|
# PRODUCER_HEADLESS_SHELL_PATH, or fails the build loudly if neither did.
|
|
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
|
npx --yes @puppeteer/browsers install chrome-headless-shell@stable \
|
|
--path /root/.cache/puppeteer; \
|
|
else \
|
|
npx --yes playwright-core@${PLAYWRIGHT_VERSION} install chromium-headless-shell; \
|
|
fi
|
|
|
|
RUN npm install -g hyperframes@${HYPERFRAMES_VERSION}
|
|
|
|
# Wrapper script: resolves the chrome-headless-shell path installed above and
|
|
# exports it as PRODUCER_HEADLESS_SHELL_PATH so the engine uses BeginFrame
|
|
# rendering. @puppeteer/browsers names the binary `chrome-headless-shell`;
|
|
# Playwright names it `headless_shell` — match either, in either cache dir.
|
|
# If neither is present the browser install step failed: fail the build loudly
|
|
# rather than silently downgrading to the (arm64-broken) Debian chromium.
|
|
RUN SHELL_PATH=$(find /root/.cache/puppeteer /root/.cache/ms-playwright \
|
|
\( -name "chrome-headless-shell" -o -name "headless_shell" \) -type f 2>/dev/null | head -1); \
|
|
if [ -n "$SHELL_PATH" ]; then \
|
|
printf '#!/bin/sh\nexport PRODUCER_HEADLESS_SHELL_PATH=%s\nexec hyperframes render "$@"\n' "$SHELL_PATH" > /usr/local/bin/hf-render; \
|
|
else \
|
|
echo "ERROR: chrome-headless-shell binary not found for ${TARGETARCH} — the browser install step above must have failed." >&2; \
|
|
exit 1; \
|
|
fi \
|
|
&& chmod +x /usr/local/bin/hf-render
|
|
|
|
WORKDIR /project
|
|
|
|
ENTRYPOINT ["hf-render"]
|