feat(runtime): add cross-platform MP4 video backgrounds - #290
Open
starsstreaming wants to merge 1 commit into
Open
feat(runtime): add cross-platform MP4 video backgrounds#290starsstreaming wants to merge 1 commit into
starsstreaming wants to merge 1 commit into
Conversation
Support optional theme.json video fields, loopback media serving, menu/tray import, poster fallback, and renderer handoff on both platforms. Closes Fei-Away#240.
Author
Demo video / 演示视频Compressed author walkthrough of MP4 video background import on Windows (tray → pick MP4 → apply → homepage/task route). Windows 托盘「一键更换视频背景」导入与生效演示(作者录屏压缩版)。
Direct download:
|
Author
Stack / 叠放后续Linear stack on top of this PR (please merge in order):
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 摘要
Add optional MP4 video backgrounds on both platforms while keeping existing static-image themes fully compatible. Users can import a video from the menu/tray or declare it in a theme package; the renderer plays it as a background layer with the still image as poster and failure fallback.
在双平台增加可选 MP4 视频背景,并保持现有静态图片主题完全兼容。用户可从菜单/托盘直接导入视频,或在主题包中声明;渲染器用独立背景层播放,静态图仍作 poster 与失败回退。
Closes #240
What users get / 用户可见行为
theme.json"video": "background.mp4".mp4, ≤ 100 MiB, realftypbox (renamed non-MP4 rejected)Direct picker is preferred for large files. Theme ZIP import still obeys existing archive caps (32 MiB compressed / 64 MiB expanded, including the MP4), so e.g. a 76 MiB video must use the menu/tray path.
大文件请用菜单/托盘直选。ZIP 仍受原有压缩/解压上限约束(含 MP4),超过解压上限的视频不能靠 ZIP 导入。
Design / 设计要点
1. Theme model / 主题模型
{ "schemaVersion": 1, "image": "background.jpg", "video": "background.mp4" }videois optional. Image-only themes behave exactly as before.videomust be a relative basename inside the theme directory (background.mp4only in the registered media map). Absolute paths,.., controls, and non-.mp4names are rejected.runtime/theme-package-validator.mjs+ platform copies):LIMITS.video = 100 * 1024 * 1024isMp4Container()checks first-box size + ASCIIftypbackground.mp4next to the image + CSStheme-windows.ps1):Assert-DreamSkinVideoFilemirrors the same size/extension/ftypchecks beforeSet-DreamSkinActiveThemecopies the file into the managed active theme.apply-community-theme.ps1) now copies and restoresVideoPath, so a video theme is not restored as a broken image-only manifest.video可选;仅图片主题行为不变。校验层(Node 包校验 + Windows PS)统一:相对名、.mp4、≤100 MiB、真实ftyp。社区主题应用的快照/恢复会带上 MP4,避免恢复成“清单有 video、磁盘无文件”。2. Loopback media server / 本机回环媒体服务
New shared module (platform copies):
macos/scripts/media-server.mjswindows/scripts/media-server.mjsContract:
127.0.0.1only, ephemeral port/media/<token>GET/HEAD/OPTIONS206+Content-Range; invalid range →416Cache-Control: no-store,X-Content-Type-Options: nosniffX-Codex-Dream-Skin-Token; otherwise 403MediaServerControllerstages the next server and commits only after renderers accept the new theme (previous server kept alive across verification so in-flight playback does not break mid-switch)Does not widen CDP beyond loopback. Windows injector additionally prefers CDP
DOM.setFileInputFiles+ Blob transport for the active session, with the loopback URL only as controlled fallback; CSP bypass for media fetch is enabled only through the verified injector path and without forcing a full page reload.新模块仅绑
127.0.0.1、一次性 token 路由、Range/206、Origin + token 门禁、文件漂移拒绝。MediaServerController在渲染器确认前保留旧服务。Windows 优先 CDP 文件注入 + Blob,loopback URL 仅作受控回退;不为换肤强制整页 reload。3. Injector payload / 注入载荷
__DREAM_SKIN_VIDEO_JSON__..replace(...)(same$-safe pattern as v1.5.6 payload integrity work).(cssText, artDataUrl, themeConfig, videoConfig) => { ... }.loadThemeresolves/realpaths the video inside the theme dir, streams content for fingerprinting (does not keep a full MP4 buffer just to hash), validatesftyp, and records size/mtime in the source stamp.rejectedSourceStamp) and is not reapplied until source files change.videoMode/videoReady/videoFailed.load-image-theme-macos.sh --file <mp4>.--allow-hidden-appliedso a deferred hidden-renderer state during video bring-up does not false-fail an otherwise healthy session (aligned with existing hidden-defer semantics).载荷第 7 个占位符
VIDEO_JSON;函数式 replace;IIFE 增加videoConfig。指纹对流式读 MP4,不全量读入。被渲染器拒绝的 revision 在源文件变化前不再重放。Windows 启动 verify 显式允许 hidden-applied 延迟态,避免视频拉起阶段误杀健康会话。4. Renderer / 渲染器
runtime/renderer-inject.js(+ macos/windows assets via sync gate):#codex-dream-skin-background-stagewith<img>poster +<video>muted/autoplay/loop/playsInline;pointer-events: nonedata-dream-media="video",data-dream-video-ready, failure flagsblob(Windows file input) orserver(loopback URL); optionalfallbackUrl<video>to avoid double-decode / poster flash背景舞台层 + poster 图 + video;切换时清理监听与 Blob URL,并 handoff 旧 video 节点以降低闪屏。失败/隐藏/清主题时回退静态图。不改动图片主题既有 chrome/布局选择器语义。
5. CSS / 样式
Pure additive block on top of upstream
dream-skin.css(~+132 lines):#codex-dream-skin-background-stageand descendantshtml[data-dream-skin="active"][data-dream-media="video"] …visibility/stacking rulesCSS 只增不删:视频舞台与
data-dream-media="video"规则;本 PR 不含 chrome 收窄或其它布局删改。6. Platform UX / 平台入口
AppDelegate.swift: menu item →NSOpenPanel(.mpeg4Movie) →load-image-theme-macos.sh --filetray-dream-skin.ps1: tray item → MP4 filter dialog →Set-DreamSkinActiveTheme -VideoPath …; busy-op balloon; watcher liveness check + optional restart prompt; post-apply--verifypollmedia-server.mjs(common-windows.ps1,build-release.ps1,setup-bootstrap.ps1, macOS menubar build script)README.md/README.en.md,windows/README.md; changelogs under## 未发布(noVERSIONbump)Files / 主要文件(44 files, +4622 / −207)
runtime/renderer-inject.js,runtime/dream-skin.css,runtime/theme-package-validator.mjsmacos/scripts/media-server.mjs,windows/scripts/media-server.mjsmacos/scripts/injector.mjs,windows/scripts/injector.mjsmacos/scripts/{stage,write,publish,load-image,switch,extract,theme-content-fingerprint}*,windows/scripts/theme-windows.ps1,apply-community-theme.ps1macos/menubar-app/.../AppDelegate.swift,windows/scripts/tray-dream-skin.ps1windows/scripts/common-windows.ps1, installers,macos/scripts/build-menubar-app.shmacos/assets/*,windows/assets/*copies of runtime CSS/JS/validatorREADME.md,README.en.md,windows/README.md,macos/CHANGELOG.md,windows/CHANGELOG.mdTASK_PROGRESS.mdandVERSIONfiles are not in this PR.Tests / 测试
Added / extended coverage
macos/tests/media-server.test.mjs,windows/tests/media-server.test.mjs— loopback bind, token route, Range/206/416, origin/token rejection, size gatetools/renderer-runtime.test.mjs— video stage, handoff, poster fallback, blob/server config, no-reload media policy expectationswindows/tests/injector-bootstrap.test.mjs— MP4 fingerprint changes when bytes change under same name; blob transport / CSP bypass / no full-file fingerprint buffer; reject-stamp; media commit-after-verify orderingwindows/tests/injector-window-readiness.test.mjs— visible-but-not-ready video is a real failure (not hidden-window defer)macos/tests/theme-package-validator.test.mjs,theme-stage.test.mjs,payload-template-integrity.test.mjs— video field, ftyp, 7 placeholders +videoConfigIIFEwindows/tests/run-tests.ps1— video write path + image-switch fingerprint regression hooksmacos/tests/injector-bootstrap.test.mjs— video-related bootstrap assertionswindows已经人工测试可用
macOS 真机测试与截图待补;其它叠放改动非本功能阻塞项。
Checks actually run for this PR / 本 PR 实跑
node tools/sync-runtime-assets.mjsnode --test tools/renderer-runtime.test.mjs windows/tests/injector-bootstrap.test.mjs windows/tests/media-server.test.mjs windows/tests/injector-window-readiness.test.mjswindows/tests/run-tests.ps1git diff --checkmacos/tests/run-tests.shfull suite/bin/bash; known symlinkEPERMon this environment (same limitation on plainupstream/main)Type / 类型
Platform / 平台
Self-check / 自测
Docs-only / 仅文档
macOS (when code under
macos/changes)macos/tests/run-tests.shpassed / 已通过macos/scripts/doctor-macos.shverify-dream-skin-macos.shor Desktop VerifymacOS full suite and live verify pending on a Mac. Shared Node media/renderer/validator coverage and payload-template integrity updates are in tree; environment limits called out above.
macOS 完整套件与真机 verify 待 Mac 补跑;共享 Node 媒体/渲染/校验与 payload 完整性改动已在树内。
Windows (when code under
windows/changes)install/start/verify/restorescripts exercised / 已按改动跑过对应脚本Security / 安全
127.0.0.1) where applicable / CDP 仍仅本机回环(如适用)Additional video-path hardening called out above:
ftypgate, 100 MiB cap, theme-dir containment (no symlink escape), loopback+token media server, no arbitrary path expose, Windows WS host check stays127.0.0.1-only in the touched validation path, streaming fingerprint (no full-buffer retain for hash only).视频路径额外约束见上文:ftyp、100 MiB、主题目录封闭、loopback+token 媒体服务、不暴露任意路径、指纹流式计算。
Notes / 补充
Out of scope / 明确不在本 PR
VERSIONbump / release packaging本 PR 不做 CSS chrome 收窄、与视频无关的原子 marker / 托盘 verified transaction 重构,也不 bump VERSION。
Environment / 环境
starsstreaming:feat/video-backgrounds@865b906on top ofv1.5.6(611c101)Screenshots / demo / 截图与演示
Demo video / 演示视频 (Windows tray import walkthrough, ~44s, 7.2 MiB, H.264/AAC, no private chat):
starsstreaming/Codex-Dream-Skin@pr-290-video-demo(prerelease asset only — not a product release)Still homepage / task-route screenshots can be added if reviewers want frame captures; the video already covers import → apply → home/task routes.
演示视频(Windows 托盘导入全程,约 44s,7.2 MiB,H.264/AAC,不含隐私对话):同上链接。
如需静态截图可再补;视频已覆盖导入 → 生效 → 首页/任务页。
Reviewer map / 建议审阅顺序
runtime/theme-package-validator.mjs+*/media-server.mjs— trust boundarywindows/scripts/injector.mjsmedia stage/commit + blob handoffruntime/renderer-inject.jsvideo lifecycle / fallbackruntime/dream-skin.cssadditive stage onlytheme-windows.ps1/apply-community-theme.ps1snapshot