Rerun Notebook Viewer 实战:在 Jupyter 中嵌入 3D 回放 Widget 加载预录制 RRD
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
本文介绍 Rerun 官方notebook_viewer示例的核心用法:不向 Viewer 实时记录新数据,而是直接在一个 Jupyter Notebook 单元格中嵌入 Rerun Viewer Widget,加载一份预录制的.rrd数据文件并就地渲染交互式 3D 场景。读完本文,你将掌握pip install "rerun-sdk[notebook]"的安装链路、rerun.notebook.Viewer的完整初始化参数、面板状态控制方法,以及底层rerun-notebook支持包的资产加载机制与常见网络环境的适配方案,可直接用于演示、文档编写与既有录制数据的快速检查。
示例背景:为什么在 Notebook 里嵌入 Viewer
notebook_viewer示例(examples/notebook/notebook_viewer)展示的是在 Jupyter 中嵌入 Rerun Viewer Widget 的最简方式。与rr.log逐条写入数据的常规流程不同,本例加载一份预录制的.rrd文件,由 Viewer 流式读取该 capture 并在浏览器端直接渲染。
这意味着你可以在不启动任何独立桌面应用的前提下,在 Notebook 内部完成 3D 场景的旋转(orbit)、缩放(zoom)与检视(inspect),非常适合以下场景:
- 技术演示(demo)与文档编写:把可交互的 3D 回放直接内嵌到教程页面中;
- 快速检查既有录制:对一份已导出的
.rrd捕获文件做即开即看的检查,无需额外启动 Viewer 进程。
该示例的元数据(见 README.md 顶部 frontmatter)将其标记为Notebook、Widget、3D三类标签,正对应上述"Notebook 内嵌 Widget + 3D 场景"的定位。
环境准备:安装 notebook 支持包
要在 Notebook 中使用 Viewer Widget,除了 Rerun SDK 本体,还需要单独的支持包rerun-notebook。官方推荐通过 SDK 的notebookextra 一键安装:
pip install "rerun-sdk[notebook]"示例目录下的 requirements.txt 内容即为上面这一行依赖声明,因此可以直接安装:
pip install -r requirements.txt该命令同时包含 Jupyter、Rerun SDK 与 notebook 支持包,适合新建一个 Notebook 环境后执行。
为什么rerun-notebook要独立成包
从 rerun_notebook/README.md 可以了解独立打包的三点原因:
- 体积:
rerun-notebook内置 Rerun Viewer 的 JS + Wasm 发行版(约 31 MiB),若并入主rerun-sdk会使其体积翻倍; - 构建后端:
rerun-notebook使用 hatch 构建,并借助hatch-jupyter-builder插件打包前端资源,而rerun-sdk必须使用 Maturin 构建 Rust 扩展,两者工具链不同(见 rerun_notebook/pyproject.toml 中的[tool.hatch.build.hooks.jupyter-builder]配置); - 开发体验:构建
rerun-notebook意味着要构建前端rerun_js,把两者拆开可以避免在非 Notebook 场景下迭代 SDK 时被迫做无谓的前端构建。
快速开始:notebook_viewer 示例逐行拆解
示例的核心代码位于 notebook_viewer.ipynb,整个 Notebook 只有一个代码单元:
from __future__ import annotations from rerun.notebook import Viewer v = Viewer( width="auto", height="auto", url="https://app.rerun.io/version/nightly/examples/raw_mesh.rrd", ) v.update_panels( blueprint="hidden", selection="hidden", time="collapsed", )参数语义(对应 SDK 源码)
Viewer的初始化参数定义在 rerun_py/rerun_sdk/rerun/notebook.py:
| 参数 | 取值 | 说明 |
|---|---|---|
width | 像素数或"auto" | "auto"时按 Notebook 单元格宽度的 100% 缩放;不传则使用 SDK 默认值 640px(见set_default_size全局默认_default_width) |
height | 像素数或"auto" | "auto"时按 16:9 宽高比随width自适应;不传默认 480px |
url | 字符串 | 可选,传入 Viewer 用于展示内容的 URL。本例即指向一个托管在 Rerun 官方服务器的raw_mesh.rrd示例录制 |
blueprint | BlueprintLike | 可选的 Blueprint 对象,等价于在初始化前调用rr.send_blueprint |
recording | RecordingStream | 指定使用的 recording;未指定时默认取当前激活的数据 recording |
use_global_recording | bool | 是否使用rr.init创建的全局/线程本地 recording。默认值随url动态决定:提供了url则为False,否则为True,这正是本例"只播 URL、不接收本地数据"的依据 |
theme | "dark"/"light"/"system" | 颜色主题;不设置时沿用持久化的主题偏好或"system" |
创建Viewer之后,它可以在当前单元格末尾直接作为返回值显示,也可以显式调用v.display()立即渲染。示例选择让 Widget 成为单元格最后一个表达式,由 Jupyter 自动展示。
面板控制:update_panels
update_panels(notebook.py)用于部分更新Viewer 中四个面板的状态:
top:顶部面板;blueprint:左侧的蓝图面板;selection:右侧的选择面板;time:底部的时间轴面板。
每个面板可接受的状态值为expanded、collapsed、hidden、default与None:
| 状态 | 效果 |
|---|---|
None | 保持不变 |
expanded | 完全展开,占据最大空间 |
collapsed | 收起为更小更简单的形态(省略部分信息;不支持 collapsed 的面板等同 hidden) |
hidden | 完全隐藏,不占空间 |
default | 恢复默认状态 |
示例将blueprint与selection设为hidden、time设为collapsed,目的是让 3D 画面占满整个单元格、界面更干净,符合"内嵌回放"的展示诉求。需要注意的是,用该方法设置过的面板状态会被锁定,用户在 Viewer 中无法再手动修改。
启动 Notebook
环境就绪后启动 Notebook:
jupyter notebook notebook_viewer.ipynb启动并运行单元格后,嵌入的 Viewer 会流式加载远程 mesh capture,你可以在 Notebook 内直接旋转、缩放、检视 3D 场景。
深入底层:rerun-notebook的资产加载机制
rerun.notebook.Viewer是高层封装,其内核是 rerun_notebook/src/rerun_notebook/init.py 中基于anywidget实现的Viewer类。它需要两类前端资源:
re_viewer_bg.wasm:编译为 Wasm 的 Rerun Viewer 本体;widget.js:将 Wasm 绑定到 Jupyter Widget 的胶水代码。
两者可在当前仓库中用pixi run py-build-notebook构建。资源的分发方式由环境变量RERUN_NOTEBOOK_ASSET控制,且必须在import rerun_notebook之前设置——因为 anywidget 会在类实例化时一次性读取资源。
默认行为:从 app.rerun.io 远程加载
默认情况下(未设置环境变量),资源从https://app.rerun.io/version/{__version__}/notebook/widget.js加载。之所以默认远程加载而不是本地内嵌,是因为当前 anywidget 通过 Jupyter comms 传输大资源的方式存在每个 cell 执行即泄漏整个模块的已知问题(见 rerun_notebook/README.md 的说明)。若在仓库开发环境中(存在RERUN_DEV_ENVIRONMENT环境变量),默认值自动切换为serve-local,因为+dev版本不会上传远端 widget。
模式一:RERUN_NOTEBOOK_ASSET=inline
RERUN_NOTEBOOK_ASSET=inline将 Wasm 以gzip + base64形式内联进widget.js(对应_buffer_to_data_url与_inline_widget的实现,init.py),再通过 Jupyter comms 直接传给前端。这是可移植性最好的方式,但已知存在内存泄漏,且在 Google Colab 等环境中性能较差——浏览器无法缓存内联的 JS/Wasm,每个输出 cell 都要重新加载。
模式二:RERUN_NOTEBOOK_ASSET=serve-local
RERUN_NOTEBOOK_ASSET=serve-local在 kernel 存活期间于本机启动一个线程服务器(asset_server.py中的serve_assets),从http://localhost:<port>/widget.js提供资源。这是本地运行 Notebook 服务时的最佳选择:JS 与 Wasm 分别提供服务,Wasm 可流式编译,启动速度更快,且两者都能被浏览器缓存。
模式三:手动托管 URL
RERUN_NOTEBOOK_ASSET=https://your-hosted-asset-url.com/widget.js从指定 URL 加载资源,最灵活但需自行托管。实现上要求 URL 必须以http://或https://开头且指向widget.js文件,否则会在 import 时抛出ValueError(见init.py)。同时Wasm 文件必须与widget.js相邻可访问,服务器需同时提供:
https://your-hosted-asset-url.com/widget.jshttps://your-hosted-asset-url.com/re_viewer_bg.wasm
rerun_notebook自带一个最小服务器,可手动启动用于验证:
python -m rerun_notebook serve任何托管平台只要对 Notebook 可达并配置了正确的 CORS 头即可(可参考 asset_server.py 的简单实现)。
源码视角:Widget 与 SDK 的通信原理
就绪前的事件队列
在 Wasm Viewer 于浏览器端就绪前,SDK 侧发来的所有消息都会先进入_event_queue排队;收到前端"ready"信号(_on_ready)后一次性 flush 发送(init.py)。这一行为在 tests/test_viewer.py 中有完整的单元测试覆盖:test_send_queues_before_ready验证了未就绪时消息入队,test_on_ready_flushes_queue验证了就绪后队列按序发送。
消息通道:send_rrd与send_table
低层 Widget 通过两类带二进制缓冲区的消息与前端通信(init.py):
send_rrd(data):发送{"type": "rrd"}消息,携带整个 recording 的 RRD 字节流;send_table(data):发送{"type": "table"}消息,携带 Arrow IPC 序列化后的数据表字节。
测试test_send_rrd_shape与test_send_table_shape分别断言了这两种消息的 shape。高层rerun.notebook.Viewer中send_table还负责把 RecordBatch/DataFrame 通过 pyarrow IPC 流编码、以__table_id元数据标记后下发给 Widget(notebook.py)。
事件回调:从 Viewer 反向通知 Python
on_event(callback)允许注册回调接收ViewerEvent,其子类型包括PlayEvent、PauseEvent、TimeUpdateEvent、TimelineChangeEvent、SelectionChangeEvent、RecordingOpenEvent等,可用于把用户的交互(播放/暂停/切时间线/选中等)同步回 Python 端。
进阶用法:超越"只看不写"的 Viewer API
rerun.notebook.Viewer除了本例用到的能力外,还提供以下常用方法(均在 notebook.py 中有 docstring 说明):
| 方法 | 用途 |
|---|---|
display(block_until_ready=False) | 立即在 cell 中显示 Viewer;block_until_ready=True会阻塞等待 Viewer 就绪,避免数据在就绪前排入队列 |
add_recording(recording, blueprint) | 向同一 Viewer 追加一个 recording(注意rr.init默认复用同一recording_id,需要隔离时应显式传recording_id=uuid.uuid4()) |
set_time_ctrl(sequence/duration/timestamp, timeline, play) | 控制时间轴:三个时间参数至多设置一个(否则抛ValueError),分别对应序列号、相对时长与绝对时间戳;play=True从该时刻开始播放 |
open_url(url)/close_url(url) | 在 Viewer 中打开/关闭一个数据源 URL,与初始化时的url参数同源 |
set_default_size(width, height) | 模块级函数,为后续创建的所有 Viewer 设置默认宽高(当前默认 640×480) |
set_active_recording(recording_id) | 等价于在蓝图面板中点击某个 recording |
set_application_blueprint(...) | 为指定 application 设置 blueprint 并可选设为激活/默认 |
这些方法共同支撑了从"静态回放一个.rrd"到"Notebook 内实时记录 + 控制 + 交互反馈"的完整能力谱系。
注意事项与常见问题
- 资源加载失败时:前端会展示
ErrorWidget提示设置RERUN_NOTEBOOK_ASSET环境变量(见 error_widget.js),此时应按上文三种模式之一调整资源来源,并确保环境变量在 import 前生效。 - 远程 URL 录制:
url参数指向的必须是有效数据源;本例使用官方托管的raw_mesh.rrd,若你的网络无法访问该地址,可替换为本地自托管的.rrd地址。 - 面板锁定:
update_panels设置的状态会锁定面板,若希望用户能自由展开面板,请省略对应参数(保持None)。 - 从源码构建:若需在本地从源码构建 SDK 与 Notebook 支持包,可在仓库根目录执行
pixi run py-build && pixi run py-build-notebook,再运行pixi run uv run jupyter notebook(详见 rerun_notebook/README.md 的 "Run from source" 一节);修改 Viewer 或 TypeScript 代码后需重新执行py-build-notebook,仅改 Python 代码则重启 Jupyter kernel 即可。
综上,notebook_viewer是 Rerun Notebook 集成的入门范例:一条安装命令、一个Viewer对象、一份.rrdURL,即可在 Jupyter 内获得完整可交互的 3D 回放体验;而RERUN_NOTEBOOK_ASSET与底层 anywidget 事件队列机制,则为你在不同网络环境、不同托管场景下稳定使用该 Widget 提供了可查、可控的依据。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考