国内网络 - ZLHad/OpenVideoHarness GitHub Wiki

国内网络

第一次用的时候,有几处要连境外的服务:npm、PyPI、Hugging Face、HyperFrames 用的 Chrome、GitHub,渲染时还可能请求 Google Fonts。连不上或很慢时,按这一页设镜像。(这一页原来在 README 里,2026-10-04 挪到 wiki。)English

地址和变量名都对照过各家的官方说明(2026-10-01 核对);镜像站可能调整,失效时以官方页面为准。

镜像

下载什么 怎么设 官方说明
npm 包:引擎依赖、每个 HyperFrames 项目的 node_modules export npm_config_registry=https://registry.npmmirror.com npmmirror、npm config
Python 依赖:声音工具和联系表,uv 现装 export UV_DEFAULT_INDEX=https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple(清华),或 https://mirrors.aliyun.com/pypi/simple/(阿里云) 清华 PyPI、阿里云 PyPI、uv 环境变量
Qwen3-TTS 模型(约 2 GB,来自 Hugging Face) export HF_ENDPOINT=https://hf-mirror.com hf-mirror、huggingface_hub 环境变量

变量要在运行 install.sh、bin/vh 之前设好:写进 ~/.zshrc 长期有效,或者只给一条命令设,比如一键安装:

curl -fsSL https://raw.githubusercontent.com/ZLHad/OpenVideoHarness/main/install.sh | npm_config_registry=https://registry.npmmirror.com bash

几处细节:

  • npm:仓库里的 package-lock.json 记的是 registry.npmjs.org 的地址,npm 默认会换成你设的镜像(replace-registry-host 的默认值是 npmjs),所以 npm ci 也走镜像,实测没有请求落到 npmjs.org。要写进配置:npm config set registry https://registry.npmmirror.com。
  • uv、pip:UV_INDEX_URL 是旧名字,uv 文档已标为弃用,请用 UV_DEFAULT_INDEX。要长期有效,写进 ~/.config/uv/uv.toml(macOS 和 Linux 都是这个位置,环境变量比配置文件优先):
    [[index]]
    url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
    default = true
    直接用 pip 时:pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple。清华还有一个域名 https://pypi.tuna.tsinghua.edu.cn/simple,也能用。阿里云页面里的示例写的是 http:// 加 trusted-host,https:// 同样可用。
  • Hugging Face:HF_ENDPOINT 是 huggingface_hub 认的变量,bin/vh tts 下载 Qwen3-TTS 走的就是它。hf-mirror 不支持登录,gated 模型要先在 Hugging Face 官网申请、拿到 Access Token,再带 --token 下载(见 hf-mirror 首页);默认的 Qwen3-TTS 是公开的,不用管这些。
  • HyperFrames 的 Chrome:第一次 hyperframes render 从 storage.googleapis.com 下载 chrome-headless-shell(0.8.82 固定用 152.0.7977.30)。连不上时,终端先一直转 "Checking browser…",最后报 Failed to download chrome-headless-shell。可以先从 npmmirror 的二进制镜像装到 HyperFrames 找的位置,在任一 HyperFrames 项目或 styles/_swatch 里运行:
    npx browsers install [email protected] \
      --path ~/.cache/hyperframes/chrome --base-url https://cdn.npmmirror.com/binaries/chrome-for-testing
    装好后 npx hyperframes browser path 会打印出它,再渲染就不下载了(实测渲染时显示 Browser: cache)。实在装不上,可以 export HYPERFRAMES_BROWSER_PATH="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"(macOS 的路径,Linux 换成 google-chrome 或 chromium 的路径),直接用装好的 Chrome:能出片,但走较慢的截图路径,这个仓库没在这条路径上测过确定性。
  • GitHub:install.sh 和 references/fetch.sh 都从 GitHub 克隆。访问不稳时,先 bash install.sh --no-refs,参考仓库用到哪个再拉哪个(references/fetch.sh <名字>);git 也可以走代理:git config --global http.proxy http://127.0.0.1:端口。

