From 59f2beda21f987109ee927793d889525b9eb8976 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Mon, 22 Jun 2026 21:15:36 +0000 Subject: [PATCH] chrome-service: run real Google Chrome (H.264/AAC codecs) for the browser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Point the chrome-service container at the new chrome-service-browser image and launch /opt/google/chrome/chrome instead of the bundled Chromium. Fixes MEDIA_ERR_SRC_NOT_SUPPORTED on H.264/AAC video (Instagram Reels etc.) in the noVNC view — bundled Chromium has those codecs compiled out; only real Chrome carries them. connect_over_cdp callers (tripit fare scrape, homelab browser, snapshot-harvester) attach over raw CDP (version-tolerant) — validated after rollout. Image is built off-infra on GHA (prior commit) → public ghcr. Co-Authored-By: Claude Opus 4.8 --- docs/architecture/chrome-service.md | 33 +++++++++++++++++++++-------- stacks/chrome-service/main.tf | 24 ++++++++++++--------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/docs/architecture/chrome-service.md b/docs/architecture/chrome-service.md index c048894c..6f9c1ee4 100644 --- a/docs/architecture/chrome-service.md +++ b/docs/architecture/chrome-service.md @@ -112,17 +112,32 @@ External caller (dev box): @playwright/mcp --isolated --storage-state ~/.cache/...storage-state.json ``` +## Browser binary — real Google Chrome (for proprietary codecs) + +The chrome-service container runs **real Google Chrome**, not the bundled +Chromium, via the infra-owned image `ghcr.io/viktorbarzin/chrome-service-browser` +(`files/chrome/Dockerfile` = `mcr.microsoft.com/playwright:v1.48.0-noble` + +`google-chrome-stable`, built by `.github/workflows/build-chrome-service-browser.yml`). +The launch resolves `CHROMIUM=/opt/google/chrome/chrome`. + +**Why:** the Playwright-bundled Chromium has proprietary codecs **compiled out**, +so H.264/AAC video (Instagram Reels, X, most `.mp4`) fails in the noVNC view with +`MEDIA_ERR_SRC_NOT_SUPPORTED` (the bytes download `200 video/mp4` but there's no +decoder — NOT a GPU issue). Royalty-free codecs (VP9/VP8/AV1 → YouTube) always +worked. Swapping `libffmpeg.so` does NOT help (codecs are compiled out, not just +the lib stripped) and Chrome-for-Testing is also codec-less — only +`google-chrome-stable` carries them. + ## Image pin -Both the server image (`mcr.microsoft.com/playwright:v1.48.0-noble` in -`stacks/chrome-service/main.tf`) and the Python client -(`playwright==1.48.0` in callers' `requirements.txt`) **must match -minor-versions**. Bump in lockstep — Playwright protocol changes between -minors and the client cannot connect to a mismatched server. - -The harvester + snapshot-server sidecar use -`mcr.microsoft.com/playwright/python:v1.48.0-noble` — same playwright -minor, with Python-side bindings pre-installed. +The Playwright base + the Python client (`playwright==1.48.0` in callers' +`requirements.txt`) and the snapshot sidecars +(`mcr.microsoft.com/playwright/python:v1.48.0-noble`) historically had to match +minor-versions. The chrome-service browser is now real Google Chrome (a newer +milestone than the 1.48 Chromium), but the `connect_over_cdp` callers (tripit +fare scrape, `homelab browser`, snapshot-harvester) attach over raw CDP, which is +version-tolerant — verified working against this Chrome. If a future Chrome +milestone breaks a caller, pin Chrome in the Dockerfile or bump the clients. ## Storage diff --git a/stacks/chrome-service/main.tf b/stacks/chrome-service/main.tf index 23ca3e79..2f679c00 100644 --- a/stacks/chrome-service/main.tf +++ b/stacks/chrome-service/main.tf @@ -178,8 +178,12 @@ resource "kubernetes_deployment" "chrome_service" { } container { - name = "chrome-service" - image = local.image + name = "chrome-service" + # Real Google Chrome (Playwright base + google-chrome-stable) for + # proprietary H.264/AAC codecs — see files/chrome/Dockerfile. The + # snapshot sidecars still use local.python_image (playwright minor + # pin) and connect_over_cdp; verified compatible with this Chrome. + image = "ghcr.io/viktorbarzin/chrome-service-browser:latest" image_pull_policy = "IfNotPresent" # Direct chromium launch (NOT `playwright launch-server`). Reason: @@ -203,16 +207,16 @@ resource "kubernetes_deployment" "chrome_service" { args = [ <<-EOT set -e - # Locate chromium in the Microsoft image. The path is - # /ms-playwright/chromium-XXXX/chrome-linux/chrome where XXXX - # is the playwright-pinned build; resolve at runtime so a minor - # bump of the image doesn't break the launch line. - CHROMIUM=$(find /ms-playwright -maxdepth 4 -name 'chrome' -type f -executable -path '*/chrome-linux/*' 2>/dev/null | head -1) - if [ -z "$CHROMIUM" ]; then - echo "ERROR: chromium binary not found under /ms-playwright" >&2 + # Real Google Chrome (proprietary H.264/AAC codecs) baked into the + # chrome-service-browser image at a fixed path — so H.264 video + # (Reels) plays in the noVNC view. The bundled Chromium under + # /ms-playwright lacks those codecs (MEDIA_ERR_SRC_NOT_SUPPORTED). + CHROMIUM=/opt/google/chrome/chrome + if [ ! -x "$CHROMIUM" ]; then + echo "ERROR: google-chrome not found at $CHROMIUM (wrong image?)" >&2 exit 1 fi - echo "[chrome-service] using chromium: $CHROMIUM" + echo "[chrome-service] using browser: $($CHROMIUM --version 2>/dev/null || echo "$CHROMIUM")" # -listen tcp enables localhost:6099 so the noVNC sidecar can # attach over the pod's shared network ns (Ubuntu 24.04