@hyperframes/player

中文文档
0.8.226发布于 2026/11/01TypeScriptESM + CJS构建来源已验证

用于超框架组合的可嵌入web组件

中文使用文档
文档目录19 节
  1. 安装
  2. 使用
  3. 有一个框架
  4. 视频文件
  5. 海报图片
  6. 属性
  7. 着色过渡预览
  8. Loading-assets卡
  9. 音频锁定(主机强制静音播放)
  10. 移动音频
  11. JavaScript API
  12. 运行时数据传递
  13. Advanced: iframe访问
  14. React:声明式引用模式
  15. 事件
  16. 分级
  17. 它是如何工作的
  18. 分布
  19. 许可证

@hyperframes /播放器

用于播放超帧组合的可嵌入web组件。零依赖,适用于任何框架。

安装

npm install @hyperframes/player

或者直接通过CDN加载:

<script type="module" src="https://cdn.jsdelivr.net/npm/@hyperframes/player"></script>

如果你需要经典的 <script> 标记代替ESM,使用显式全局构建:

<script src="https://cdn.jsdelivr.net/npm/@hyperframes/player/dist/hyperframes-player.global.js"></script>

使用

<hyperframes-player src="./my-composition/index.html" controls></hyperframes-player>

玩家在沙盒iframe中加载组件,自动检测其尺寸和持续时间,并根据容器进行相应缩放。

添加或删除 controls 随时都可以。当显示时,控件反映当前播放状态、位置和速度。

有一个框架

import "@hyperframes/player";

// The custom element is now registered — use it in your markup
// React: <hyperframes-player src="..." controls />
// Vue:   <hyperframes-player :src="url" controls />

视频文件

集 type 到一个视频类型,播放器播放 src 在一个 <video playsinline> 而不是加载它作为一个组合。相同的API和事件适用: play(), pause(), seek(), currentTime, duration, ready, timeupdate, play, pause, ended, durationchange 和 resize,视频本身的大小为 compositionWidth/compositionHeight。一个无法加载的视频 error 立刻与 { message, code },在那里 code 是 MediaError 代码。一个 play() 浏览器会阻止(例如,未静音的自动播放)触发 playbackerror 与 { source: "video" } 让玩家暂停。 poster, controls, loop, muted, volume, playback-rate 和 autoplay 就像他们写作文一样。 scenes, setRuntimeData(), setColorGrading(), iframeElement 和 stopMedia() 是否仅限合成:视频没有场景或运行时,其iframe保持空白,以及 stopMedia() 不能停止视频。 srcdoc 赢得视频 src,就像在iframe中一样。

<hyperframes-player
  type="video/mp4"
  src="./render.mp4"
  poster="./poster.jpg"
  controls
></hyperframes-player>

海报图片

在播放开始前显示静态图像:

<hyperframes-player
  src="./composition/index.html"
  poster="./thumbnail.jpg"
  controls
></hyperframes-player>

属性

属性类型默认的描述
src字符串- - - - - -URL指向合成HTML文件,或指向视频文件 type
type字符串- - - - - -一、 video/... 类型(如。 video/mp4)玩 src 作为视频文件
audio-src字符串- - - - - -用于父框架播放的音频URL(移动)
width数量1920合成宽度(以像素为单位)
height数量1080合成高度(以像素为单位)
controls布尔假显示播放/暂停,洗涤器和时间显示
muted布尔假静音音频回放
audio-locked布尔假强制静音和隐藏音量控制,使观众无法打开声音
poster字符串- - - - - -播放开始前显示的图像URL
playback-rate数量1速度倍增器(0.5 =一半,2 =两倍)
autoplay布尔假准备好了就开始玩
loop布尔假当合成结束时重新开始
shader-capture-scale数量- - - - - -着色器过渡快照比例转发到浏览器预览(0.25-1)
shader-loadingcomposition | player | nonecomposition控制着色过渡准备加载UI所有权
assets-loading-uiplayer | noneplayernone 从不显示载入资产卡;资产事件仍在触发
low-power-idle布尔假暂停时,每秒检查一次,而不是每80毫秒检查一次(多玩家页面)
disable-click-to-play布尔假点击播放器不再播放或暂停(主机覆盖自己的点击)
no-load-timeout布尔假慢速负载在8秒时从不失败;页面拥有截止日期。错误仍然失败
range-start数量- - - - - -电影秒播放开始,循环回和公园时暂停
range-end数量- - - - - -胶片第二帧范围结束之前:它停止或循环在它之前的帧

range-start 和 range-end 播放电影的片段[开始,结束]。玩家停在 range-start 在 ready当一个暂停的弹头落在新的范围之外时; play() 从外面的范围开始。最后保存之前的最后一帧 range-end 和火灾 ended,或包裹到 range-start 与 loop。当前运行时停止于该帧本身;视频和 __timelines 玩家会在下一个时钟滴答声中停下来,然后返回;当玩家看到时间经过终点时,旧的运行时就会停止。 currentTime 和 duration 保持电影时间。超过胶片的范围被剪到尽头,空的或负的范围被忽略;两个火 rangeclamped.

着色过渡预览

