[{"data":1,"prerenderedAt":3744},["ShallowReactive",2],{"navigation":3,"\u002Fpackages\u002Fengine":686,"\u002Fpackages\u002Fengine-surround":3739},[4,31,57,147,168,198,652],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":30},"快速入门","i-lucide-rocket","\u002Fgetting-started","01.getting-started",[10,14,18,22,26],{"title":11,"path":12,"stem":13},"简介","\u002Fgetting-started\u002Fintroduction","01.getting-started\u002F01.introduction",{"title":15,"path":16,"stem":17},"快速开始","\u002Fgetting-started\u002Fquickstart","01.getting-started\u002F02.quickstart",{"title":19,"path":20,"stem":21},"展示作品","\u002Fgetting-started\u002Fshowcase","01.getting-started\u002F03.showcase",{"title":23,"path":24,"stem":25},"示例","\u002Fgetting-started\u002Fexamples","01.getting-started\u002F04.examples",{"title":27,"path":28,"stem":29},"发布视频","\u002Fgetting-started\u002Flaunch-videos","01.getting-started\u002F05.launch-videos",false,{"title":32,"icon":33,"path":34,"stem":35,"children":36,"page":30},"核心概念","i-lucide-lightbulb","\u002Fconcepts","02.concepts",[37,41,45,49,53],{"title":38,"path":39,"stem":40},"合成","\u002Fconcepts\u002Fcompositions","02.concepts\u002F01.compositions",{"title":42,"path":43,"stem":44},"数据属性","\u002Fconcepts\u002Fdata-attributes","02.concepts\u002F02.data-attributes",{"title":46,"path":47,"stem":48},"变量","\u002Fconcepts\u002Fvariables","02.concepts\u002F03.variables",{"title":50,"path":51,"stem":52},"帧适配器","\u002Fconcepts\u002Fframe-adapters","02.concepts\u002F04.frame-adapters",{"title":54,"path":55,"stem":56},"确定性渲染","\u002Fconcepts\u002Fdeterminism","02.concepts\u002F05.determinism",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":30},"使用指南","i-lucide-compass","\u002Fguides","03.guides",[63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143],{"title":64,"path":65,"stem":66},"工作流水线","\u002Fguides\u002Fpipeline","03.guides\u002F01.pipeline",{"title":68,"path":69,"stem":70},"HTML-in-Canvas","\u002Fguides\u002Fhtml-in-canvas","03.guides\u002F02.html-in-canvas",{"title":72,"path":73,"stem":74},"网站转视频","\u002Fguides\u002Fwebsite-to-video","03.guides\u002F03.website-to-video",{"title":76,"path":77,"stem":78},"Google Antigravity","\u002Fguides\u002Fantigravity","03.guides\u002F04.antigravity",{"title":80,"path":81,"stem":82},"GitHub Copilot CLI","\u002Fguides\u002Fcopilot-cli","03.guides\u002F05.copilot-cli",{"title":84,"path":85,"stem":86},"Claude Design","\u002Fguides\u002Fclaude-design","03.guides\u002F06.claude-design",{"title":88,"path":89,"stem":90},"Open Design","\u002Fguides\u002Fopen-design","03.guides\u002F07.open-design",{"title":92,"path":93,"stem":94},"提示词指南","\u002Fguides\u002Fprompting","03.guides\u002F08.prompting",{"title":96,"path":97,"stem":98},"Hyperframes vs Remotion","\u002Fguides\u002Fhyperframes-vs-remotion","03.guides\u002F09.hyperframes-vs-remotion",{"title":100,"path":101,"stem":102},"GSAP 动画","\u002Fguides\u002Fgsap-animation","03.guides\u002F10.gsap-animation",{"title":104,"path":105,"stem":106},"渲染","\u002Fguides\u002Frendering","03.guides\u002F11.rendering",{"title":108,"path":109,"stem":110},"去除背景（透明视频）","\u002Fguides\u002Fremove-background","03.guides\u002F12.remove-background",{"title":112,"path":113,"stem":114},"HDR 渲染","\u002Fguides\u002Fhdr","03.guides\u002F13.hdr",{"title":116,"path":117,"stem":118},"4K 渲染","\u002Fguides\u002F4k-rendering","03.guides\u002F14.4k-rendering",{"title":120,"path":121,"stem":122},"性能","\u002Fguides\u002Fperformance","03.guides\u002F15.performance",{"title":124,"path":125,"stem":126},"时间轴编辑","\u002Fguides\u002Ftimeline-editing","03.guides\u002F16.timeline-editing",{"title":128,"path":129,"stem":130},"视频编辑者速查表","\u002Fguides\u002Fvideo-editor-cheatsheet","03.guides\u002F17.video-editor-cheatsheet",{"title":132,"path":133,"stem":134},"常见错误","\u002Fguides\u002Fcommon-mistakes","03.guides\u002F18.common-mistakes",{"title":136,"path":137,"stem":138},"故障排除","\u002Fguides\u002Ftroubleshooting","03.guides\u002F19.troubleshooting",{"title":140,"path":141,"stem":142},"反馈收集","\u002Fguides\u002Ffeedback","03.guides\u002F20.feedback",{"title":144,"path":145,"stem":146},"HyperFrames MCP","\u002Fguides\u002Fmcp","03.guides\u002F21.mcp",{"title":148,"icon":149,"path":150,"stem":151,"children":152,"page":30},"部署","i-lucide-cloud","\u002Fdeploy","04.deploy",[153,156,160,164],{"title":148,"path":154,"stem":155},"\u002Fdeploy\u002Fdeploy","04.deploy\u002F01.deploy",{"title":157,"path":158,"stem":159},"AWS Lambda","\u002Fdeploy\u002Faws-lambda","04.deploy\u002F02.aws-lambda",{"title":161,"path":162,"stem":163},"Lambda 上的模板","\u002Fdeploy\u002Ftemplates-on-lambda","04.deploy\u002F03.templates-on-lambda",{"title":165,"path":166,"stem":167},"迁移到 HyperFrames Lambda","\u002Fdeploy\u002Fmigrating-to-hyperframes-lambda","04.deploy\u002F04.migrating-to-hyperframes-lambda",{"title":169,"icon":170,"path":171,"stem":172,"children":173,"page":30},"包","i-lucide-package","\u002Fpackages","05.packages",[174,178,182,186,190,194],{"title":175,"path":176,"stem":177},"@hyperframes\u002Fcore","\u002Fpackages\u002Fcore","05.packages\u002F01.core",{"title":179,"path":180,"stem":181},"@hyperframes\u002Fengine","\u002Fpackages\u002Fengine","05.packages\u002F02.engine",{"title":183,"path":184,"stem":185},"@hyperframes\u002Fplayer","\u002Fpackages\u002Fplayer","05.packages\u002F03.player",{"title":187,"path":188,"stem":189},"@hyperframes\u002Fproducer","\u002Fpackages\u002Fproducer","05.packages\u002F04.producer",{"title":191,"path":192,"stem":193},"@hyperframes\u002Fstudio","\u002Fpackages\u002Fstudio","05.packages\u002F05.studio",{"title":195,"path":196,"stem":197},"CLI","\u002Fpackages\u002Fcli","05.packages\u002F06.cli",{"title":199,"icon":200,"path":201,"stem":202,"children":203,"page":30},"组件目录","i-lucide-layout-grid","\u002Fcatalog","06.catalog",[204,270,324,358,420,478,512,546,584,598],{"title":205,"icon":206,"path":207,"stem":208,"children":209,"page":30},"字幕","i-lucide-captions","\u002Fcatalog\u002Fcaption","06.catalog\u002F01.caption",[210,214,218,222,226,230,234,238,242,246,250,254,258,262,266],{"title":211,"path":212,"stem":213},"裁剪擦除","\u002Fcatalog\u002Fcaption\u002Fcaption-clip-wipe","06.catalog\u002F01.caption\u002F01.caption-clip-wipe",{"title":215,"path":216,"stem":217},"编辑强调","\u002Fcatalog\u002Fcaption\u002Fcaption-editorial-emphasis","06.catalog\u002F01.caption\u002F02.caption-editorial-emphasis",{"title":219,"path":220,"stem":221},"Emoji 弹出","\u002Fcatalog\u002Fcaption\u002Fcaption-emoji-pop","06.catalog\u002F01.caption\u002F03.caption-emoji-pop",{"title":223,"path":224,"stem":225},"故障 RGB","\u002Fcatalog\u002Fcaption\u002Fcaption-glitch-rgb","06.catalog\u002F01.caption\u002F04.caption-glitch-rgb",{"title":227,"path":228,"stem":229},"渐变填充","\u002Fcatalog\u002Fcaption\u002Fcaption-gradient-fill","06.catalog\u002F01.caption\u002F05.caption-gradient-fill",{"title":231,"path":232,"stem":233},"高亮","\u002Fcatalog\u002Fcaption\u002Fcaption-highlight","06.catalog\u002F01.caption\u002F06.caption-highlight",{"title":235,"path":236,"stem":237},"动感冲击","\u002Fcatalog\u002Fcaption\u002Fcaption-kinetic-slam","06.catalog\u002F01.caption\u002F07.caption-kinetic-slam",{"title":239,"path":240,"stem":241},"矩阵解码","\u002Fcatalog\u002Fcaption\u002Fcaption-matrix-decode","06.catalog\u002F01.caption\u002F08.caption-matrix-decode",{"title":243,"path":244,"stem":245},"霓虹强调","\u002Fcatalog\u002Fcaption\u002Fcaption-neon-accent","06.catalog\u002F01.caption\u002F09.caption-neon-accent",{"title":247,"path":248,"stem":249},"霓虹发光","\u002Fcatalog\u002Fcaption\u002Fcaption-neon-glow","06.catalog\u002F01.caption\u002F10.caption-neon-glow",{"title":251,"path":252,"stem":253},"视差图层","\u002Fcatalog\u002Fcaption\u002Fcaption-parallax-layers","06.catalog\u002F01.caption\u002F11.caption-parallax-layers",{"title":255,"path":256,"stem":257},"粒子爆发","\u002Fcatalog\u002Fcaption\u002Fcaption-particle-burst","06.catalog\u002F01.caption\u002F12.caption-particle-burst",{"title":259,"path":260,"stem":261},"胶囊卡拉OK","\u002Fcatalog\u002Fcaption\u002Fcaption-pill-karaoke","06.catalog\u002F01.caption\u002F13.caption-pill-karaoke",{"title":263,"path":264,"stem":265},"纹理","\u002Fcatalog\u002Fcaption\u002Fcaption-texture","06.catalog\u002F01.caption\u002F14.caption-texture",{"title":267,"path":268,"stem":269},"字重切换","\u002Fcatalog\u002Fcaption\u002Fcaption-weight-shift","06.catalog\u002F01.caption\u002F15.caption-weight-shift",{"title":271,"icon":272,"path":273,"stem":274,"children":275,"page":30},"HTML 画布","i-lucide-layout-dashboard","\u002Fcatalog\u002Fhtml-canvas","06.catalog\u002F02.html-canvas",[276,280,284,288,292,296,300,304,308,312,316,320],{"title":277,"path":278,"stem":279},"iOS 26 Liquid Glass 主屏幕","\u002Fcatalog\u002Fhtml-canvas\u002Fios26-liquid-glass","06.catalog\u002F02.html-canvas\u002F01.ios26-liquid-glass",{"title":281,"path":282,"stem":283},"Liquid Glass 右键菜单","\u002Fcatalog\u002Fhtml-canvas\u002Fliquid-glass-context-menu","06.catalog\u002F02.html-canvas\u002F02.liquid-glass-context-menu",{"title":285,"path":286,"stem":287},"Liquid Glass 媒体控制","\u002Fcatalog\u002Fhtml-canvas\u002Fliquid-glass-media-controls","06.catalog\u002F02.html-canvas\u002F03.liquid-glass-media-controls",{"title":289,"path":290,"stem":291},"Liquid Glass 通知","\u002Fcatalog\u002Fhtml-canvas\u002Fliquid-glass-notification","06.catalog\u002F02.html-canvas\u002F04.liquid-glass-notification",{"title":293,"path":294,"stem":295},"Liquid Glass 小组件","\u002Fcatalog\u002Fhtml-canvas\u002Fliquid-glass-widgets","06.catalog\u002F02.html-canvas\u002F05.liquid-glass-widgets",{"title":297,"path":298,"stem":299},"macOS Tahoe Liquid Glass 桌面","\u002Fcatalog\u002Fhtml-canvas\u002Fmacos-tahoe-liquid-glass","06.catalog\u002F02.html-canvas\u002F06.macos-tahoe-liquid-glass",{"title":301,"path":302,"stem":303},"iPhone & MacBook 3D 展示","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-iphone-device","06.catalog\u002F02.html-canvas\u002F07.vfx-iphone-device",{"title":305,"path":306,"stem":307},"液态背景","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-liquid-background","06.catalog\u002F02.html-canvas\u002F08.vfx-liquid-background",{"title":309,"path":310,"stem":311},"磁力效果","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-magnetic","06.catalog\u002F02.html-canvas\u002F09.vfx-magnetic",{"title":313,"path":314,"stem":315},"传送门","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-portal","06.catalog\u002F02.html-canvas\u002F10.vfx-portal",{"title":317,"path":318,"stem":319},"碎裂效果","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-shatter","06.catalog\u002F02.html-canvas\u002F11.vfx-shatter",{"title":321,"path":322,"stem":323},"VFX 文字光标","\u002Fcatalog\u002Fhtml-canvas\u002Fvfx-text-cursor","06.catalog\u002F02.html-canvas\u002F12.vfx-text-cursor",{"title":325,"icon":326,"path":327,"stem":328,"children":329,"page":30},"社交叠加层","i-lucide-share-2","\u002Fcatalog\u002Fsocial-overlays","06.catalog\u002F03.social-overlays",[330,334,338,342,346,350,354],{"title":331,"path":332,"stem":333},"Instagram 关注","\u002Fcatalog\u002Fsocial-overlays\u002Finstagram-follow","06.catalog\u002F03.social-overlays\u002F01.instagram-follow",{"title":335,"path":336,"stem":337},"macOS 通知","\u002Fcatalog\u002Fsocial-overlays\u002Fmacos-notification","06.catalog\u002F03.social-overlays\u002F02.macos-notification",{"title":339,"path":340,"stem":341},"Reddit 帖子卡片","\u002Fcatalog\u002Fsocial-overlays\u002Freddit-post","06.catalog\u002F03.social-overlays\u002F03.reddit-post",{"title":343,"path":344,"stem":345},"Spotify 正在播放","\u002Fcatalog\u002Fsocial-overlays\u002Fspotify-card","06.catalog\u002F03.social-overlays\u002F04.spotify-card",{"title":347,"path":348,"stem":349},"TikTok 关注","\u002Fcatalog\u002Fsocial-overlays\u002Ftiktok-follow","06.catalog\u002F03.social-overlays\u002F05.tiktok-follow",{"title":351,"path":352,"stem":353},"X 帖子卡片","\u002Fcatalog\u002Fsocial-overlays\u002Fx-post","06.catalog\u002F03.social-overlays\u002F06.x-post",{"title":355,"path":356,"stem":357},"YouTube 下方三分之一","\u002Fcatalog\u002Fsocial-overlays\u002Fyt-lower-third","06.catalog\u002F03.social-overlays\u002F07.yt-lower-third",{"title":359,"icon":360,"path":361,"stem":362,"children":363,"page":30},"着色器过渡","i-lucide-wand-2","\u002Fcatalog\u002Fshader-transitions","06.catalog\u002F04.shader-transitions",[364,368,372,376,380,384,388,392,396,400,404,408,412,416],{"title":365,"path":366,"stem":367},"色散径向分裂","\u002Fcatalog\u002Fshader-transitions\u002Fchromatic-radial-split","06.catalog\u002F04.shader-transitions\u002F01.chromatic-radial-split",{"title":369,"path":370,"stem":371},"电影感变焦","\u002Fcatalog\u002Fshader-transitions\u002Fcinematic-zoom","06.catalog\u002F04.shader-transitions\u002F02.cinematic-zoom",{"title":373,"path":374,"stem":375},"交叉扭曲变形","\u002Fcatalog\u002Fshader-transitions\u002Fcross-warp-morph","06.catalog\u002F04.shader-transitions\u002F03.cross-warp-morph",{"title":377,"path":378,"stem":379},"域扭曲溶解","\u002Fcatalog\u002Fshader-transitions\u002Fdomain-warp-dissolve","06.catalog\u002F04.shader-transitions\u002F04.domain-warp-dissolve",{"title":381,"path":382,"stem":383},"白色闪光过渡","\u002Fcatalog\u002Fshader-transitions\u002Fflash-through-white","06.catalog\u002F04.shader-transitions\u002F05.flash-through-white",{"title":385,"path":386,"stem":387},"故障效果","\u002Fcatalog\u002Fshader-transitions\u002Fglitch","06.catalog\u002F04.shader-transitions\u002F06.glitch",{"title":389,"path":390,"stem":391},"引力透镜","\u002Fcatalog\u002Fshader-transitions\u002Fgravitational-lens","06.catalog\u002F04.shader-transitions\u002F07.gravitational-lens",{"title":393,"path":394,"stem":395},"光线泄漏","\u002Fcatalog\u002Fshader-transitions\u002Flight-leak","06.catalog\u002F04.shader-transitions\u002F08.light-leak",{"title":397,"path":398,"stem":399},"褶皱燃烧","\u002Fcatalog\u002Fshader-transitions\u002Fridged-burn","06.catalog\u002F04.shader-transitions\u002F09.ridged-burn",{"title":401,"path":402,"stem":403},"涟漪波纹","\u002Fcatalog\u002Fshader-transitions\u002Fripple-waves","06.catalog\u002F04.shader-transitions\u002F10.ripple-waves",{"title":405,"path":406,"stem":407},"SDF 光圈","\u002Fcatalog\u002Fshader-transitions\u002Fsdf-iris","06.catalog\u002F04.shader-transitions\u002F11.sdf-iris",{"title":409,"path":410,"stem":411},"漩涡涡流","\u002Fcatalog\u002Fshader-transitions\u002Fswirl-vortex","06.catalog\u002F04.shader-transitions\u002F12.swirl-vortex",{"title":413,"path":414,"stem":415},"热浪扭曲","\u002Fcatalog\u002Fshader-transitions\u002Fthermal-distortion","06.catalog\u002F04.shader-transitions\u002F13.thermal-distortion",{"title":417,"path":418,"stem":419},"快速摇摄","\u002Fcatalog\u002Fshader-transitions\u002Fwhip-pan","06.catalog\u002F04.shader-transitions\u002F14.whip-pan",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":30},"CSS 过渡","i-lucide-repeat","\u002Fcatalog\u002Fcss-transitions","06.catalog\u002F05.css-transitions",[426,430,434,438,442,446,450,454,458,462,466,470,474],{"title":427,"path":428,"stem":429},"3D 过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-3d","06.catalog\u002F05.css-transitions\u002F01.transitions-3d",{"title":431,"path":432,"stem":433},"模糊过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-blur","06.catalog\u002F05.css-transitions\u002F02.transitions-blur",{"title":435,"path":436,"stem":437},"覆盖过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-cover","06.catalog\u002F05.css-transitions\u002F03.transitions-cover",{"title":439,"path":440,"stem":441},"破碎过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-destruction","06.catalog\u002F05.css-transitions\u002F04.transitions-destruction",{"title":443,"path":444,"stem":445},"溶解过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-dissolve","06.catalog\u002F05.css-transitions\u002F05.transitions-dissolve",{"title":447,"path":448,"stem":449},"扭曲过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-distortion","06.catalog\u002F05.css-transitions\u002F06.transitions-distortion",{"title":451,"path":452,"stem":453},"网格过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-grid","06.catalog\u002F05.css-transitions\u002F07.transitions-grid",{"title":455,"path":456,"stem":457},"光效过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-light","06.catalog\u002F05.css-transitions\u002F08.transitions-light",{"title":459,"path":460,"stem":461},"机械过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-mechanical","06.catalog\u002F05.css-transitions\u002F09.transitions-mechanical",{"title":463,"path":464,"stem":465},"其他过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-other","06.catalog\u002F05.css-transitions\u002F10.transitions-other",{"title":467,"path":468,"stem":469},"推移过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-push","06.catalog\u002F05.css-transitions\u002F11.transitions-push",{"title":471,"path":472,"stem":473},"径向过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-radial","06.catalog\u002F05.css-transitions\u002F12.transitions-radial",{"title":475,"path":476,"stem":477},"缩放过渡","\u002Fcatalog\u002Fcss-transitions\u002Ftransitions-scale","06.catalog\u002F05.css-transitions\u002F13.transitions-scale",{"title":479,"icon":480,"path":481,"stem":482,"children":483,"page":30},"展示","i-lucide-monitor-play","\u002Fcatalog\u002Fshowcase","06.catalog\u002F06.showcase",[484,488,492,496,500,504,508],{"title":485,"path":486,"stem":487},"应用展示","\u002Fcatalog\u002Fshowcase\u002Fapp-showcase","06.catalog\u002F06.showcase\u002F01.app-showcase",{"title":489,"path":490,"stem":491},"Apple 金额计数器","\u002Fcatalog\u002Fshowcase\u002Fapple-money-count","06.catalog\u002F06.showcase\u002F02.apple-money-count",{"title":493,"path":494,"stem":495},"蓝色毛衣开场视频","\u002Fcatalog\u002Fshowcase\u002Fblue-sweater-intro-video","06.catalog\u002F06.showcase\u002F03.blue-sweater-intro-video",{"title":497,"path":498,"stem":499},"朝鲜封锁","\u002Fcatalog\u002Fshowcase\u002Fnorth-korea-locked-down","06.catalog\u002F06.showcase\u002F04.north-korea-locked-down",{"title":501,"path":502,"stem":503},"纽约巴黎航班","\u002Fcatalog\u002Fshowcase\u002Fnyc-paris-flight","06.catalog\u002F06.showcase\u002F05.nyc-paris-flight",{"title":505,"path":506,"stem":507},"3D UI 展示","\u002Fcatalog\u002Fshowcase\u002Fui-3d-reveal","06.catalog\u002F06.showcase\u002F06.ui-3d-reveal",{"title":509,"path":510,"stem":511},"VPN YouTube 广告片段","\u002Fcatalog\u002Fshowcase\u002Fvpn-youtube-spot","06.catalog\u002F06.showcase\u002F07.vpn-youtube-spot",{"title":513,"icon":514,"path":515,"stem":516,"children":517,"page":30},"数据","i-lucide-bar-chart-3","\u002Fcatalog\u002Fdata","06.catalog\u002F07.data",[518,522,526,530,534,538,542],{"title":519,"path":520,"stem":521},"数据图表","\u002Fcatalog\u002Fdata\u002Fdata-chart","06.catalog\u002F07.data\u002F01.data-chart",{"title":523,"path":524,"stem":525},"西班牙地图","\u002Fcatalog\u002Fdata\u002Fspain-map","06.catalog\u002F07.data\u002F02.spain-map",{"title":527,"path":528,"stem":529},"美国地图","\u002Fcatalog\u002Fdata\u002Fus-map","06.catalog\u002F07.data\u002F03.us-map",{"title":531,"path":532,"stem":533},"美国气泡地图","\u002Fcatalog\u002Fdata\u002Fus-map-bubble","06.catalog\u002F07.data\u002F04.us-map-bubble",{"title":535,"path":536,"stem":537},"美国流动地图","\u002Fcatalog\u002Fdata\u002Fus-map-flow","06.catalog\u002F07.data\u002F05.us-map-flow",{"title":539,"path":540,"stem":541},"美国六边形网格地图","\u002Fcatalog\u002Fdata\u002Fus-map-hex","06.catalog\u002F07.data\u002F06.us-map-hex",{"title":543,"path":544,"stem":545},"世界地图","\u002Fcatalog\u002Fdata\u002Fworld-map","06.catalog\u002F07.data\u002F07.world-map",{"title":547,"icon":548,"path":549,"stem":550,"children":551,"page":30},"效果","i-lucide-sparkles","\u002Fcatalog\u002Feffects","06.catalog\u002F08.effects",[552,556,560,564,568,572,576,580],{"title":553,"path":554,"stem":555},"差值混合","\u002Fcatalog\u002Feffects\u002Fcaption-blend-difference","06.catalog\u002F08.effects\u002F01.caption-blend-difference",{"title":557,"path":558,"stem":559},"胶片颗粒叠加","\u002Fcatalog\u002Feffects\u002Fgrain-overlay","06.catalog\u002F08.effects\u002F02.grain-overlay",{"title":561,"path":562,"stem":563},"网格像素化擦除","\u002Fcatalog\u002Feffects\u002Fgrid-pixelate-wipe","06.catalog\u002F08.effects\u002F03.grid-pixelate-wipe",{"title":565,"path":566,"stem":567},"视差缩小","\u002Fcatalog\u002Feffects\u002Fparallax-unzoom","06.catalog\u002F08.effects\u002F04.parallax-unzoom",{"title":569,"path":570,"stem":571},"视差放大","\u002Fcatalog\u002Feffects\u002Fparallax-zoom","06.catalog\u002F08.effects\u002F05.parallax-zoom",{"title":573,"path":574,"stem":575},"微光扫过","\u002Fcatalog\u002Feffects\u002Fshimmer-sweep","06.catalog\u002F08.effects\u002F06.shimmer-sweep",{"title":577,"path":578,"stem":579},"纹理遮罩文字","\u002Fcatalog\u002Feffects\u002Ftexture-mask-text","06.catalog\u002F08.effects\u002F07.texture-mask-text",{"title":581,"path":582,"stem":583},"暗角","\u002Fcatalog\u002Feffects\u002Fvignette","06.catalog\u002F08.effects\u002F08.vignette",{"title":585,"icon":586,"path":587,"stem":588,"children":589,"page":30},"区块","i-lucide-box","\u002Fcatalog\u002Fblocks","06.catalog\u002F09.blocks",[590,594],{"title":591,"path":592,"stem":593},"流程图","\u002Fcatalog\u002Fblocks\u002Fflowchart","06.catalog\u002F09.blocks\u002F01.flowchart",{"title":595,"path":596,"stem":597},"Logo 片尾","\u002Fcatalog\u002Fblocks\u002Flogo-outro","06.catalog\u002F09.blocks\u002F02.logo-outro",{"title":599,"icon":600,"path":601,"stem":602,"children":603,"page":30},"代码片段","i-lucide-code-2","\u002Fcatalog\u002Fcode-snippets","06.catalog\u002F10.code-snippets",[604,608,612,616,620,624,628,632,636,640,644,648],{"title":605,"path":606,"stem":607},"Dark 2026","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-dark-2026","06.catalog\u002F10.code-snippets\u002F01.code-snippet-dark-2026",{"title":609,"path":610,"stem":611},"Dark Modern","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-dark-modern","06.catalog\u002F10.code-snippets\u002F02.code-snippet-dark-modern",{"title":613,"path":614,"stem":615},"Dark+","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-dark-plus","06.catalog\u002F10.code-snippets\u002F03.code-snippet-dark-plus",{"title":617,"path":618,"stem":619},"High Contrast","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-high-contrast","06.catalog\u002F10.code-snippets\u002F04.code-snippet-high-contrast",{"title":621,"path":622,"stem":623},"High Contrast Light","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-high-contrast-light","06.catalog\u002F10.code-snippets\u002F05.code-snippet-high-contrast-light",{"title":625,"path":626,"stem":627},"Light 2026","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-light-2026","06.catalog\u002F10.code-snippets\u002F06.code-snippet-light-2026",{"title":629,"path":630,"stem":631},"Light Modern","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-light-modern","06.catalog\u002F10.code-snippets\u002F07.code-snippet-light-modern",{"title":633,"path":634,"stem":635},"Light+","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-light-plus","06.catalog\u002F10.code-snippets\u002F08.code-snippet-light-plus",{"title":637,"path":638,"stem":639},"Monokai","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-monokai","06.catalog\u002F10.code-snippets\u002F09.code-snippet-monokai",{"title":641,"path":642,"stem":643},"Solarized Light","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-solarized-light","06.catalog\u002F10.code-snippets\u002F10.code-snippet-solarized-light",{"title":645,"path":646,"stem":647},"Visual Studio Dark","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-visual-studio-dark","06.catalog\u002F10.code-snippets\u002F11.code-snippet-visual-studio-dark",{"title":649,"path":650,"stem":651},"Visual Studio Light","\u002Fcatalog\u002Fcode-snippets\u002Fcode-snippet-visual-studio-light","06.catalog\u002F10.code-snippets\u002F12.code-snippet-visual-studio-light",{"title":653,"icon":654,"path":655,"stem":656,"children":657,"page":30},"参考","i-lucide-book-marked","\u002Freference","07.reference",[658,662,666,670,674,678,682],{"title":659,"path":660,"stem":661},"HTML Schema 参考","\u002Freference\u002Fhtml-schema","07.reference\u002F01.html-schema",{"title":663,"path":664,"stem":665},"贡献指南","\u002Freference\u002Fcontributing","07.reference\u002F02.contributing",{"title":667,"path":668,"stem":669},"贡献到 Catalog","\u002Freference\u002Fcatalog","07.reference\u002F03.catalog",{"title":671,"path":672,"stem":673},"发布渠道","\u002Freference\u002Frelease-channels","07.reference\u002F04.release-channels",{"title":675,"path":676,"stem":677},"测试本地 CLI 变更","\u002Freference\u002Ftesting-local-changes","07.reference\u002F05.testing-local-changes",{"title":679,"path":680,"stem":681},"Studio 手动 DOM 编辑","\u002Freference\u002Fstudio-manual-dom-editing","07.reference\u002F06.studio-manual-dom-editing",{"title":683,"path":684,"stem":685},"采用者","\u002Freference\u002Fadopters","07.reference\u002F07.adopters",{"id":687,"title":179,"body":688,"description":3733,"extension":3734,"links":3735,"meta":3736,"navigation":952,"path":180,"seo":3737,"stem":181,"__hash__":3738},"docs\u002F05.packages\u002F02.engine.md",{"type":689,"value":690,"toc":3698},"minimark",[691,696,705,730,734,762,770,786,791,815,818,825,830,837,840,843,846,853,857,863,866,869,875,878,1024,1027,1089,1093,1136,1139,1142,1561,1564,1693,1696,1699,2023,2028,2039,2082,2085,2088,2257,2260,2263,2441,2444,2544,2547,2710,2713,2716,2816,2820,2831,2848,2850,3075,3092,3096,3099,3333,3357,3364,3370,3570,3572,3576,3582,3602,3608,3611,3620,3642,3645,3649,3658,3661,3694],[692,693,695],"h1",{"id":694},"hyperframesengine","\"@hyperframes\u002Fengine\"",[697,698,699,700,704],"p",{},"engine 包提供了底层视频捕获管道：它在无头 Chrome 中加载 HTML 页面，独立地跳转到每一帧，并使用 Chrome 的 ",[701,702,703],"code",{},"HeadlessExperimental.beginFrame"," API 捕获像素缓冲区。这是使 Hyperframes 渲染具有确定性的核心层。",[706,707,712],"pre",{"className":708,"code":709,"language":710,"meta":711,"style":711},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npm install @hyperframes\u002Fengine\n","bash","",[701,713,714],{"__ignoreMap":711},[715,716,719,723,727],"span",{"class":717,"line":718},"line",1,[715,720,722],{"class":721},"sBMFI","npm",[715,724,726],{"class":725},"sfazB"," install",[715,728,729],{"class":725}," @hyperframes\u002Fengine\n",[731,732,733],"h2",{"id":733},"何时使用",[735,736,737,744],"blockquote",{},[697,738,739,740],{},"⚠️ ",[741,742,743],"strong",{},"Warning",[697,745,746,749,750,753,754,757,758,761],{},[741,747,748],{},"大多数用户不应直接使用 engine。"," 请改用 ",[751,752,195],"a",{"href":196},"（",[701,755,756],{},"npx hyperframes render","）或 ",[751,759,760],{"href":188},"producer"," 包 — 它们会为你处理运行时注入、音频混音和编码。",[697,763,764],{},[741,765,766,767,769],{},"在以下场景使用 ",[701,768,179],{},"：",[771,772,773,777,780,783],"ul",{},[774,775,776],"li",{},"构建具有完全帧捕获控制的自定义渲染管道",[774,778,779],{},"将 Hyperframes 捕获集成到现有的视频处理系统中",[774,781,782],{},"捕获单个帧（例如用于缩略图或精灵图）而不编码为视频",[774,784,785],{},"实现自定义编码后端（非 FFmpeg）",[697,787,788],{},[741,789,790],{},"如果需要以下功能，请使用其他包：",[771,792,793,801,809],{},[774,794,795,796,798,799],{},"将 HTML 合成渲染为成品 MP4 或 WebM — 使用 ",[751,797,760],{"href":188}," 或 ",[751,800,195],{"href":196},[774,802,803,804,798,806],{},"在浏览器中预览合成 — 使用 ",[751,805,195],{"href":196},[751,807,808],{"href":192},"studio",[774,810,811,812],{},"检查或解析合成 HTML — 使用 ",[751,813,814],{"href":176},"core",[731,816,817],{"id":817},"工作原理",[697,819,820,821,824],{},"engine 实现了一个与屏幕录制根本不同的",[741,822,823],{},"跳转并捕获","循环：",[826,827,829],"h3",{"id":828},"启动无头-chrome","启动无头 Chrome",[697,831,832,833,836],{},"engine 启动 ",[701,834,835],{},"chrome-headless-shell","，一个为通过 Chrome DevTools Protocol (CDP) 进行编程控制而优化的最小化无头 Chrome 二进制文件。",[826,838,839],{"id":839},"加载合成",[697,841,842],{},"你的 HTML 合成被加载到浏览器页面中。注入 Hyperframes 运行时来管理时间轴跳转。",[826,844,845],{"id":845},"逐帧跳转",[697,847,848,849,852],{},"对于视频中的每一帧（例如 30fps 的 30 秒视频有 900 帧），engine 调用 ",[701,850,851],{},"renderSeek(time)"," 将合成推进到精确的时间戳。不涉及时钟时间 — 每一帧都是独立定位的。",[826,854,856],{"id":855},"通过-beginframe-捕获","通过 BeginFrame 捕获",[697,858,859,860,862],{},"Chrome 的 ",[701,861,703],{}," API 将合成器输出捕获为像素缓冲区。这会产生像素完美的帧，没有任何屏幕录制伪影。",[826,864,865],{"id":865},"传递帧数据",[697,867,868],{},"捕获的帧缓冲区被传递给消费者 — 通常是 FFmpeg（通过 producer）编码为 MP4，但你也可以提供自己的消费者。",[697,870,871,872,874],{},"这种方法保证了",[751,873,54],{"href":55},"：相同的 HTML 始终产生相同的视频，无论系统负载或时序如何。",[731,876,877],{"id":877},"配置",[706,879,883],{"className":880,"code":881,"language":882,"meta":711,"style":711},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { resolveConfig, DEFAULT_CONFIG } from '@hyperframes\u002Fengine';\nimport type { EngineConfig } from '@hyperframes\u002Fengine';\n\n\u002F\u002F 使用默认值\nconst config = DEFAULT_CONFIG;\n\n\u002F\u002F 或使用覆盖项解析\nconst config = resolveConfig({\n\u002F\u002F ... 自定义选项\n});\n","typescript",[701,884,885,922,947,954,961,978,983,989,1007,1013],{"__ignoreMap":711},[715,886,887,891,895,899,902,905,908,911,914,916,919],{"class":717,"line":718},[715,888,890],{"class":889},"s7zQu","import",[715,892,894],{"class":893},"sMK4o"," {",[715,896,898],{"class":897},"sTEyZ"," resolveConfig",[715,900,901],{"class":893},",",[715,903,904],{"class":897}," DEFAULT_CONFIG",[715,906,907],{"class":893}," }",[715,909,910],{"class":889}," from",[715,912,913],{"class":893}," '",[715,915,179],{"class":725},[715,917,918],{"class":893},"'",[715,920,921],{"class":893},";\n",[715,923,925,927,930,932,935,937,939,941,943,945],{"class":717,"line":924},2,[715,926,890],{"class":889},[715,928,929],{"class":889}," type",[715,931,894],{"class":893},[715,933,934],{"class":897}," EngineConfig",[715,936,907],{"class":893},[715,938,910],{"class":889},[715,940,913],{"class":893},[715,942,179],{"class":725},[715,944,918],{"class":893},[715,946,921],{"class":893},[715,948,950],{"class":717,"line":949},3,[715,951,953],{"emptyLinePlaceholder":952},true,"\n",[715,955,957],{"class":717,"line":956},4,[715,958,960],{"class":959},"sHwdD","\u002F\u002F 使用默认值\n",[715,962,964,968,971,974,976],{"class":717,"line":963},5,[715,965,967],{"class":966},"spNyl","const",[715,969,970],{"class":897}," config ",[715,972,973],{"class":893},"=",[715,975,904],{"class":897},[715,977,921],{"class":893},[715,979,981],{"class":717,"line":980},6,[715,982,953],{"emptyLinePlaceholder":952},[715,984,986],{"class":717,"line":985},7,[715,987,988],{"class":959},"\u002F\u002F 或使用覆盖项解析\n",[715,990,992,994,996,998,1001,1004],{"class":717,"line":991},8,[715,993,967],{"class":966},[715,995,970],{"class":897},[715,997,973],{"class":893},[715,999,898],{"class":1000},"s2Zo4",[715,1002,1003],{"class":897},"(",[715,1005,1006],{"class":893},"{\n",[715,1008,1010],{"class":717,"line":1009},9,[715,1011,1012],{"class":959},"\u002F\u002F ... 自定义选项\n",[715,1014,1016,1019,1022],{"class":717,"line":1015},10,[715,1017,1018],{"class":893},"}",[715,1020,1021],{"class":897},")",[715,1023,921],{"class":893},[826,1025,1026],{"id":1026},"质量预设",[1028,1029,1030,1046],"table",{},[1031,1032,1033],"thead",{},[1034,1035,1036,1040,1043],"tr",{},[1037,1038,1039],"th",{},"预设",[1037,1041,1042],{},"使用场景",[1037,1044,1045],{},"速度",[1047,1048,1049,1063,1076],"tbody",{},[1034,1050,1051,1057,1060],{},[1052,1053,1054],"td",{},[701,1055,1056],{},"draft",[1052,1058,1059],{},"开发期间的快速迭代",[1052,1061,1062],{},"最快",[1034,1064,1065,1070,1073],{},[1052,1066,1067],{},[701,1068,1069],{},"standard",[1052,1071,1072],{},"生产渲染，质量与速度的良好平衡",[1052,1074,1075],{},"中等",[1034,1077,1078,1083,1086],{},[1052,1079,1080],{},[701,1081,1082],{},"high",[1052,1084,1085],{},"最终交付，最高质量",[1052,1087,1088],{},"最慢",[826,1090,1092],{"id":1091},"fps-选项","FPS 选项",[1028,1094,1095,1104],{},[1031,1096,1097],{},[1034,1098,1099,1102],{},[1037,1100,1101],{},"FPS",[1037,1103,1042],{},[1047,1105,1106,1116,1126],{},[1034,1107,1108,1113],{},[1052,1109,1110],{},[701,1111,1112],{},"24",[1052,1114,1115],{},"电影感，较小的文件大小",[1034,1117,1118,1123],{},[1052,1119,1120],{},[701,1121,1122],{},"30",[1052,1124,1125],{},"标准网页视频，良好的平衡",[1034,1127,1128,1133],{},[1052,1129,1130],{},[701,1131,1132],{},"60",[1052,1134,1135],{},"流畅的运动，UI 动画，屏幕录制",[731,1137,1138],{"id":1138},"编程方式使用",[697,1140,1141],{},"engine 使用基于会话的 API 进行帧捕获：",[706,1143,1145],{"className":880,"code":1144,"language":882,"meta":711,"style":711},"import {\ncreateCaptureSession,\ninitializeSession,\ncaptureFrame,\ncaptureFrameToBuffer,\ngetCompositionDuration,\ncloseCaptureSession,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 1. 创建捕获会话\nconst session = await createCaptureSession({ fps: { num: 30, den: 1 }, width: 1920, height: 1080 });\n\n\u002F\u002F 2. 用合成初始化\nawait initializeSession(session, '.\u002Fmy-video\u002Findex.html');\n\n\u002F\u002F 3. 获取总时长\nconst duration = getCompositionDuration(session);\n\n\u002F\u002F 4. 捕获帧\nconst totalFrames = Math.ceil(duration * 30);\nfor (let i = 0; i \u003C totalFrames; i++) {\n\u002F\u002F 捕获到磁盘\nconst result = await captureFrame(session, i);\n\u002F\u002F result.path, result.captureTimeMs\n\n\u002F\u002F 或捕获到缓冲区（内存中）\nconst bufResult = await captureFrameToBuffer(session, i);\n\u002F\u002F bufResult.buffer, bufResult.captureTimeMs\n}\n\n\u002F\u002F 5. 清理\nawait closeCaptureSession(session);\n",[701,1146,1147,1154,1162,1169,1176,1183,1190,1197,1211,1215,1220,1296,1301,1307,1332,1337,1343,1361,1366,1372,1403,1447,1453,1482,1488,1493,1499,1526,1532,1538,1543,1549],{"__ignoreMap":711},[715,1148,1149,1151],{"class":717,"line":718},[715,1150,890],{"class":889},[715,1152,1153],{"class":893}," {\n",[715,1155,1156,1159],{"class":717,"line":924},[715,1157,1158],{"class":897},"createCaptureSession",[715,1160,1161],{"class":893},",\n",[715,1163,1164,1167],{"class":717,"line":949},[715,1165,1166],{"class":897},"initializeSession",[715,1168,1161],{"class":893},[715,1170,1171,1174],{"class":717,"line":956},[715,1172,1173],{"class":897},"captureFrame",[715,1175,1161],{"class":893},[715,1177,1178,1181],{"class":717,"line":963},[715,1179,1180],{"class":897},"captureFrameToBuffer",[715,1182,1161],{"class":893},[715,1184,1185,1188],{"class":717,"line":980},[715,1186,1187],{"class":897},"getCompositionDuration",[715,1189,1161],{"class":893},[715,1191,1192,1195],{"class":717,"line":985},[715,1193,1194],{"class":897},"closeCaptureSession",[715,1196,1161],{"class":893},[715,1198,1199,1201,1203,1205,1207,1209],{"class":717,"line":991},[715,1200,1018],{"class":893},[715,1202,910],{"class":889},[715,1204,913],{"class":893},[715,1206,179],{"class":725},[715,1208,918],{"class":893},[715,1210,921],{"class":893},[715,1212,1213],{"class":717,"line":1009},[715,1214,953],{"emptyLinePlaceholder":952},[715,1216,1217],{"class":717,"line":1015},[715,1218,1219],{"class":959},"\u002F\u002F 1. 创建捕获会话\n",[715,1221,1223,1225,1228,1230,1233,1236,1238,1241,1245,1248,1250,1253,1255,1259,1261,1264,1266,1269,1272,1275,1277,1280,1282,1285,1287,1290,1292,1294],{"class":717,"line":1222},11,[715,1224,967],{"class":966},[715,1226,1227],{"class":897}," session ",[715,1229,973],{"class":893},[715,1231,1232],{"class":889}," await",[715,1234,1235],{"class":1000}," createCaptureSession",[715,1237,1003],{"class":897},[715,1239,1240],{"class":893},"{",[715,1242,1244],{"class":1243},"swJcz"," fps",[715,1246,1247],{"class":893},":",[715,1249,894],{"class":893},[715,1251,1252],{"class":1243}," num",[715,1254,1247],{"class":893},[715,1256,1258],{"class":1257},"sbssI"," 30",[715,1260,901],{"class":893},[715,1262,1263],{"class":1243}," den",[715,1265,1247],{"class":893},[715,1267,1268],{"class":1257}," 1",[715,1270,1271],{"class":893}," },",[715,1273,1274],{"class":1243}," width",[715,1276,1247],{"class":893},[715,1278,1279],{"class":1257}," 1920",[715,1281,901],{"class":893},[715,1283,1284],{"class":1243}," height",[715,1286,1247],{"class":893},[715,1288,1289],{"class":1257}," 1080",[715,1291,907],{"class":893},[715,1293,1021],{"class":897},[715,1295,921],{"class":893},[715,1297,1299],{"class":717,"line":1298},12,[715,1300,953],{"emptyLinePlaceholder":952},[715,1302,1304],{"class":717,"line":1303},13,[715,1305,1306],{"class":959},"\u002F\u002F 2. 用合成初始化\n",[715,1308,1310,1313,1316,1319,1321,1323,1326,1328,1330],{"class":717,"line":1309},14,[715,1311,1312],{"class":889},"await",[715,1314,1315],{"class":1000}," initializeSession",[715,1317,1318],{"class":897},"(session",[715,1320,901],{"class":893},[715,1322,913],{"class":893},[715,1324,1325],{"class":725},".\u002Fmy-video\u002Findex.html",[715,1327,918],{"class":893},[715,1329,1021],{"class":897},[715,1331,921],{"class":893},[715,1333,1335],{"class":717,"line":1334},15,[715,1336,953],{"emptyLinePlaceholder":952},[715,1338,1340],{"class":717,"line":1339},16,[715,1341,1342],{"class":959},"\u002F\u002F 3. 获取总时长\n",[715,1344,1346,1348,1351,1353,1356,1359],{"class":717,"line":1345},17,[715,1347,967],{"class":966},[715,1349,1350],{"class":897}," duration ",[715,1352,973],{"class":893},[715,1354,1355],{"class":1000}," getCompositionDuration",[715,1357,1358],{"class":897},"(session)",[715,1360,921],{"class":893},[715,1362,1364],{"class":717,"line":1363},18,[715,1365,953],{"emptyLinePlaceholder":952},[715,1367,1369],{"class":717,"line":1368},19,[715,1370,1371],{"class":959},"\u002F\u002F 4. 捕获帧\n",[715,1373,1375,1377,1380,1382,1385,1388,1391,1394,1397,1399,1401],{"class":717,"line":1374},20,[715,1376,967],{"class":966},[715,1378,1379],{"class":897}," totalFrames ",[715,1381,973],{"class":893},[715,1383,1384],{"class":897}," Math",[715,1386,1387],{"class":893},".",[715,1389,1390],{"class":1000},"ceil",[715,1392,1393],{"class":897},"(duration ",[715,1395,1396],{"class":893},"*",[715,1398,1258],{"class":1257},[715,1400,1021],{"class":897},[715,1402,921],{"class":893},[715,1404,1406,1409,1412,1415,1418,1420,1423,1426,1428,1431,1434,1436,1439,1442,1445],{"class":717,"line":1405},21,[715,1407,1408],{"class":889},"for",[715,1410,1411],{"class":897}," (",[715,1413,1414],{"class":966},"let",[715,1416,1417],{"class":897}," i ",[715,1419,973],{"class":893},[715,1421,1422],{"class":1257}," 0",[715,1424,1425],{"class":893},";",[715,1427,1417],{"class":897},[715,1429,1430],{"class":893},"\u003C",[715,1432,1433],{"class":897}," totalFrames",[715,1435,1425],{"class":893},[715,1437,1438],{"class":897}," i",[715,1440,1441],{"class":893},"++",[715,1443,1444],{"class":897},") ",[715,1446,1006],{"class":893},[715,1448,1450],{"class":717,"line":1449},22,[715,1451,1452],{"class":959},"\u002F\u002F 捕获到磁盘\n",[715,1454,1456,1458,1461,1464,1466,1469,1471,1474,1476,1478,1480],{"class":717,"line":1455},23,[715,1457,967],{"class":966},[715,1459,1460],{"class":897}," result",[715,1462,1463],{"class":893}," =",[715,1465,1232],{"class":889},[715,1467,1468],{"class":1000}," captureFrame",[715,1470,1003],{"class":1243},[715,1472,1473],{"class":897},"session",[715,1475,901],{"class":893},[715,1477,1438],{"class":897},[715,1479,1021],{"class":1243},[715,1481,921],{"class":893},[715,1483,1485],{"class":717,"line":1484},24,[715,1486,1487],{"class":959},"\u002F\u002F result.path, result.captureTimeMs\n",[715,1489,1491],{"class":717,"line":1490},25,[715,1492,953],{"emptyLinePlaceholder":952},[715,1494,1496],{"class":717,"line":1495},26,[715,1497,1498],{"class":959},"\u002F\u002F 或捕获到缓冲区（内存中）\n",[715,1500,1502,1504,1507,1509,1511,1514,1516,1518,1520,1522,1524],{"class":717,"line":1501},27,[715,1503,967],{"class":966},[715,1505,1506],{"class":897}," bufResult",[715,1508,1463],{"class":893},[715,1510,1232],{"class":889},[715,1512,1513],{"class":1000}," captureFrameToBuffer",[715,1515,1003],{"class":1243},[715,1517,1473],{"class":897},[715,1519,901],{"class":893},[715,1521,1438],{"class":897},[715,1523,1021],{"class":1243},[715,1525,921],{"class":893},[715,1527,1529],{"class":717,"line":1528},28,[715,1530,1531],{"class":959},"\u002F\u002F bufResult.buffer, bufResult.captureTimeMs\n",[715,1533,1535],{"class":717,"line":1534},29,[715,1536,1537],{"class":893},"}\n",[715,1539,1541],{"class":717,"line":1540},30,[715,1542,953],{"emptyLinePlaceholder":952},[715,1544,1546],{"class":717,"line":1545},31,[715,1547,1548],{"class":959},"\u002F\u002F 5. 清理\n",[715,1550,1552,1554,1557,1559],{"class":717,"line":1551},32,[715,1553,1312],{"class":889},[715,1555,1556],{"class":1000}," closeCaptureSession",[715,1558,1358],{"class":897},[715,1560,921],{"class":893},[826,1562,1563],{"id":1563},"浏览器管理",[706,1565,1567],{"className":880,"code":1566,"language":882,"meta":711,"style":711},"import {\nacquireBrowser,\nreleaseBrowser,\nresolveHeadlessShellPath,\nbuildChromeArgs,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 获取浏览器实例（创建或从池中复用）\nconst browser = await acquireBrowser();\n\n\u002F\u002F 获取 Chrome 二进制路径\nconst chromePath = await resolveHeadlessShellPath();\n\n\u002F\u002F 使用完毕后释放\nawait releaseBrowser(browser);\n",[701,1568,1569,1575,1582,1589,1596,1603,1617,1621,1626,1645,1649,1654,1672,1676,1681],{"__ignoreMap":711},[715,1570,1571,1573],{"class":717,"line":718},[715,1572,890],{"class":889},[715,1574,1153],{"class":893},[715,1576,1577,1580],{"class":717,"line":924},[715,1578,1579],{"class":897},"acquireBrowser",[715,1581,1161],{"class":893},[715,1583,1584,1587],{"class":717,"line":949},[715,1585,1586],{"class":897},"releaseBrowser",[715,1588,1161],{"class":893},[715,1590,1591,1594],{"class":717,"line":956},[715,1592,1593],{"class":897},"resolveHeadlessShellPath",[715,1595,1161],{"class":893},[715,1597,1598,1601],{"class":717,"line":963},[715,1599,1600],{"class":897},"buildChromeArgs",[715,1602,1161],{"class":893},[715,1604,1605,1607,1609,1611,1613,1615],{"class":717,"line":980},[715,1606,1018],{"class":893},[715,1608,910],{"class":889},[715,1610,913],{"class":893},[715,1612,179],{"class":725},[715,1614,918],{"class":893},[715,1616,921],{"class":893},[715,1618,1619],{"class":717,"line":985},[715,1620,953],{"emptyLinePlaceholder":952},[715,1622,1623],{"class":717,"line":991},[715,1624,1625],{"class":959},"\u002F\u002F 获取浏览器实例（创建或从池中复用）\n",[715,1627,1628,1630,1633,1635,1637,1640,1643],{"class":717,"line":1009},[715,1629,967],{"class":966},[715,1631,1632],{"class":897}," browser ",[715,1634,973],{"class":893},[715,1636,1232],{"class":889},[715,1638,1639],{"class":1000}," acquireBrowser",[715,1641,1642],{"class":897},"()",[715,1644,921],{"class":893},[715,1646,1647],{"class":717,"line":1015},[715,1648,953],{"emptyLinePlaceholder":952},[715,1650,1651],{"class":717,"line":1222},[715,1652,1653],{"class":959},"\u002F\u002F 获取 Chrome 二进制路径\n",[715,1655,1656,1658,1661,1663,1665,1668,1670],{"class":717,"line":1298},[715,1657,967],{"class":966},[715,1659,1660],{"class":897}," chromePath ",[715,1662,973],{"class":893},[715,1664,1232],{"class":889},[715,1666,1667],{"class":1000}," resolveHeadlessShellPath",[715,1669,1642],{"class":897},[715,1671,921],{"class":893},[715,1673,1674],{"class":717,"line":1303},[715,1675,953],{"emptyLinePlaceholder":952},[715,1677,1678],{"class":717,"line":1309},[715,1679,1680],{"class":959},"\u002F\u002F 使用完毕后释放\n",[715,1682,1683,1685,1688,1691],{"class":717,"line":1334},[715,1684,1312],{"class":889},[715,1686,1687],{"class":1000}," releaseBrowser",[715,1689,1690],{"class":897},"(browser)",[715,1692,921],{"class":893},[826,1694,1695],{"id":1695},"编码",[697,1697,1698],{},"engine 包含 FFmpeg 编码工具，支持 MP4 (h264) 和 WebM (VP9 带 alpha)：",[706,1700,1702],{"className":880,"code":1701,"language":882,"meta":711,"style":711},"import {\nencodeFramesFromDir,\nmuxVideoWithAudio,\napplyFaststart,\ndetectGpuEncoder,\ngetEncoderPreset,\nENCODER_PRESETS,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 获取格式感知的编码器设置\nconst mp4Preset = getEncoderPreset('standard', 'mp4');\n\u002F\u002F { codec: \"h264\", pixelFormat: \"yuv420p\", preset: \"medium\", quality: 23 }\n\nconst webmPreset = getEncoderPreset('standard', 'webm');\n\u002F\u002F { codec: \"vp9\", pixelFormat: \"yuva420p\", preset: \"good\", quality: 23 }\n\n\u002F\u002F 将捕获的帧编码为视频\nawait encodeFramesFromDir(framesDir, 'frame_%06d.png', outputPath, {\nfps: { num: 30, den: 1 },\n...webmPreset,\n});\n\n\u002F\u002F 将视频与音频混音（WebM 使用 Opus，MP4 使用 AAC）\nawait muxVideoWithAudio(videoPath, audioPath, outputPath);\n\n\u002F\u002F 应用 MP4 faststart 用于流式传输（WebM 不适用）\nawait applyFaststart(inputPath, outputPath);\n\n\u002F\u002F 检测 GPU 编码支持\nconst gpu = await detectGpuEncoder();\n\u002F\u002F gpu: \"nvenc\" | \"videotoolbox\" | \"vaapi\" | \"qsv\" | \"amf\" | null\n",[701,1703,1704,1710,1717,1724,1731,1738,1745,1752,1766,1770,1775,1808,1813,1817,1849,1854,1858,1863,1891,1917,1927,1935,1939,1944,1966,1970,1975,1991,1995,2000,2018],{"__ignoreMap":711},[715,1705,1706,1708],{"class":717,"line":718},[715,1707,890],{"class":889},[715,1709,1153],{"class":893},[715,1711,1712,1715],{"class":717,"line":924},[715,1713,1714],{"class":897},"encodeFramesFromDir",[715,1716,1161],{"class":893},[715,1718,1719,1722],{"class":717,"line":949},[715,1720,1721],{"class":897},"muxVideoWithAudio",[715,1723,1161],{"class":893},[715,1725,1726,1729],{"class":717,"line":956},[715,1727,1728],{"class":897},"applyFaststart",[715,1730,1161],{"class":893},[715,1732,1733,1736],{"class":717,"line":963},[715,1734,1735],{"class":897},"detectGpuEncoder",[715,1737,1161],{"class":893},[715,1739,1740,1743],{"class":717,"line":980},[715,1741,1742],{"class":897},"getEncoderPreset",[715,1744,1161],{"class":893},[715,1746,1747,1750],{"class":717,"line":985},[715,1748,1749],{"class":897},"ENCODER_PRESETS",[715,1751,1161],{"class":893},[715,1753,1754,1756,1758,1760,1762,1764],{"class":717,"line":991},[715,1755,1018],{"class":893},[715,1757,910],{"class":889},[715,1759,913],{"class":893},[715,1761,179],{"class":725},[715,1763,918],{"class":893},[715,1765,921],{"class":893},[715,1767,1768],{"class":717,"line":1009},[715,1769,953],{"emptyLinePlaceholder":952},[715,1771,1772],{"class":717,"line":1015},[715,1773,1774],{"class":959},"\u002F\u002F 获取格式感知的编码器设置\n",[715,1776,1777,1779,1782,1784,1787,1789,1791,1793,1795,1797,1799,1802,1804,1806],{"class":717,"line":1222},[715,1778,967],{"class":966},[715,1780,1781],{"class":897}," mp4Preset ",[715,1783,973],{"class":893},[715,1785,1786],{"class":1000}," getEncoderPreset",[715,1788,1003],{"class":897},[715,1790,918],{"class":893},[715,1792,1069],{"class":725},[715,1794,918],{"class":893},[715,1796,901],{"class":893},[715,1798,913],{"class":893},[715,1800,1801],{"class":725},"mp4",[715,1803,918],{"class":893},[715,1805,1021],{"class":897},[715,1807,921],{"class":893},[715,1809,1810],{"class":717,"line":1298},[715,1811,1812],{"class":959},"\u002F\u002F { codec: \"h264\", pixelFormat: \"yuv420p\", preset: \"medium\", quality: 23 }\n",[715,1814,1815],{"class":717,"line":1303},[715,1816,953],{"emptyLinePlaceholder":952},[715,1818,1819,1821,1824,1826,1828,1830,1832,1834,1836,1838,1840,1843,1845,1847],{"class":717,"line":1309},[715,1820,967],{"class":966},[715,1822,1823],{"class":897}," webmPreset ",[715,1825,973],{"class":893},[715,1827,1786],{"class":1000},[715,1829,1003],{"class":897},[715,1831,918],{"class":893},[715,1833,1069],{"class":725},[715,1835,918],{"class":893},[715,1837,901],{"class":893},[715,1839,913],{"class":893},[715,1841,1842],{"class":725},"webm",[715,1844,918],{"class":893},[715,1846,1021],{"class":897},[715,1848,921],{"class":893},[715,1850,1851],{"class":717,"line":1334},[715,1852,1853],{"class":959},"\u002F\u002F { codec: \"vp9\", pixelFormat: \"yuva420p\", preset: \"good\", quality: 23 }\n",[715,1855,1856],{"class":717,"line":1339},[715,1857,953],{"emptyLinePlaceholder":952},[715,1859,1860],{"class":717,"line":1345},[715,1861,1862],{"class":959},"\u002F\u002F 将捕获的帧编码为视频\n",[715,1864,1865,1867,1870,1873,1875,1877,1880,1882,1884,1887,1889],{"class":717,"line":1363},[715,1866,1312],{"class":889},[715,1868,1869],{"class":1000}," encodeFramesFromDir",[715,1871,1872],{"class":897},"(framesDir",[715,1874,901],{"class":893},[715,1876,913],{"class":893},[715,1878,1879],{"class":725},"frame_%06d.png",[715,1881,918],{"class":893},[715,1883,901],{"class":893},[715,1885,1886],{"class":897}," outputPath",[715,1888,901],{"class":893},[715,1890,1153],{"class":893},[715,1892,1893,1896,1898,1900,1902,1904,1906,1908,1910,1912,1914],{"class":717,"line":1368},[715,1894,1895],{"class":1243},"fps",[715,1897,1247],{"class":893},[715,1899,894],{"class":893},[715,1901,1252],{"class":1243},[715,1903,1247],{"class":893},[715,1905,1258],{"class":1257},[715,1907,901],{"class":893},[715,1909,1263],{"class":1243},[715,1911,1247],{"class":893},[715,1913,1268],{"class":1257},[715,1915,1916],{"class":893}," },\n",[715,1918,1919,1922,1925],{"class":717,"line":1374},[715,1920,1921],{"class":893},"...",[715,1923,1924],{"class":897},"webmPreset",[715,1926,1161],{"class":893},[715,1928,1929,1931,1933],{"class":717,"line":1405},[715,1930,1018],{"class":893},[715,1932,1021],{"class":897},[715,1934,921],{"class":893},[715,1936,1937],{"class":717,"line":1449},[715,1938,953],{"emptyLinePlaceholder":952},[715,1940,1941],{"class":717,"line":1455},[715,1942,1943],{"class":959},"\u002F\u002F 将视频与音频混音（WebM 使用 Opus，MP4 使用 AAC）\n",[715,1945,1946,1948,1951,1954,1956,1959,1961,1964],{"class":717,"line":1484},[715,1947,1312],{"class":889},[715,1949,1950],{"class":1000}," muxVideoWithAudio",[715,1952,1953],{"class":897},"(videoPath",[715,1955,901],{"class":893},[715,1957,1958],{"class":897}," audioPath",[715,1960,901],{"class":893},[715,1962,1963],{"class":897}," outputPath)",[715,1965,921],{"class":893},[715,1967,1968],{"class":717,"line":1490},[715,1969,953],{"emptyLinePlaceholder":952},[715,1971,1972],{"class":717,"line":1495},[715,1973,1974],{"class":959},"\u002F\u002F 应用 MP4 faststart 用于流式传输（WebM 不适用）\n",[715,1976,1977,1979,1982,1985,1987,1989],{"class":717,"line":1501},[715,1978,1312],{"class":889},[715,1980,1981],{"class":1000}," applyFaststart",[715,1983,1984],{"class":897},"(inputPath",[715,1986,901],{"class":893},[715,1988,1963],{"class":897},[715,1990,921],{"class":893},[715,1992,1993],{"class":717,"line":1528},[715,1994,953],{"emptyLinePlaceholder":952},[715,1996,1997],{"class":717,"line":1534},[715,1998,1999],{"class":959},"\u002F\u002F 检测 GPU 编码支持\n",[715,2001,2002,2004,2007,2009,2011,2014,2016],{"class":717,"line":1540},[715,2003,967],{"class":966},[715,2005,2006],{"class":897}," gpu ",[715,2008,973],{"class":893},[715,2010,1232],{"class":889},[715,2012,2013],{"class":1000}," detectGpuEncoder",[715,2015,1642],{"class":897},[715,2017,921],{"class":893},[715,2019,2020],{"class":717,"line":1545},[715,2021,2022],{"class":959},"\u002F\u002F gpu: \"nvenc\" | \"videotoolbox\" | \"vaapi\" | \"qsv\" | \"amf\" | null\n",[2024,2025,2027],"h4",{"id":2026},"webm-vp9-alpha","WebM VP9 Alpha",[697,2029,2030,2031,2034,2035,2038],{},"当编码透明度时，使用 ",[701,2032,2033],{},"format: \"webm\""," 配合 ",[701,2036,2037],{},"getEncoderPreset()","。这会配置：",[771,2040,2041,2054,2068,2076],{},[774,2042,2043,1411,2046,2049,2050,2053],{},[741,2044,2045],{},"VP9 编解码器",[701,2047,2048],{},"libvpx-vp9",") 配合支持 alpha 的 ",[701,2051,2052],{},"yuva420p"," 像素格式",[774,2055,2056,2061,2062,2067],{},[741,2057,2058],{},[701,2059,2060],{},"-auto-alt-ref 0"," 和 ",[741,2063,2064],{},[701,2065,2066],{},"alpha_mode=1"," 元数据用于正确的 alpha 编码",[774,2069,2070,2075],{},[741,2071,2072],{},[701,2073,2074],{},"-row-mt 1"," 用于多线程 VP9 编码",[774,2077,2078,2081],{},[741,2079,2080],{},"Opus 音频"," 在混流步骤中（而非 MP4 的 AAC）",[826,2083,2084],{"id":2084},"流式编码器",[697,2086,2087],{},"无需将帧写入磁盘即可进行内存高效的编码：",[706,2089,2091],{"className":880,"code":2090,"language":882,"meta":711,"style":711},"import { spawnStreamingEncoder } from '@hyperframes\u002Fengine';\n\nconst encoder = await spawnStreamingEncoder({\noutputPath: '.\u002Foutput.mp4',\nfps: { num: 30, den: 1 },\nwidth: 1920,\nheight: 1080,\n});\n\n\u002F\u002F 直接将帧送入编码器\nencoder.writeFrame(frameBuffer);\n\u002F\u002F ...\nconst result = await encoder.finalize();\n",[701,2092,2093,2114,2118,2135,2151,2175,2186,2197,2205,2209,2214,2229,2234],{"__ignoreMap":711},[715,2094,2095,2097,2099,2102,2104,2106,2108,2110,2112],{"class":717,"line":718},[715,2096,890],{"class":889},[715,2098,894],{"class":893},[715,2100,2101],{"class":897}," spawnStreamingEncoder",[715,2103,907],{"class":893},[715,2105,910],{"class":889},[715,2107,913],{"class":893},[715,2109,179],{"class":725},[715,2111,918],{"class":893},[715,2113,921],{"class":893},[715,2115,2116],{"class":717,"line":924},[715,2117,953],{"emptyLinePlaceholder":952},[715,2119,2120,2122,2125,2127,2129,2131,2133],{"class":717,"line":949},[715,2121,967],{"class":966},[715,2123,2124],{"class":897}," encoder ",[715,2126,973],{"class":893},[715,2128,1232],{"class":889},[715,2130,2101],{"class":1000},[715,2132,1003],{"class":897},[715,2134,1006],{"class":893},[715,2136,2137,2140,2142,2144,2147,2149],{"class":717,"line":956},[715,2138,2139],{"class":1243},"outputPath",[715,2141,1247],{"class":893},[715,2143,913],{"class":893},[715,2145,2146],{"class":725},".\u002Foutput.mp4",[715,2148,918],{"class":893},[715,2150,1161],{"class":893},[715,2152,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173],{"class":717,"line":963},[715,2154,1895],{"class":1243},[715,2156,1247],{"class":893},[715,2158,894],{"class":893},[715,2160,1252],{"class":1243},[715,2162,1247],{"class":893},[715,2164,1258],{"class":1257},[715,2166,901],{"class":893},[715,2168,1263],{"class":1243},[715,2170,1247],{"class":893},[715,2172,1268],{"class":1257},[715,2174,1916],{"class":893},[715,2176,2177,2180,2182,2184],{"class":717,"line":980},[715,2178,2179],{"class":1243},"width",[715,2181,1247],{"class":893},[715,2183,1279],{"class":1257},[715,2185,1161],{"class":893},[715,2187,2188,2191,2193,2195],{"class":717,"line":985},[715,2189,2190],{"class":1243},"height",[715,2192,1247],{"class":893},[715,2194,1289],{"class":1257},[715,2196,1161],{"class":893},[715,2198,2199,2201,2203],{"class":717,"line":991},[715,2200,1018],{"class":893},[715,2202,1021],{"class":897},[715,2204,921],{"class":893},[715,2206,2207],{"class":717,"line":1009},[715,2208,953],{"emptyLinePlaceholder":952},[715,2210,2211],{"class":717,"line":1015},[715,2212,2213],{"class":959},"\u002F\u002F 直接将帧送入编码器\n",[715,2215,2216,2219,2221,2224,2227],{"class":717,"line":1222},[715,2217,2218],{"class":897},"encoder",[715,2220,1387],{"class":893},[715,2222,2223],{"class":1000},"writeFrame",[715,2225,2226],{"class":897},"(frameBuffer)",[715,2228,921],{"class":893},[715,2230,2231],{"class":717,"line":1298},[715,2232,2233],{"class":959},"\u002F\u002F ...\n",[715,2235,2236,2238,2241,2243,2245,2248,2250,2253,2255],{"class":717,"line":1303},[715,2237,967],{"class":966},[715,2239,2240],{"class":897}," result ",[715,2242,973],{"class":893},[715,2244,1232],{"class":889},[715,2246,2247],{"class":897}," encoder",[715,2249,1387],{"class":893},[715,2251,2252],{"class":1000},"finalize",[715,2254,1642],{"class":897},[715,2256,921],{"class":893},[826,2258,2259],{"id":2259},"视频帧提取",[697,2261,2262],{},"从源视频文件中提取帧以注入浏览器：",[706,2264,2266],{"className":880,"code":2265,"language":882,"meta":711,"style":711},"import {\nparseVideoElements,\nextractAllVideoFrames,\ngetFrameAtTime,\ncreateFrameLookupTable,\nFrameLookupTable,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 从 HTML 解析视频元素\nconst videos = parseVideoElements(html);\n\n\u002F\u002F 从视频中提取所有帧\nconst frames = await extractAllVideoFrames(videoPath, { fps: 30 });\n\n\u002F\u002F 创建用于快速帧访问的查找表\nconst lookup = createFrameLookupTable(frames);\nconst frame = lookup.getFrameAtTime(5.0);\n",[701,2267,2268,2274,2281,2288,2295,2302,2309,2323,2327,2332,2349,2353,2358,2390,2394,2399,2416],{"__ignoreMap":711},[715,2269,2270,2272],{"class":717,"line":718},[715,2271,890],{"class":889},[715,2273,1153],{"class":893},[715,2275,2276,2279],{"class":717,"line":924},[715,2277,2278],{"class":897},"parseVideoElements",[715,2280,1161],{"class":893},[715,2282,2283,2286],{"class":717,"line":949},[715,2284,2285],{"class":897},"extractAllVideoFrames",[715,2287,1161],{"class":893},[715,2289,2290,2293],{"class":717,"line":956},[715,2291,2292],{"class":897},"getFrameAtTime",[715,2294,1161],{"class":893},[715,2296,2297,2300],{"class":717,"line":963},[715,2298,2299],{"class":897},"createFrameLookupTable",[715,2301,1161],{"class":893},[715,2303,2304,2307],{"class":717,"line":980},[715,2305,2306],{"class":897},"FrameLookupTable",[715,2308,1161],{"class":893},[715,2310,2311,2313,2315,2317,2319,2321],{"class":717,"line":985},[715,2312,1018],{"class":893},[715,2314,910],{"class":889},[715,2316,913],{"class":893},[715,2318,179],{"class":725},[715,2320,918],{"class":893},[715,2322,921],{"class":893},[715,2324,2325],{"class":717,"line":991},[715,2326,953],{"emptyLinePlaceholder":952},[715,2328,2329],{"class":717,"line":1009},[715,2330,2331],{"class":959},"\u002F\u002F 从 HTML 解析视频元素\n",[715,2333,2334,2336,2339,2341,2344,2347],{"class":717,"line":1015},[715,2335,967],{"class":966},[715,2337,2338],{"class":897}," videos ",[715,2340,973],{"class":893},[715,2342,2343],{"class":1000}," parseVideoElements",[715,2345,2346],{"class":897},"(html)",[715,2348,921],{"class":893},[715,2350,2351],{"class":717,"line":1222},[715,2352,953],{"emptyLinePlaceholder":952},[715,2354,2355],{"class":717,"line":1298},[715,2356,2357],{"class":959},"\u002F\u002F 从视频中提取所有帧\n",[715,2359,2360,2362,2365,2367,2369,2372,2374,2376,2378,2380,2382,2384,2386,2388],{"class":717,"line":1303},[715,2361,967],{"class":966},[715,2363,2364],{"class":897}," frames ",[715,2366,973],{"class":893},[715,2368,1232],{"class":889},[715,2370,2371],{"class":1000}," extractAllVideoFrames",[715,2373,1953],{"class":897},[715,2375,901],{"class":893},[715,2377,894],{"class":893},[715,2379,1244],{"class":1243},[715,2381,1247],{"class":893},[715,2383,1258],{"class":1257},[715,2385,907],{"class":893},[715,2387,1021],{"class":897},[715,2389,921],{"class":893},[715,2391,2392],{"class":717,"line":1309},[715,2393,953],{"emptyLinePlaceholder":952},[715,2395,2396],{"class":717,"line":1334},[715,2397,2398],{"class":959},"\u002F\u002F 创建用于快速帧访问的查找表\n",[715,2400,2401,2403,2406,2408,2411,2414],{"class":717,"line":1339},[715,2402,967],{"class":966},[715,2404,2405],{"class":897}," lookup ",[715,2407,973],{"class":893},[715,2409,2410],{"class":1000}," createFrameLookupTable",[715,2412,2413],{"class":897},"(frames)",[715,2415,921],{"class":893},[715,2417,2418,2420,2423,2425,2428,2430,2432,2434,2437,2439],{"class":717,"line":1345},[715,2419,967],{"class":966},[715,2421,2422],{"class":897}," frame ",[715,2424,973],{"class":893},[715,2426,2427],{"class":897}," lookup",[715,2429,1387],{"class":893},[715,2431,2292],{"class":1000},[715,2433,1003],{"class":897},[715,2435,2436],{"class":1257},"5.0",[715,2438,1021],{"class":897},[715,2440,921],{"class":893},[826,2442,2443],{"id":2443},"音频处理",[706,2445,2447],{"className":880,"code":2446,"language":882,"meta":711,"style":711},"import { parseAudioElements, processCompositionAudio } from '@hyperframes\u002Fengine';\n\n\u002F\u002F 从 HTML 解析音频元素\nconst audioElements = parseAudioElements(html);\n\n\u002F\u002F 处理并混音所有音频轨道\nconst mixResult = await processCompositionAudio({ audioElements, duration, fps });\n",[701,2448,2449,2475,2479,2484,2499,2503,2508],{"__ignoreMap":711},[715,2450,2451,2453,2455,2458,2460,2463,2465,2467,2469,2471,2473],{"class":717,"line":718},[715,2452,890],{"class":889},[715,2454,894],{"class":893},[715,2456,2457],{"class":897}," parseAudioElements",[715,2459,901],{"class":893},[715,2461,2462],{"class":897}," processCompositionAudio",[715,2464,907],{"class":893},[715,2466,910],{"class":889},[715,2468,913],{"class":893},[715,2470,179],{"class":725},[715,2472,918],{"class":893},[715,2474,921],{"class":893},[715,2476,2477],{"class":717,"line":924},[715,2478,953],{"emptyLinePlaceholder":952},[715,2480,2481],{"class":717,"line":949},[715,2482,2483],{"class":959},"\u002F\u002F 从 HTML 解析音频元素\n",[715,2485,2486,2488,2491,2493,2495,2497],{"class":717,"line":956},[715,2487,967],{"class":966},[715,2489,2490],{"class":897}," audioElements ",[715,2492,973],{"class":893},[715,2494,2457],{"class":1000},[715,2496,2346],{"class":897},[715,2498,921],{"class":893},[715,2500,2501],{"class":717,"line":963},[715,2502,953],{"emptyLinePlaceholder":952},[715,2504,2505],{"class":717,"line":980},[715,2506,2507],{"class":959},"\u002F\u002F 处理并混音所有音频轨道\n",[715,2509,2510,2512,2515,2517,2519,2521,2523,2525,2528,2530,2533,2535,2538,2540,2542],{"class":717,"line":985},[715,2511,967],{"class":966},[715,2513,2514],{"class":897}," mixResult ",[715,2516,973],{"class":893},[715,2518,1232],{"class":889},[715,2520,2462],{"class":1000},[715,2522,1003],{"class":897},[715,2524,1240],{"class":893},[715,2526,2527],{"class":897}," audioElements",[715,2529,901],{"class":893},[715,2531,2532],{"class":897}," duration",[715,2534,901],{"class":893},[715,2536,2537],{"class":897}," fps ",[715,2539,1018],{"class":893},[715,2541,1021],{"class":897},[715,2543,921],{"class":893},[826,2545,2546],{"id":2546},"并行渲染",[706,2548,2550],{"className":880,"code":2549,"language":882,"meta":711,"style":711},"import {\ncalculateOptimalWorkers,\ndistributeFrames,\nexecuteParallelCapture,\ngetSystemResources,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 检查系统资源\nconst resources = getSystemResources();\n\n\u002F\u002F 计算最优 worker 数量\nconst workers = calculateOptimalWorkers(totalFrames);\n\n\u002F\u002F 在 worker 之间分配帧\nconst tasks = distributeFrames(totalFrames, workers);\n\n\u002F\u002F 执行并行捕获\nconst results = await executeParallelCapture(tasks);\n",[701,2551,2552,2558,2565,2572,2579,2586,2600,2604,2609,2625,2629,2634,2651,2655,2660,2682,2686,2691],{"__ignoreMap":711},[715,2553,2554,2556],{"class":717,"line":718},[715,2555,890],{"class":889},[715,2557,1153],{"class":893},[715,2559,2560,2563],{"class":717,"line":924},[715,2561,2562],{"class":897},"calculateOptimalWorkers",[715,2564,1161],{"class":893},[715,2566,2567,2570],{"class":717,"line":949},[715,2568,2569],{"class":897},"distributeFrames",[715,2571,1161],{"class":893},[715,2573,2574,2577],{"class":717,"line":956},[715,2575,2576],{"class":897},"executeParallelCapture",[715,2578,1161],{"class":893},[715,2580,2581,2584],{"class":717,"line":963},[715,2582,2583],{"class":897},"getSystemResources",[715,2585,1161],{"class":893},[715,2587,2588,2590,2592,2594,2596,2598],{"class":717,"line":980},[715,2589,1018],{"class":893},[715,2591,910],{"class":889},[715,2593,913],{"class":893},[715,2595,179],{"class":725},[715,2597,918],{"class":893},[715,2599,921],{"class":893},[715,2601,2602],{"class":717,"line":985},[715,2603,953],{"emptyLinePlaceholder":952},[715,2605,2606],{"class":717,"line":991},[715,2607,2608],{"class":959},"\u002F\u002F 检查系统资源\n",[715,2610,2611,2613,2616,2618,2621,2623],{"class":717,"line":1009},[715,2612,967],{"class":966},[715,2614,2615],{"class":897}," resources ",[715,2617,973],{"class":893},[715,2619,2620],{"class":1000}," getSystemResources",[715,2622,1642],{"class":897},[715,2624,921],{"class":893},[715,2626,2627],{"class":717,"line":1015},[715,2628,953],{"emptyLinePlaceholder":952},[715,2630,2631],{"class":717,"line":1222},[715,2632,2633],{"class":959},"\u002F\u002F 计算最优 worker 数量\n",[715,2635,2636,2638,2641,2643,2646,2649],{"class":717,"line":1298},[715,2637,967],{"class":966},[715,2639,2640],{"class":897}," workers ",[715,2642,973],{"class":893},[715,2644,2645],{"class":1000}," calculateOptimalWorkers",[715,2647,2648],{"class":897},"(totalFrames)",[715,2650,921],{"class":893},[715,2652,2653],{"class":717,"line":1303},[715,2654,953],{"emptyLinePlaceholder":952},[715,2656,2657],{"class":717,"line":1309},[715,2658,2659],{"class":959},"\u002F\u002F 在 worker 之间分配帧\n",[715,2661,2662,2664,2667,2669,2672,2675,2677,2680],{"class":717,"line":1334},[715,2663,967],{"class":966},[715,2665,2666],{"class":897}," tasks ",[715,2668,973],{"class":893},[715,2670,2671],{"class":1000}," distributeFrames",[715,2673,2674],{"class":897},"(totalFrames",[715,2676,901],{"class":893},[715,2678,2679],{"class":897}," workers)",[715,2681,921],{"class":893},[715,2683,2684],{"class":717,"line":1339},[715,2685,953],{"emptyLinePlaceholder":952},[715,2687,2688],{"class":717,"line":1345},[715,2689,2690],{"class":959},"\u002F\u002F 执行并行捕获\n",[715,2692,2693,2695,2698,2700,2702,2705,2708],{"class":717,"line":1363},[715,2694,967],{"class":966},[715,2696,2697],{"class":897}," results ",[715,2699,973],{"class":893},[715,2701,1232],{"class":889},[715,2703,2704],{"class":1000}," executeParallelCapture",[715,2706,2707],{"class":897},"(tasks)",[715,2709,921],{"class":893},[826,2711,2712],{"id":2712},"文件服务器",[697,2714,2715],{},"通过 HTTP 为浏览器提供合成文件：",[706,2717,2719],{"className":880,"code":2718,"language":882,"meta":711,"style":711},"import { createFileServer } from '@hyperframes\u002Fengine';\n\nconst server = await createFileServer({ root: '.\u002Fmy-video', port: 0 });\n\u002F\u002F server.url, server.port\n\u002F\u002F ... 使用 server.url 作为合成 URL\nawait server.close();\n",[701,2720,2721,2742,2746,2790,2795,2800],{"__ignoreMap":711},[715,2722,2723,2725,2727,2730,2732,2734,2736,2738,2740],{"class":717,"line":718},[715,2724,890],{"class":889},[715,2726,894],{"class":893},[715,2728,2729],{"class":897}," createFileServer",[715,2731,907],{"class":893},[715,2733,910],{"class":889},[715,2735,913],{"class":893},[715,2737,179],{"class":725},[715,2739,918],{"class":893},[715,2741,921],{"class":893},[715,2743,2744],{"class":717,"line":924},[715,2745,953],{"emptyLinePlaceholder":952},[715,2747,2748,2750,2753,2755,2757,2759,2761,2763,2766,2768,2770,2773,2775,2777,2780,2782,2784,2786,2788],{"class":717,"line":949},[715,2749,967],{"class":966},[715,2751,2752],{"class":897}," server ",[715,2754,973],{"class":893},[715,2756,1232],{"class":889},[715,2758,2729],{"class":1000},[715,2760,1003],{"class":897},[715,2762,1240],{"class":893},[715,2764,2765],{"class":1243}," root",[715,2767,1247],{"class":893},[715,2769,913],{"class":893},[715,2771,2772],{"class":725},".\u002Fmy-video",[715,2774,918],{"class":893},[715,2776,901],{"class":893},[715,2778,2779],{"class":1243}," port",[715,2781,1247],{"class":893},[715,2783,1422],{"class":1257},[715,2785,907],{"class":893},[715,2787,1021],{"class":897},[715,2789,921],{"class":893},[715,2791,2792],{"class":717,"line":956},[715,2793,2794],{"class":959},"\u002F\u002F server.url, server.port\n",[715,2796,2797],{"class":717,"line":963},[715,2798,2799],{"class":959},"\u002F\u002F ... 使用 server.url 作为合成 URL\n",[715,2801,2802,2804,2807,2809,2812,2814],{"class":717,"line":980},[715,2803,1312],{"class":889},[715,2805,2806],{"class":897}," server",[715,2808,1387],{"class":893},[715,2810,2811],{"class":1000},"close",[715,2813,1642],{"class":897},[715,2815,921],{"class":893},[731,2817,2819],{"id":2818},"hdr-api","HDR API",[697,2821,2822,2823,2826,2827,2830],{},"engine 导出两层 HDR 支持：",[741,2824,2825],{},"色彩空间工具","（用于分类源并配置 FFmpeg 编码器）和 ",[741,2828,2829],{},"WebGPU 回读运行时","（用于将 CSS 动画 DOM 直接捕获为 HDR）。",[697,2832,2833,2834,2836,2837,2840,2841,2844,2845,2847],{},"要进行端到端的 HDR 渲染（将 HDR 视频和图像源合成为 HDR10 MP4），请使用 ",[751,2835,760],{"href":188}," 或带有 HDR 自动检测 \u002F ",[701,2838,2839],{},"--hdr"," \u002F ",[701,2842,2843],{},"--sdr"," 的 CLI 渲染管道 — 参见 ",[751,2846,112],{"href":113},"。以下 API 用于自定义集成。",[826,2849,2825],{"id":2825},[706,2851,2853],{"className":880,"code":2852,"language":882,"meta":711,"style":711},"import {\nisHdrColorSpace,\ndetectTransfer,\nanalyzeCompositionHdr,\ngetHdrEncoderColorParams,\nDEFAULT_HDR10_MASTERING,\n} from '@hyperframes\u002Fengine';\nimport type { HdrTransfer, HdrEncoderColorParams, HdrMasteringMetadata } from '@hyperframes\u002Fengine';\n\n\u002F\u002F 从 ffprobe 色彩空间分类单个源\nisHdrColorSpace(colorSpace);          \u002F\u002F boolean — BT.2020 \u002F PQ \u002F HLG 时为 true\ndetectTransfer(colorSpace);           \u002F\u002F 'pq' | 'hlg'（先检查 isHdrColorSpace）\n\n\u002F\u002F 在多个源中选择主要的传输特性\nanalyzeCompositionHdr([cs1, cs2]);    \u002F\u002F { hasHdr, dominantTransfer: 'pq' | 'hlg' | null }\n\n\u002F\u002F 为 x265 构建 FFmpeg 色彩参数 + HDR10 静态元数据\nconst params = getHdrEncoderColorParams('pq');\n\u002F\u002F {\n\u002F\u002F   colorPrimaries: 'bt2020',\n\u002F\u002F   colorTrc: 'smpte2084',\n\u002F\u002F   colorspace: 'bt2020nc',\n\u002F\u002F   pixelFormat: 'yuv420p10le',\n\u002F\u002F   x265ColorParams: 'colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display=...:max-cll=1000,400',\n\u002F\u002F   mastering: { masterDisplay: '...', maxCll: '1000,400' },\n\u002F\u002F }\n",[701,2854,2855,2861,2868,2875,2882,2889,2896,2910,2943,2947,2952,2964,2975,2979,2984,3001,3005,3010,3035,3040,3045,3050,3055,3060,3065,3070],{"__ignoreMap":711},[715,2856,2857,2859],{"class":717,"line":718},[715,2858,890],{"class":889},[715,2860,1153],{"class":893},[715,2862,2863,2866],{"class":717,"line":924},[715,2864,2865],{"class":897},"isHdrColorSpace",[715,2867,1161],{"class":893},[715,2869,2870,2873],{"class":717,"line":949},[715,2871,2872],{"class":897},"detectTransfer",[715,2874,1161],{"class":893},[715,2876,2877,2880],{"class":717,"line":956},[715,2878,2879],{"class":897},"analyzeCompositionHdr",[715,2881,1161],{"class":893},[715,2883,2884,2887],{"class":717,"line":963},[715,2885,2886],{"class":897},"getHdrEncoderColorParams",[715,2888,1161],{"class":893},[715,2890,2891,2894],{"class":717,"line":980},[715,2892,2893],{"class":897},"DEFAULT_HDR10_MASTERING",[715,2895,1161],{"class":893},[715,2897,2898,2900,2902,2904,2906,2908],{"class":717,"line":985},[715,2899,1018],{"class":893},[715,2901,910],{"class":889},[715,2903,913],{"class":893},[715,2905,179],{"class":725},[715,2907,918],{"class":893},[715,2909,921],{"class":893},[715,2911,2912,2914,2916,2918,2921,2923,2926,2928,2931,2933,2935,2937,2939,2941],{"class":717,"line":991},[715,2913,890],{"class":889},[715,2915,929],{"class":889},[715,2917,894],{"class":893},[715,2919,2920],{"class":897}," HdrTransfer",[715,2922,901],{"class":893},[715,2924,2925],{"class":897}," HdrEncoderColorParams",[715,2927,901],{"class":893},[715,2929,2930],{"class":897}," HdrMasteringMetadata",[715,2932,907],{"class":893},[715,2934,910],{"class":889},[715,2936,913],{"class":893},[715,2938,179],{"class":725},[715,2940,918],{"class":893},[715,2942,921],{"class":893},[715,2944,2945],{"class":717,"line":1009},[715,2946,953],{"emptyLinePlaceholder":952},[715,2948,2949],{"class":717,"line":1015},[715,2950,2951],{"class":959},"\u002F\u002F 从 ffprobe 色彩空间分类单个源\n",[715,2953,2954,2956,2959,2961],{"class":717,"line":1222},[715,2955,2865],{"class":1000},[715,2957,2958],{"class":897},"(colorSpace)",[715,2960,1425],{"class":893},[715,2962,2963],{"class":959},"          \u002F\u002F boolean — BT.2020 \u002F PQ \u002F HLG 时为 true\n",[715,2965,2966,2968,2970,2972],{"class":717,"line":1298},[715,2967,2872],{"class":1000},[715,2969,2958],{"class":897},[715,2971,1425],{"class":893},[715,2973,2974],{"class":959},"           \u002F\u002F 'pq' | 'hlg'（先检查 isHdrColorSpace）\n",[715,2976,2977],{"class":717,"line":1303},[715,2978,953],{"emptyLinePlaceholder":952},[715,2980,2981],{"class":717,"line":1309},[715,2982,2983],{"class":959},"\u002F\u002F 在多个源中选择主要的传输特性\n",[715,2985,2986,2988,2991,2993,2996,2998],{"class":717,"line":1334},[715,2987,2879],{"class":1000},[715,2989,2990],{"class":897},"([cs1",[715,2992,901],{"class":893},[715,2994,2995],{"class":897}," cs2])",[715,2997,1425],{"class":893},[715,2999,3000],{"class":959},"    \u002F\u002F { hasHdr, dominantTransfer: 'pq' | 'hlg' | null }\n",[715,3002,3003],{"class":717,"line":1339},[715,3004,953],{"emptyLinePlaceholder":952},[715,3006,3007],{"class":717,"line":1345},[715,3008,3009],{"class":959},"\u002F\u002F 为 x265 构建 FFmpeg 色彩参数 + HDR10 静态元数据\n",[715,3011,3012,3014,3017,3019,3022,3024,3026,3029,3031,3033],{"class":717,"line":1363},[715,3013,967],{"class":966},[715,3015,3016],{"class":897}," params ",[715,3018,973],{"class":893},[715,3020,3021],{"class":1000}," getHdrEncoderColorParams",[715,3023,1003],{"class":897},[715,3025,918],{"class":893},[715,3027,3028],{"class":725},"pq",[715,3030,918],{"class":893},[715,3032,1021],{"class":897},[715,3034,921],{"class":893},[715,3036,3037],{"class":717,"line":1368},[715,3038,3039],{"class":959},"\u002F\u002F {\n",[715,3041,3042],{"class":717,"line":1374},[715,3043,3044],{"class":959},"\u002F\u002F   colorPrimaries: 'bt2020',\n",[715,3046,3047],{"class":717,"line":1405},[715,3048,3049],{"class":959},"\u002F\u002F   colorTrc: 'smpte2084',\n",[715,3051,3052],{"class":717,"line":1449},[715,3053,3054],{"class":959},"\u002F\u002F   colorspace: 'bt2020nc',\n",[715,3056,3057],{"class":717,"line":1455},[715,3058,3059],{"class":959},"\u002F\u002F   pixelFormat: 'yuv420p10le',\n",[715,3061,3062],{"class":717,"line":1484},[715,3063,3064],{"class":959},"\u002F\u002F   x265ColorParams: 'colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc:master-display=...:max-cll=1000,400',\n",[715,3066,3067],{"class":717,"line":1490},[715,3068,3069],{"class":959},"\u002F\u002F   mastering: { masterDisplay: '...', maxCll: '1000,400' },\n",[715,3071,3072],{"class":717,"line":1495},[715,3073,3074],{"class":959},"\u002F\u002F }\n",[697,3076,3077,3079,3080,3084,3085,3088,3089,3091],{},[701,3078,2886],{}," 始终包含颜色标签",[3081,3082,3083],"em",{},"和"," HDR10 静态元数据（母版显示 + 内容光照级别）。没有这些元数据，下游播放器会将文件视为 SDR BT.2020 并进行错误的色调映射。如果你有测量过的逐内容值，请传入自定义 ",[701,3086,3087],{},"HdrMasteringMetadata","；否则保守的 ",[701,3090,2893],{}," 默认值与大多数 HDR10 调色套件标记内容的方式一致。",[826,3093,3095],{"id":3094},"webgpu-hdr-dom-捕获","WebGPU HDR DOM 捕获",[697,3097,3098],{},"要将 CSS 动画 DOM 直接捕获为 HDR（不涉及 FFmpeg 源），engine 提供了单独的 WebGPU 管道：",[706,3100,3102],{"className":880,"code":3101,"language":882,"meta":711,"style":711},"import {\nlaunchHdrBrowser,\nbuildHdrChromeArgs,\ninitHdrReadback,\nuploadAndReadbackHdrFrame,\nfloat16ToPqRgb,\n} from '@hyperframes\u002Fengine';\n\n\u002F\u002F 启动启用了 WebGPU 的有头 Chrome\nconst { browser, page } = await launchHdrBrowser({ width: 1920, height: 1080 });\n\n\u002F\u002F 注入 WebGPU 回读运行时\nconst ok = await initHdrReadback(page, 1920, 1080);\n\n\u002F\u002F 对于每一帧：上传 float16 像素，回读 float16 RGBA\nconst { rgba16, bytesPerRow } = await uploadAndReadbackHdrFrame(page, float16Base64);\n\n\u002F\u002F 将线性 float16 转换为 PQ 编码的 16 位 RGB，适合通过管道传入 ffmpeg\u002Fx265\nconst pqRgb = float16ToPqRgb(rgba16, width, height, bytesPerRow);\n",[701,3103,3104,3110,3117,3124,3131,3138,3145,3159,3163,3168,3215,3219,3224,3253,3257,3262,3294,3298,3303],{"__ignoreMap":711},[715,3105,3106,3108],{"class":717,"line":718},[715,3107,890],{"class":889},[715,3109,1153],{"class":893},[715,3111,3112,3115],{"class":717,"line":924},[715,3113,3114],{"class":897},"launchHdrBrowser",[715,3116,1161],{"class":893},[715,3118,3119,3122],{"class":717,"line":949},[715,3120,3121],{"class":897},"buildHdrChromeArgs",[715,3123,1161],{"class":893},[715,3125,3126,3129],{"class":717,"line":956},[715,3127,3128],{"class":897},"initHdrReadback",[715,3130,1161],{"class":893},[715,3132,3133,3136],{"class":717,"line":963},[715,3134,3135],{"class":897},"uploadAndReadbackHdrFrame",[715,3137,1161],{"class":893},[715,3139,3140,3143],{"class":717,"line":980},[715,3141,3142],{"class":897},"float16ToPqRgb",[715,3144,1161],{"class":893},[715,3146,3147,3149,3151,3153,3155,3157],{"class":717,"line":985},[715,3148,1018],{"class":893},[715,3150,910],{"class":889},[715,3152,913],{"class":893},[715,3154,179],{"class":725},[715,3156,918],{"class":893},[715,3158,921],{"class":893},[715,3160,3161],{"class":717,"line":991},[715,3162,953],{"emptyLinePlaceholder":952},[715,3164,3165],{"class":717,"line":1009},[715,3166,3167],{"class":959},"\u002F\u002F 启动启用了 WebGPU 的有头 Chrome\n",[715,3169,3170,3172,3174,3177,3179,3182,3184,3186,3188,3191,3193,3195,3197,3199,3201,3203,3205,3207,3209,3211,3213],{"class":717,"line":1015},[715,3171,967],{"class":966},[715,3173,894],{"class":893},[715,3175,3176],{"class":897}," browser",[715,3178,901],{"class":893},[715,3180,3181],{"class":897}," page ",[715,3183,1018],{"class":893},[715,3185,1463],{"class":893},[715,3187,1232],{"class":889},[715,3189,3190],{"class":1000}," launchHdrBrowser",[715,3192,1003],{"class":897},[715,3194,1240],{"class":893},[715,3196,1274],{"class":1243},[715,3198,1247],{"class":893},[715,3200,1279],{"class":1257},[715,3202,901],{"class":893},[715,3204,1284],{"class":1243},[715,3206,1247],{"class":893},[715,3208,1289],{"class":1257},[715,3210,907],{"class":893},[715,3212,1021],{"class":897},[715,3214,921],{"class":893},[715,3216,3217],{"class":717,"line":1222},[715,3218,953],{"emptyLinePlaceholder":952},[715,3220,3221],{"class":717,"line":1298},[715,3222,3223],{"class":959},"\u002F\u002F 注入 WebGPU 回读运行时\n",[715,3225,3226,3228,3231,3233,3235,3238,3241,3243,3245,3247,3249,3251],{"class":717,"line":1303},[715,3227,967],{"class":966},[715,3229,3230],{"class":897}," ok ",[715,3232,973],{"class":893},[715,3234,1232],{"class":889},[715,3236,3237],{"class":1000}," initHdrReadback",[715,3239,3240],{"class":897},"(page",[715,3242,901],{"class":893},[715,3244,1279],{"class":1257},[715,3246,901],{"class":893},[715,3248,1289],{"class":1257},[715,3250,1021],{"class":897},[715,3252,921],{"class":893},[715,3254,3255],{"class":717,"line":1309},[715,3256,953],{"emptyLinePlaceholder":952},[715,3258,3259],{"class":717,"line":1334},[715,3260,3261],{"class":959},"\u002F\u002F 对于每一帧：上传 float16 像素，回读 float16 RGBA\n",[715,3263,3264,3266,3268,3271,3273,3276,3278,3280,3282,3285,3287,3289,3292],{"class":717,"line":1339},[715,3265,967],{"class":966},[715,3267,894],{"class":893},[715,3269,3270],{"class":897}," rgba16",[715,3272,901],{"class":893},[715,3274,3275],{"class":897}," bytesPerRow ",[715,3277,1018],{"class":893},[715,3279,1463],{"class":893},[715,3281,1232],{"class":889},[715,3283,3284],{"class":1000}," uploadAndReadbackHdrFrame",[715,3286,3240],{"class":897},[715,3288,901],{"class":893},[715,3290,3291],{"class":897}," float16Base64)",[715,3293,921],{"class":893},[715,3295,3296],{"class":717,"line":1345},[715,3297,953],{"emptyLinePlaceholder":952},[715,3299,3300],{"class":717,"line":1363},[715,3301,3302],{"class":959},"\u002F\u002F 将线性 float16 转换为 PQ 编码的 16 位 RGB，适合通过管道传入 ffmpeg\u002Fx265\n",[715,3304,3305,3307,3310,3312,3315,3318,3320,3322,3324,3326,3328,3331],{"class":717,"line":1368},[715,3306,967],{"class":966},[715,3308,3309],{"class":897}," pqRgb ",[715,3311,973],{"class":893},[715,3313,3314],{"class":1000}," float16ToPqRgb",[715,3316,3317],{"class":897},"(rgba16",[715,3319,901],{"class":893},[715,3321,1274],{"class":897},[715,3323,901],{"class":893},[715,3325,1284],{"class":897},[715,3327,901],{"class":893},[715,3329,3330],{"class":897}," bytesPerRow)",[715,3332,921],{"class":893},[735,3334,3335,3339],{},[697,3336,739,3337],{},[741,3338,743],{},[697,3340,3341,3342,3349,3350,3352,3353,3356],{},"此路径需要",[741,3343,3344,3345,3348],{},"带有 ",[701,3346,3347],{},"--enable-unsafe-webgpu"," 的有头 Chrome"," — WebGPU 在 ",[701,3351,835],{}," 中不可用。默认的 HDR 感知渲染管道（通过 FFmpeg 从源中提取 HDR 像素并在 Node 中合成）",[3081,3354,3355],{},"不使用","此路径。仅在需要 CSS 动画驱动 HDR 像素输出的高级自定义管道中使用它。",[731,3358,3360,3363],{"id":3359},"window__hf-协议",[701,3361,3362],{},"window.__hf"," 协议",[697,3365,3366,3367,3369],{},"engine 通过 ",[701,3368,3362],{}," 协议与浏览器页面通信。任何实现了此协议的页面都可以被 engine 捕获 — 你不仅限于 Hyperframes 合成。",[706,3371,3373],{"className":880,"code":3372,"language":882,"meta":711,"style":711},"\u002F\u002F 页面必须在 window.__hf 上暴露此接口\ninterface HfProtocol {\nduration: number;                  \u002F\u002F 总时长（秒）\nseek(time: number): void;         \u002F\u002F 跳转到指定时间\nmedia?: HfMediaElement[];         \u002F\u002F 可选的媒体元素声明\n}\n\ninterface HfMediaElement {\nelementId: string;                 \u002F\u002F DOM 元素 ID\nsrc: string;                       \u002F\u002F 媒体源 URL\nstartTime: number;                 \u002F\u002F 时间轴上的开始时间\nendTime: number;                   \u002F\u002F 时间轴上的结束时间\nmediaOffset?: number;              \u002F\u002F 源中的播放偏移\nvolume?: number;                   \u002F\u002F 音量 (0-1)\nhasAudio?: boolean;                \u002F\u002F 元素是否包含音频\n}\n",[701,3374,3375,3380,3390,3405,3431,3450,3454,3458,3466,3481,3495,3509,3523,3537,3551,3566],{"__ignoreMap":711},[715,3376,3377],{"class":717,"line":718},[715,3378,3379],{"class":959},"\u002F\u002F 页面必须在 window.__hf 上暴露此接口\n",[715,3381,3382,3385,3388],{"class":717,"line":924},[715,3383,3384],{"class":966},"interface",[715,3386,3387],{"class":721}," HfProtocol",[715,3389,1153],{"class":893},[715,3391,3392,3395,3397,3400,3402],{"class":717,"line":949},[715,3393,3394],{"class":1243},"duration",[715,3396,1247],{"class":893},[715,3398,3399],{"class":721}," number",[715,3401,1425],{"class":893},[715,3403,3404],{"class":959},"                  \u002F\u002F 总时长（秒）\n",[715,3406,3407,3410,3412,3416,3418,3420,3423,3426,3428],{"class":717,"line":956},[715,3408,3409],{"class":1243},"seek",[715,3411,1003],{"class":893},[715,3413,3415],{"class":3414},"sHdIc","time",[715,3417,1247],{"class":893},[715,3419,3399],{"class":721},[715,3421,3422],{"class":893},"):",[715,3424,3425],{"class":721}," void",[715,3427,1425],{"class":893},[715,3429,3430],{"class":959},"         \u002F\u002F 跳转到指定时间\n",[715,3432,3433,3436,3439,3442,3445,3447],{"class":717,"line":963},[715,3434,3435],{"class":1243},"media",[715,3437,3438],{"class":893},"?:",[715,3440,3441],{"class":721}," HfMediaElement",[715,3443,3444],{"class":897},"[]",[715,3446,1425],{"class":893},[715,3448,3449],{"class":959},"         \u002F\u002F 可选的媒体元素声明\n",[715,3451,3452],{"class":717,"line":980},[715,3453,1537],{"class":893},[715,3455,3456],{"class":717,"line":985},[715,3457,953],{"emptyLinePlaceholder":952},[715,3459,3460,3462,3464],{"class":717,"line":991},[715,3461,3384],{"class":966},[715,3463,3441],{"class":721},[715,3465,1153],{"class":893},[715,3467,3468,3471,3473,3476,3478],{"class":717,"line":1009},[715,3469,3470],{"class":1243},"elementId",[715,3472,1247],{"class":893},[715,3474,3475],{"class":721}," string",[715,3477,1425],{"class":893},[715,3479,3480],{"class":959},"                 \u002F\u002F DOM 元素 ID\n",[715,3482,3483,3486,3488,3490,3492],{"class":717,"line":1015},[715,3484,3485],{"class":1243},"src",[715,3487,1247],{"class":893},[715,3489,3475],{"class":721},[715,3491,1425],{"class":893},[715,3493,3494],{"class":959},"                       \u002F\u002F 媒体源 URL\n",[715,3496,3497,3500,3502,3504,3506],{"class":717,"line":1222},[715,3498,3499],{"class":1243},"startTime",[715,3501,1247],{"class":893},[715,3503,3399],{"class":721},[715,3505,1425],{"class":893},[715,3507,3508],{"class":959},"                 \u002F\u002F 时间轴上的开始时间\n",[715,3510,3511,3514,3516,3518,3520],{"class":717,"line":1298},[715,3512,3513],{"class":1243},"endTime",[715,3515,1247],{"class":893},[715,3517,3399],{"class":721},[715,3519,1425],{"class":893},[715,3521,3522],{"class":959},"                   \u002F\u002F 时间轴上的结束时间\n",[715,3524,3525,3528,3530,3532,3534],{"class":717,"line":1303},[715,3526,3527],{"class":1243},"mediaOffset",[715,3529,3438],{"class":893},[715,3531,3399],{"class":721},[715,3533,1425],{"class":893},[715,3535,3536],{"class":959},"              \u002F\u002F 源中的播放偏移\n",[715,3538,3539,3542,3544,3546,3548],{"class":717,"line":1309},[715,3540,3541],{"class":1243},"volume",[715,3543,3438],{"class":893},[715,3545,3399],{"class":721},[715,3547,1425],{"class":893},[715,3549,3550],{"class":959},"                   \u002F\u002F 音量 (0-1)\n",[715,3552,3553,3556,3558,3561,3563],{"class":717,"line":1334},[715,3554,3555],{"class":1243},"hasAudio",[715,3557,3438],{"class":893},[715,3559,3560],{"class":721}," boolean",[715,3562,1425],{"class":893},[715,3564,3565],{"class":959},"                \u002F\u002F 元素是否包含音频\n",[715,3567,3568],{"class":717,"line":1339},[715,3569,1537],{"class":893},[731,3571,32],{"id":32},[826,3573,3575],{"id":3574},"beginframe-渲染","BeginFrame 渲染",[697,3577,3578,3579,3581],{},"传统屏幕录制以实际时间速度记录 — 如果你的系统负载较高，帧就会被丢弃。engine 使用 Chrome 的 ",[701,3580,703],{}," 来显式推进合成器，按需生成每一帧。这意味着：",[771,3583,3584,3590,3596],{},[774,3585,3586,3589],{},[741,3587,3588],{},"不丢帧"," — 每一帧都被捕获",[774,3591,3592,3595],{},[741,3593,3594],{},"无时间依赖"," — 60 秒的视频不需要 60 秒来捕获",[774,3597,3598,3601],{},[741,3599,3600],{},"像素完美输出"," — 合成器产生与其显示完全相同的像素",[697,3603,3604,3605,3607],{},"有关这如何实现确定性输出的更多信息，请参阅",[751,3606,54],{"href":55},"。",[826,3609,3610],{"id":3610},"跳转约定",[697,3612,3613,3614,3616,3617,769],{},"engine 依赖 Hyperframes 运行时的 ",[701,3615,851],{}," 函数。调用时，",[701,3618,3619],{},"renderSeek",[3621,3622,3623,3626,3629,3632],"ol",{},[774,3624,3625],{},"暂停所有 GSAP 时间轴",[774,3627,3628],{},"将每个时间轴跳转到精确的时间戳",[774,3630,3631],{},"更新所有媒体元素（视频、音频）以匹配",[774,3633,3634,3635,2061,3638,3641],{},"根据 ",[701,3636,3637],{},"data-start",[701,3639,3640],{},"data-duration"," 挂载\u002F卸载 clip",[697,3643,3644],{},"这个约定使得逐帧捕获成为可能 — 每一帧都是合成在该时间点的完整、独立的快照。",[826,3646,3648],{"id":3647},"chrome-要求","Chrome 要求",[697,3650,3651,3652,3654,3655,3657],{},"engine 需要 ",[701,3653,835],{},"，安装包时已包含。它使用固定的 Chrome 版本以确保跨环境一致的渲染。要获得完全确定性的输出（包括字体），请通过 ",[751,3656,760],{"href":188}," 使用 Docker 模式。",[731,3659,3660],{"id":3660},"相关包",[771,3662,3663,3671,3679,3686],{},[774,3664,3665,3670],{},[741,3666,3667],{},[751,3668,3669],{"href":188},"Producer","\n封装了 engine，提供运行时注入、FFmpeg 编码和音频混音，实现完整的 MP4 输出。",[774,3672,3673,3678],{},[741,3674,3675],{},[751,3676,3677],{"href":176},"Core","\n提供 engine 所依赖的类型、运行时和 Linter。",[774,3680,3681,3685],{},[741,3682,3683],{},[751,3684,195],{"href":196},"\n最简单的渲染方式 — 底层调用 producer（和 engine）。",[774,3687,3688,3693],{},[741,3689,3690],{},[751,3691,3692],{"href":192},"Studio","\n在使用 engine 渲染之前构建合成的可视化编辑器。",[3695,3696,3697],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":711,"searchDepth":718,"depth":924,"links":3699},[3700,3701,3708,3712,3721,3725,3727,3732],{"id":733,"depth":924,"text":733},{"id":817,"depth":924,"text":817,"children":3702},[3703,3704,3705,3706,3707],{"id":828,"depth":949,"text":829},{"id":839,"depth":949,"text":839},{"id":845,"depth":949,"text":845},{"id":855,"depth":949,"text":856},{"id":865,"depth":949,"text":865},{"id":877,"depth":924,"text":877,"children":3709},[3710,3711],{"id":1026,"depth":949,"text":1026},{"id":1091,"depth":949,"text":1092},{"id":1138,"depth":924,"text":1138,"children":3713},[3714,3715,3716,3717,3718,3719,3720],{"id":1563,"depth":949,"text":1563},{"id":1695,"depth":949,"text":1695},{"id":2084,"depth":949,"text":2084},{"id":2259,"depth":949,"text":2259},{"id":2443,"depth":949,"text":2443},{"id":2546,"depth":949,"text":2546},{"id":2712,"depth":949,"text":2712},{"id":2818,"depth":924,"text":2819,"children":3722},[3723,3724],{"id":2825,"depth":949,"text":2825},{"id":3094,"depth":949,"text":3095},{"id":3359,"depth":924,"text":3726},"window.__hf 协议",{"id":32,"depth":924,"text":32,"children":3728},[3729,3730,3731],{"id":3574,"depth":949,"text":3575},{"id":3610,"depth":949,"text":3610},{"id":3647,"depth":949,"text":3648},{"id":3660,"depth":924,"text":3660},"基于 Chrome BeginFrame API 的可寻址页面到视频捕获引擎。","md",null,{},{"title":179,"description":3733},"LxAe-ggxK033GbAFV_mZoDZb4rToKOlp6BA6Vv00uTY",[3740,3742],{"title":175,"path":176,"stem":177,"description":3741,"children":-1},"类型定义、HTML 生成、运行时与 Linter — 所有其他包的基础依赖。",{"title":183,"path":184,"stem":185,"description":3743,"children":-1},"可嵌入的 Web 组件，用于在任何网页中播放 HyperFrames 合成。",1780322244404]