关于 paper2reel
paper2reel 是用于构建自包含浏览器的技能,可按章节关联论文海报、幻灯片、博客和视频。它面向使用 paper2assets、paper2blog 与 paper2video 输出的工作流,并采用固定交互模板和包检查器。
主要功能
- 01按章节对齐多种媒体
- 02海报优先的视图与快捷键
- 03基于时间线的视频和幻灯片片段
- 04双语博客面板与幻灯片缩略图
- 05下载包生成与成品校验
适用场景
- 01跨海报、幻灯片、博客和视频浏览论文
- 02从海报章节跳转到对应媒体
- 03打包最终成果供本地查看
- 04交付前检查播放定位与视图行为
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ researchstudio --skill paper2reel安装后在 Claude Code 中输入/paper2reel确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdassets/section_modal_contract.jsonscripts/build_poster_slides_view.pybuild_reel_from_paper.pybuild_section_media_from_timeline.pycheck_reel_package.pyreel_downloads.pyserve_reel.py详细介绍
paper2reel - 对齐素材查看器
paper2reel 在现有素材之上构建浏览层。它不会替换或修改 paper2poster、ppt-master、paper2blog 或 paper2video 的输出。
核心素材是:
content_alignment.json
它将 paper2assets 的 assets/meta/sections.json 中的规范章节 ID 映射到:
- 海报 DOM 目标,通常为
[data-section="<id>"]; - 幻灯片帧目标,通常为一个或多个幻灯片索引;
- 由与最终 DOCX 相同的 paper2blog 内容渲染的博客区块;
- 从与 paper2video 交付内容相同的最终版、带 Bottom Bar 字幕的 MP4 和时间线中剪出的片段。
这个 sidecar 可让外层 UI 在海报 / 幻灯片 / 博客之间切换,并跳转到相应位置,而无需在交付物中添加可见的工程标签。
查看器 UX 契约
面向用户的查看器必须保留原始海报作为默认屏幕。首次打开 reel.html 时,只应显示海报本身:没有常驻的外层工具栏、标签栏,也没有海报之外可见的说明。可通过键盘快捷键和章节交互发现外层控件:
- 按
v可切换顶部章节菜单。 - 按
h可切换键盘快捷键帮助。 - 按
a可切换海报现有的音频控件。 - 按
s可切换全屏。 - 按
d可切换海报调试/悬停控件。 - 双击海报章节可打开大型模态窗口。
- 点击或双击海报标题可打开全文模态窗口。
方法焦点卡片保留各自的 data-section="method-1"…"method-N" 标识。有卡片专属对齐条目时使用该条目;否则,其悬停/双击交互应打开规范的 method 视频、博客和幻灯片。无论海报如何缩放或叠加了历史栅格图,都要高亮实际点击的卡片。不要重命名卡片,也不要为了让卡片可点击而虚构子章节片段。
模态窗口必须采用章节媒体布局:左侧是带有内嵌 Bottom Bar 字幕的视频,右侧是博客,支持 EN/中文切换,视频下方显示幻灯片缩略图,并提供可拖动的分隔条。不要将其替换为带有海报/幻灯片/视频/博客标签的查看器。标签式查看器会丢失章节级交互契约,属于回退。
视频可定位播放是契约的一部分,而非托管细节。模态窗口的视频进度条和幻灯片缩略图必须能够实际定位播放。请使用下方支持 Range 的 paper2reel 服务来提供和测试 reel;不要将 python -m http.server 用作合格的预览或 QA 环境,因为它可能会以 200 OK 而不是 206 Partial Content 响应 MP4 Range 请求。
查看器有意采用固定模板。将 assets/section_modal_contract.json 视为从经过手动调整的 Attention reel 提炼出的黄金 UI 契约:固定的章节模态窗口模板、默认隐藏顶部栏、v/h/a/s/d 快捷键、调试不透明度滑块、内嵌字幕播放、下载菜单、可拖动分隔条、幻灯片缩略图、中英文博客面板,以及由时间线驱动的章节片段。不要让 Agent 重新设计此 HTML。构建器只能向固定模板填充数据并复制自包含素材。
输入和输出
对于完整素材包,paper2reel 必须读取与交付给用户相同的 v2 输出:
<poster_outdir>/ # poster.html, poster.pdf/png/pptx, manifest.json, assets/
<blog_outdir>/ # blog_zh.docx, blog_en.docx, manifest.json, assets/
<video_outdir>/ # video*.mp4, manifest.json, assets/
不要使用过时的示例文件或旧的 exports/ 文件夹来构建 reel。查看器和所有由时间线驱动的片段都必须使用最终的 <video_outdir>/video.mp4,其中字幕已内嵌到附加的黑色 Bottom Bar 中。不要在 Reel 查看器中附加 VTT sidecar,否则每个视频帧中已有的文字会被重复显示。
直接在 v2 reel 素材包中构建面向用户的查看器:
<reel_outdir>/
reel.html
content_alignment.json
manifest.json
assets/
poster/
media/
slides/
blog/
meta/
reel_downloads.json
downloads/ # materialized mode only
此目录必须包含足够的自包含内容,以便在本地提供服务:reel.html 和 content_alignment.json 位于素材包根目录;海报/视频/幻灯片/博客素材位于 assets/ 下。不要只复制 reel.html。
海报 + 幻灯片基础查看器
在仓库根目录运行:
python skills/paper2reel/scripts/build_poster_slides_view.py \
--poster-dir <poster_outdir> \
--slides-dir <slide_png_or_svg_dir> \
--script-json <optional_audio_script_json> \
--section-slide-map <optional_section_slide_map.json> \
--blog-outline-en <blog_outdir>/assets/meta/outline_en.json \
--blog-outline-zh <blog_outdir>/assets/meta/outline_zh.json \
--blog-figures-dir <blog_outdir>/assets/figures \
--download-poster-dir <poster_outdir> \
--download-blog-dir <blog_outdir> \
--download-video-dir <video_outdir> \
--download-mode materialized \
--outdir <reel_outdir>
脚本会写入:
<viewer_outdir>/
reel.html
content_alignment.json
manifest.json
assets/
poster/
poster.html
assets/
figures/
fonts/
logos/
qr/
audio/
slides/
slide_01.png
...
blog/
figures/
...
meta/
reel_downloads.json
downloads/ # materialized mode only
all_final.zip
poster_final.zip
blog_final.zip
video_final.zip
reel.html 会将海报保留在 iframe 中,使其自身的交互保持不变。包装页面只会监听章节点击并应用临时高亮。幻灯片会被复制为图像帧,以实现稳定的滚动和高亮效果。
如果有 paper2blog 大纲,请同时传入两种语言的大纲和图片目录。构建器会将博客图片复制到 blog/figures/,并在 content_alignment.json 中存储章节级的 EN/CN 区块;浏览器检查要求提供这些区块。
提供下载目录时,构建器始终会写入 assets/meta/reel_downloads.json,其 schema 为 paper2reel.downloads.v1。其 archives 对象恰好包含 all、poster、video 和 blog;每个归档都声明 label、filename,以及去重后的 files 条目,其中包含相对于 bundle 的 POSIX path、ZIP arcname 和精确字节数 size。
下载分发有两种明确模式:
materialized是独立运行时的默认模式。它会保留assets/downloads/{all,poster,video,blog}_final.zip,并支持完整的file://下载功能。on_demand不会写入持久 ZIP 文件。它使用相对路径__download__/{all,poster,video,blog}链接,由serve_reel.py根据清单解析并以临时 ZIP 响应流式传输。直接通过file://打开时,这些仅限在线使用的链接会被隐藏。
两种模式都会排除 .claude/、嵌套下载目录、备份和内部文件。Video 归档包含 video.pptx、video.mp4、可选的字幕 sidecar 文件,以及一份根目录下的 README.txt,引导编辑者使用 PPTX2Video。没有此 README 的历史清单仍然有效;下载服务会在 video_final.zip 中注入规范说明,而不会重写旧 bundle。
新清单会标记 all_package_version: paper2reel.all.v2;其 All 归档则是一个可独立离线使用的 Reel,包含 reel.html、content_alignment.json、assets/poster、assets/media、assets/slides、assets/blog、assets/ui 和 assets/fonts 下的 Reel 运行时文件,以及最终版 Poster PDF/PPTX、Video MP4/PPTX 和 EN/CN Blog DOCX 文件。它不会重复包含根目录下的 poster.html 或 poster.png,并会排除构建/缓存目录和嵌套 ZIP 文件。没有 all_package_version 的历史清单会保留原有的去重并集行为,仍可下载。Portal 作业使用 on_demand,独立离线 bundle 使用 materialized,除非调用方明确选择其他模式。
基于时间线的章节媒体
paper2video 生成 timeline.json 后,应将其作为模态视频片段、幻灯片片段和章节时间的事实来源。不要根据猜测的 MP4 时间戳剪辑章节视频。章节片段应由完整的时间线幻灯片片段组成,并以一段短暂的静音定格尾帧结束,以免模态窗口在动作或表达中途停止。
python skills/paper2reel/scripts/build_section_media_from_timeline.py \
--viewer-dir <reel_outdir> \
--timeline <video_outdir>/assets/meta/timeline.json \
--video <video_outdir>/video.mp4 \
--allow-burned-subtitle-video \
--section-tail-seconds 0.9
这会更新:
<viewer_outdir>/content_alignment.json
<viewer_outdir>/reel.html # inline ALIGNMENT refreshed when present
<viewer_outdir>/assets/media/video.mp4 # final playback copy with baked Bottom Bar
<viewer_outdir>/assets/media/clips/<section>.mp4
<viewer_outdir>/assets/media/slide_clips/slide-XX.mp4
确定性的 Reel 引导程序会传入 --allow-burned-subtitle-video,声明所选来源是最终的 Bottom Bar 渲染版本。在此模式下,构建器会将视频来源和字幕分发都记录为 burned_bottom_bar,且不会提供 sidecar CC 轨道。
timeline.json 必须已经包含显式的章节映射。如果幻灯片使用的是幻灯片 ID,而不是规范海报 ID,请先使用 python -m pptx2video.build_timeline --section-map ... 构建时间线。
必须通过的硬性门槛
构建基础查看器和基于时间线的媒体后,运行 reel 包检查器。这是必须通过的门槛,不是可选的冒烟测试:
python skills/paper2reel/scripts/check_reel_package.py \
<reel_outdir> \
--browser \
--file-browser \
--screenshot <reel_outdir>/assets/meta/previews/reel_browser_gate.png \
--report <reel_outdir>/assets/meta/reports/reel_qa_report.json
必须通过检查器,才能将 paper2reel 标记为完成。它会验证交付的查看器是分节模态框 UI,而不是过时的标签页查看器;并在真实浏览器中确认默认的仅海报视图、快捷键、双击打开分节模态框、内嵌字幕的视频片段、幻灯片缩略图和博客文本均正常工作。它还会验证 MP4 字节范围支持并测试真实的视频跳转:点击后续幻灯片缩略图时,必须将 sectionVideo 跳转到缩略图对应的时间戳;直接通过进度条样式的方式跳转,也必须在完整视频和分节片段播放时都成功。
同一个最终版 reel.html 还必须支持通过 file:// 直接打开或双击打开。在直接打开模式下,查看器会通过 iframe.srcdoc 嵌入复制的海报 HTML,将海报基础 URL 设为 assets/poster/,将 MathJax 等海报渲染资源本地化到 assets/poster/,并保留内嵌的 Bottom Bar,同时确保分节模态框、海报悬停、快捷键、博客窗格、幻灯片缩略图跳转和直接视频跳转都能在不启动服务器的情况下使用。这是面向用户的功能对等路径,不是 HTTP 协议替代方案:file:// 没有 HTTP 206 Range 标头,因此 Range/跳转验证仍需使用 --browser,而 --file-browser 则单独验证直接打开时的运行状况。
检查器会读取 assets/section_modal_contract.json。缺少任何必需的黄金契约功能都属于阻断性 ERROR:快捷键处理程序、调试滑块、paper2poster 原生调试 bbox/尺寸叠加层、带图标且包含 All | Poster | Video | Blog 链接的黄金下载胶囊、分节轨道悬停样式、带内嵌 Bottom Bar 字幕的分节片段、无重复的旁路字幕轨道、博客图片,或固定的模板/版本标记。
下载 QA 按照清单中明确指定的 delivery 字段执行。在 materialized 模式下,它会使用现有的归档边界验证四个 ZIP 文件。在 on_demand 模式下,它会拒绝已持久化的 ZIP 文件,验证清单中的每个路径、分类、源文件和字节大小,检查去重后的 All 并集,并通过 HTTP HEAD 探测每个动态端点。
如果检查器失败,应首先将其视为 Agent 修复任务:修复查看器并重新运行门槛检查。不要将阶段标记为 PASS,也不要让用户通过目视检查页面来发现问题。
如需人工预览,请启动浏览器门槛检查所用的同一个支持 Range 的服务器:
python skills/paper2reel/scripts/serve_reel.py <reel_outdir> --port 8900
打开 http://127.0.0.1:8900/reel.html。只有视频请求针对 Range 请求返回 206 Partial Content,预览才算忠实还原。
对于 on_demand 包,该服务器还会提供
/__download__/{all,poster,video,blog},并仅在收到请求时创建相应的 ZIP 文件;它不会将归档写入包中。
如需快速本地分享,用户也可以双击 <reel_outdir>/reel.html。
不要移除 assets/ 文件夹,也不要只复制 HTML 文件;直接打开模式仍依赖 v2 包文件夹结构。
输出清单
<reel_outdir>/manifest.json 必须包含 "layout": "v2-assets",并包含 reel.html、content_alignment.json、assets/poster/、assets/media/、assets/slides/、assets/blog/ 和 assets/meta/reel_downloads.json 的相对根目录路径。Materialized 包还必须索引 assets/downloads/。将 QA 截图和报告放在 assets/meta/previews/ 和 assets/meta/reports/ 下。
如果缺少必需输入,或查看器无法加载所需文件,请在 QA 报告/清单中记录 ERROR 并停止。不要静默构建隐藏缺失海报、视频、幻灯片或博客内容的部分查看器。
从 PDF 或不完整的包开始
当用户使用 PDF、arXiv/链接输入或不完整的 v2 包调用 paper2reel 时,先检查共享包,并判断哪些上游阶段已经完成。必须通过对应的完整技能补齐缺失阶段,然后才能组装 Reel:
paper2assets -> paper2poster -> paper2blog -> paper2video -> paper2reel
使用引导辅助工具进行检查和确定性的最终组装:
python skills/paper2reel/scripts/build_reel_from_paper.py <paper.pdf-or-bundle> --dry-run
然后按照阶段报告操作:
-
如果
paper2assets缺少paper_spec.md,运行完整的paper2assets技能。不要仅凭extract_pdf.py的输出就将其视为 paper2assets 包,因为第 4 步由模型驱动。 -
如果仅缺少
manifest.json、assets/meta/sections.json或assets/meta/narration.json,而paper_spec.md、text.txt、figures.json和metadata.json已存在,辅助工具可以使用--run-missing刷新这些确定性的包文件。 -
如果缺少
paper2poster,运行完整的paper2poster技能,包括测量填充 循环、渲染/导出、html2pptx 交接,以及交付物门禁。 -
如果缺少
paper2blog,运行完整的双语paper2blog技能,包括真实的 EN/CN 大纲、DOCX 生成、嵌入图表,以及博客 QA 门禁。 -
如果缺少
paper2video,运行完整的paper2video技能,包括 ppt-master、音频、时间线、字幕、视觉重点、video.mp4、video_no_subtitles.mp4、video.pptx,以及视频 QA 门禁。 -
当所有上游阶段都通过后,让辅助工具组装 Reel:
python skills/paper2reel/scripts/build_reel_from_paper.py \ <paper.pdf-or-bundle> \ --run-missing \ --download-mode materialized门户调用方必须传入
--download-mode on_demand。将暂存的 Reel 同步到最终共享包后,辅助工具会针对该最终包重建清单,并删除任何历史遗留的assets/downloads/目录。
辅助工具会在临时暂存目录中构建查看器,然后仅将 Reel 交付物复制回 v2 包。
这样可以避免 build_poster_slides_view.py --outdir 的清理步骤删除现有的
海报、博客、视频或 paper2assets 输出。它会保留 v2 约定:
包根目录下的 reel.html 和 content_alignment.json,以及位于
assets/poster/、assets/media/、assets/slides/、assets/blog/
下的 Reel 支持资源,此外还有 assets/meta/reel_downloads.json;只有物化模式
才会添加 assets/downloads/。
如果辅助工具报告某个阶段受阻,请停止并完成报告中指定的完整技能阶段。不要编写简化版海报、视频、博客大纲、幻灯片图像或 HTML 页面来让 Reel 检查器通过。
对齐规则
优先使用 paper2assets 中明确指定的章节 id:
titleproblemmotivationcontributionmethoddataset-benchmarkkey-resultablation-studyheadline-numberstakeaway- 论文专属自定义 id,例如
failure-modes-limitations
对于幻灯片,如有 script.json,请传入该文件。脚本中的 sections[*].id
及其顺序可在不向 PPTX 中嵌入元数据的情况下标识幻灯片。
如果自动匹配幻灯片的效果不佳,请传入覆盖 JSON:
{
"method": [4, 5],
"key-result": [7, 9],
"takeaway": [10]
}
使用以下命令应用覆盖:
python skills/paper2reel/scripts/build_poster_slides_view.py \
--poster-dir <paper2poster_outdir> \
--slides-dir <slide_png_or_svg_dir> \
--script-json <script.json> \
--section-slide-map <map.json> \
--outdir <viewer_outdir>