当一个合成使用 @hyperframes/shader-transitions,玩家可以拥有仅预览的着色器捕获设置:

<hyperframes-player
  src="./composition/index.html"
  shader-capture-scale="1"
  shader-loading="player"
  controls
></hyperframes-player>

shader-loading="player" 显示来自着色器进度信息的玩家拥有的过渡准备叠加。 composition 只留下直接组合回退行为,和 none 抑制加载器。

Loading-assets卡

而图像、视频或字体仍在加载 ready,玩家在帧上显示一张加载卡片,并设置 assets-loading 属性。绘制自己的加载状态的主机可以使用 assets-loading-ui="none" (或 player.assetsLoadingUi = "none"). 这个 assets-loading 属性和 assetsready 和 painted 无论哪种方式,事件的行为都是相同的,因此主机仍然知道帧何时准备好。

音频锁定(主机强制静音播放)

audio-locked 部队 muted 打开和隐藏音量控制,没有UI路径为观众打开声音。使用它时,嵌入在聊天主机(克劳德。ai, ChatGPT等),无论观众的意图如何,音频都必须关闭。设置 muted 直接是 不 足够了——观看者可以通过控制条将其翻转回来。

删除 audio-locked 只隐藏控件;它 不 auto-unmute。电话管理 muted 在解锁后显式地。

宿主环境回退。 一些主机渲染器——尤其是Claude桌面电子客户端——在到达DOM之前剥离未知的自定义元素属性,从而破坏了属性。作为安全网,当玩家检测到这样的环境时,他们也会自己施加锁 navigator.userAgent,因此即使该属性从未到达,音频也保持静音。公众 audioLocked 属性仍然只反映属性,因此外部消费者(例如镜像状态的宿主小部件)不受回退的影响。

移动音频

移动浏览器阻塞 audio.play() 当用户手势发生在父框架中时,在iframes内部 用户激活规范 不传播激活跨帧边界通过 postMessage)。

播放器自动处理同源iframe(默认- sandbox 包括 allow-same-origin):

  1. 当合成准备好时,玩家提取所有定时媒体(audio[data-start], video[data-start]),并创建父框架副本。
  2. iframe原件被禁用(src 和 data-start 删除),所以运行时不会尝试播放它们。
  3. 当 play() 调用(从用户手势),父媒体 .play() 在手势调用栈中同步运行,满足移动自动播放策略。
  4. 母媒体和GSAP时间轴同时启动并且自由运行——不需要主动同步,因为它们都是实时系统。

消费者不需要进行任何更改——这是开箱即用的。

可选 audio-src 属性可用于在iframe加载之前开始预加载主音轨(在慢速连接上很有用),但不需要用于移动播放。

JavaScript API

const player = document.querySelector("hyperframes-player");

// Playback
player.play();
player.pause();
player.seek(2.5); // jump to 2.5 seconds

// Properties
player.currentTime; // number (read/write)
player.duration; // number (read-only)
player.paused; // boolean (read-only)
player.ready; // boolean (read-only)
player.compositionWidth; // number (read-only), the composition's width
player.compositionHeight; // number (read-only), the composition's height
player.disableClickToPlay; // boolean (read/write)
player.playbackRate; // number (read/write)
player.muted; // boolean (read/write)
player.audioLocked; // boolean (read/write) — force-mute + hide volume controls
player.loop; // boolean (read/write)
player.rangeStart; // number | null (read/write, mirrors range-start)
player.rangeEnd; // number | null (read/write, mirrors range-end)
player.shaderCaptureScale; // number (read/write)
player.shaderLoading; // "composition" | "player" | "none" (read/write)

// Inner iframe access (for advanced consumers — see "Advanced: iframe access" below)
player.iframeElement; // HTMLIFrameElement (read-only)

运行时数据传递

setRuntimeData(channel, payload) 克隆并保留有效负载,然后在 组合运行时已经准备好了。无效通道和不可克隆的有效载荷同步抛出。 报告调用返回后的失败 runtimedataerror;成功申请 报告 runtimedataapplied。这两个事件包括 { channel, requestId },还有错误 包括 message。当交付很重要时,倾听这两种结果:

player.addEventListener("runtimedataapplied", ({ detail }) => {
  console.log("applied", detail.channel, detail.requestId);
});
player.addEventListener("runtimedataerror", ({ detail }) => {
  console.error("not applied", detail.channel, detail.requestId, detail.message);
});
player.setRuntimeData("captions", captionData);

只有通道的最新动态更新才能触发完成。缺少运行时响应; 如果框架拆除,或发出桥交付失败 runtimedataerror 而不是等待 下去。

Advanced: iframe访问

合成在沙盒中运行 <iframe> 在玩家的Shadow DOM中。默认的沙箱包括 allow-same-origin 用于检查组合DOM的编辑器、记录器和自定义时间轴集成。这是一种可信内容模式,而不是隔离边界:同源组合代码可以到达嵌入页面。