渲染时会连 Google Fonts

有几处在渲染时会请求 fonts.googleapis.com:

  • engines/ClaudeAnimationBase/studio.html 请求手写字用的 Permanent Marker;手绘和 MV 项目(bin/vh new handdrawn、mv)和 showcase/01 都是从它复制来的。render.mjs 要等页面网络空闲才开始渲:请求一直挂着时,30 秒后以 Navigation timeout of 30000 ms exceeded 退出;请求立刻失败时,只打一行 Failed to load resource,照常出片,手写字落到后备字体(Comic Sans MS)。
  • showcase/02-short-leo-doppler/index.html,和照它写的竖屏科普:Noto Sans SC 的 500、800 两个字重。
  • HyperFrames 自己:字体栈里没有用 @font-face 声明的字体,render、snapshot、check 每次运行都会去 Google Fonts 请求(字体文件缓存在 ~/.cache/hyperframes/fonts,缓存了也照样请求)。lint 放行的 Arial、Helvetica Neue、Menlo 等名字也在此列,渲染时被换成 Inter、JetBrains Mono 再去取;以 sans-serif 这类通用族名开头的栈,前面会被补上 Inter。请求挂着时,render 的进度停在 5% 的 "Compiling composition",snapshot 和 check 什么也不输出(实测等了 90 到 150 秒都没有结束);请求立刻失败时没有警告,Inter 只剩 HyperFrames 自带的 400、700、900 三个字重,原来脚手架里 600 的标题渲成了 700。bin/vh hf-init 现在把脚手架默认的 Inter 换成用 local() 声明的本机字体(下面第 1 种做法),新建的项目不再请求 Google Fonts;之前建的项目照第 1 种做法改。

本地化有三种做法,按省事程度排:

  1. 用系统字体,不联网。 样片渲染器和 bin/vh hf-init 搭的脚手架都是这么做的:在页面的 <style> 里声明 @font-face,src 写 local(),例如 @font-face { font-family: "PingFang SC"; src: local("PingFangSC-Semibold"), local("PingFang SC Semibold"); font-weight: 600; }。字体栈里每个字体都要这样声明,排第一的也得是声明过的字体。现成的声明在 styles/_swatch/fonts.css,换了机器用 python3 styles/_swatch/fonts.py 按本机字体重新生成;各字体有哪些字重,见 styles/_swatch/README.md 的"字体"一节。
  2. 字体文件放进项目。 放到 assets/fonts/,在 <style> 里写 @font-face { font-family: "…"; src: url("assets/fonts/….woff2") format("woff2"); },来源和许可记进 NOTES.md。HyperFrames 看到自己声明的字体,就不会再去取了(实测没有任何请求)。
  3. 用 npm 装。 Fontsource 把 Google Fonts 打成了 npm 包,走上面的 npm 镜像就行:
    • 手绘引擎:npm i -D @fontsource/permanent-marker(0.1 MB),把 studio.html 里 fonts.googleapis.com 那行 <link> 换成 <link rel="stylesheet" href="node_modules/@fontsource/permanent-marker/index.css">。实测 Google Fonts 连不上时,字体 1 秒内加载完。
    • Noto Sans SC:npm i -D @fontsource-variable/noto-sans-sc(约 5 MB 的可变字体,100–900 的字重都有),页面里写 <link rel="stylesheet" href="node_modules/@fontsource-variable/noto-sans-sc/wght.css">,font-family 写 "Noto Sans SC Variable"。showcase 02 照此改完,HyperFrames 的 snapshot 和原版逐像素一致(实测三个时刻);snapshot 会打一条 [StaticGuard] … Font family used without @font-face declaration,字体其实已经加载,可以不管。
⚠️ **GitHub.com Fallback** ⚠️