对于只读或消息桥接集成,请设置 sandbox-origin="opaque"。任何非空值都是 被视为不透明的,因此错别字不会削弱隔离性。更改属性会重新加载活动 因为浏览器沙盒更改只对导航生效。不透明模式 allow-same-origin 同时保留脚本,并防止与阅读无关的作文 父DOM。直接 contentDocument, __player, __timelines 访问是有意的 该模式不可用。

如果您正在构建需要直接访问的可信编辑器集成,请使用 iframeElement 吸气剂:

const player = document.querySelector("hyperframes-player");
const iframe = player.iframeElement;

// Now you can reach into the composition's DOM and runtime
iframe.contentDocument.querySelectorAll("[data-composition-id]");
iframe.contentWindow.__timelines;

这是将玩家与工具连接起来的典型方法 @hyperframes/studio。该工作室出口了 resolveIframe 与iframe refs和web组件refs一起工作的助手:

import { useTimelinePlayer, resolveIframe } from "@hyperframes/studio";

const { iframeRef } = useTimelinePlayer();
const player = document.createElement("hyperframes-player");
player.setAttribute("src", src);
container.appendChild(player);

// Forward the inner iframe so useTimelinePlayer can drive play/pause/seek.
iframeRef.current = resolveIframe(player);

React:声明式引用模式

如果你更喜欢JSX而不是命令式元素创建,直接在web组件上附加一个ref,并在效果中解析iframe:

import "@hyperframes/player";
import type { HyperframesPlayer } from "@hyperframes/player";
import { useTimelinePlayer, resolveIframe } from "@hyperframes/studio";

function StudioPreview({ src }: { src: string }) {
  const { iframeRef, onIframeLoad } = useTimelinePlayer();
  const playerRef = useRef<HyperframesPlayer>(null);

  useEffect(() => {
    iframeRef.current = resolveIframe(playerRef.current);
  });

  return <hyperframes-player ref={playerRef} src={src} onLoad={onIframeLoad} />;
}

注意——常见的陷阱

如果你通过了 <hyperframes-player> 元素本身(不是) iframeElement)放入一个钩子中,该钩子需要一个 <iframe>,每一个 .contentWindow / .contentDocument 访问的回报 null 因为iframe存在于玩家的Shadow DOM中。总是提取 iframeElement 首先,还是使用 resolveIframe 从 @hyperframes/studio 它透明地处理iframe和web组件主机。

事件

事件细节时触发
ready{ duration, compositionWidth, compositionHeight }加载成分并确定持续时间
durationchange{ duration }持续时间在 ready
resize{ compositionWidth, compositionHeight }构图的大小改变了
play- - - - - -开始播放
pause- - - - - -播放暂停
timeupdate{ currentTime }播放位置改变(~10 fps)
ended- - - - - -到达终点(没有循环时)
rangeclamped{ rangeStart, rangeEnd, duration }这个范围被剪掉了,或者被忽略了
error{ message } (视频模式: { message, code })未能加载合成或视频
playbackerror{ source, error }浏览器阻止播放
shadertransitionstate{ compositionId, state }着色器过渡缓存/捕获进度
player.addEventListener("ready", (e) => {
  console.log(`Duration: ${e.detail.duration}s`);
});

player.addEventListener("ended", () => {
  console.log("Done!");
});

分级

玩家填充它的容器并在保持长宽比的同时缩放构图。设置元素或其父元素的大小:

hyperframes-player {
  width: 100%;
  max-width: 800px;
  aspect-ratio: 16 / 9;
}

这个 width 和 height 属性定义了用于宽高比计算的合成的原生分辨率——它们不设置播放器的显示尺寸。

它是如何工作的

玩家在沙盒中渲染构图 <iframe> 在一个Shadow DOM里面。与HyperFrames运行时通信 postMessage。如果作文有GSAP时间表(window.__timelines),但没有运行时,播放器自动注入它从CDN。

分布

格式文件用例
ESMhyperframes-player.js捆绑器(Vite, webpack等)
cjhyperframes-player.cjsNode.js / require()
IIFEhyperframes-player.global.js<script> 标签,CDN

所有格式都使用源映射进行缩小。包括TypeScript定义。

许可证

麻省理工学院

版本与发布记录

@hyperframes/player 共发布 556 个版本,首次发布于 2026/04/10;过去 12 个月发布了 556 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.8.226latest2026/11/012 天前
0.8.2252026/11/012 天前
0.8.2242026/11/012 天前
0.8.2232026/10/313 天前
0.8.2222026/10/313 天前
0.8.2212026/10/304 天前

其他发布通道:alpha → 0.7.67-alpha.0,desktop → 0.8.53-desktop.0,hdr → 0.8.190-hdr.1。

关于 @hyperframes/player 的常见问题

@hyperframes/player 是什么?

用于超框架组合的可嵌入web组件

如何安装 @hyperframes/player?

在项目目录运行 npm install @hyperframes/player,或使用 pnpm add / yarn add / bun add。

@hyperframes/player 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@hyperframes/player 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@hyperframes/player 可以商用吗?

@hyperframes/player 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@hyperframes/player 还在维护吗?

最新版本 0.8.226 发布于 2026/11/01(2 天前);至今共发布 556 个版本,其中过去 12 个月发布了 556 个;首次发布于 2026/04/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。