FiftyOne MCAP Explorer:在 App 内将任意本地/远程 MCAP 录制打开为 Episode 的完整实现解析

FiftyOne MCAP Explorer:在 App 内将任意本地/远程 MCAP 录制打开为 Episode 的完整实现解析 FiftyOne MCAP Explorer在 App 内将任意本地/远程 MCAP 录制打开为 Episode 的完整实现解析【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyoneMCAP ExplorerMCAP 录制文件浏览器是 FiftyOne App 中负责打开任意本地或远程 MCAP 录制并将其呈现为一个 Episode的用户侧工作流模块。本文将基于 mcap-explorer/README.md 的领域定义结合app/packages/multimodal包内的面板实现、源描述符、云端解析注册表与测试用例完整讲解该模块的设计边界、交互流程、输入校验规则、字节源描述符结构以及云存储路径的扩展点帮助你理解如何在浏览器会话中安全、中立地消费 MCAP 录制数据。模块定位格式名描述产品表面而非实现边界README 开篇即定义了本模块的领域边界This domain owns the user-facing workflow for opening an arbitrary local or remote MCAP recording and presenting it as an episode.这句定义包含三层含义职责范围MCAP Explorer 只负责打开校验用户输入与呈现组装 Episode 能力是用户与录制数据之间的入口层中立性MCAP这个名字描述的是产品表面product surface不是实现边界。Explorer 本身不解析 MCAP、不消费生成的 schema、不导入适配器内部实现组合而非内联它只做校验输入 组装中立的能力描述真正的字节读取、格式解析、时间轴构建由下游的 Episode/Adapter 层完成。从源码看这一边界被严格贯彻app/packages/multimodal/src/views/mcap-explorer/McapExplorerPanel.tsx中没有任何 MCAP 字节解析逻辑面板把所有打开后的工作委托给SourcePlayback并通过episodeSourceFromByteSource见 episode-source.ts将一个物理录制包装成多资产 Episode 端口中的单个recording资产。可以推断这种格式无关的面板 格式相关的适配器分层是为了让同一套 Episode 回放体系能够承载 MCAP 之外的多种录制格式。用户工作流两种入口一套面板面板组件McapExplorerPanel由入口文件 entry.tsx 以懒加载lazywithSuspense方式注册为名为McapExplorerPanel的视图并配有一个独立的 McapExplorerIcon.tsx。面板提供两种打开方式方式一本地文件拖拽 / 文件选择支持将.mcap文件拖入drop zone或点击浏览通过系统文件选择器选取拖拽逻辑对dataTransfer做了兼容处理优先读files其次遍历items中kind file的条目最后回退检查types是否包含FilesisFileDrag/fileFromDataTransfer见 McapExplorerPanel.tsxdrop zone 用dragDepthRef计数器管理拖入/拖出状态避免进入子元素时闪烁同时保证已挂载录制期间禁止再次拖入新文件active非空时dropEffect置为none界面文案明确提示.mcap · files stay in this browser session and are read directly即本地文件仅存在于当前浏览器会话内、被直接读取不会上传到服务端文件选择器通过accept.mcap过滤类型并支持键盘Enter/空格触发浏览满足无障碍要求。方式二远程 URLHTTP(S) 或已配置的云路径面板底部提供 URL 表单输入框带ExternalLink图标提交按钮在打开过程中显示 Opening... 并禁用占位提示会根据当前产品版本动态变化未注册云解析器时https://example.com/recording.mcap已注册云解析器时https://example.com/recording.mcap or s3://bucket/recording.mcap打开成功后active状态驱动视图切换到SourcePlayback播放界面右上角提供Unmount recording按钮data-testidany-mcap-unmount用于卸载当前录制并回到选择界面选择界面通过隐藏的input typefile与 drop zone 复用实现。错误处理面板维护一个带target: file | url的ViewerError状态分别渲染在文件区或 URL 区下方。错误信息统一由diagnosticMessage(caught, Could not open MCAP)生成见 utils/errors.ts保证用户看到的是可读的定位信息而非原始异常堆栈。URL 输入变化时若此前有错误会自动清除。源描述符层校验输入并产出中立字节源用户输入到可读取的字节源的转换集中在 source-descriptors.ts该文件是 Explorer不解析 MCAP、只做校验与组合边界的最直接体现。字节源描述符结构字节源的类型定义位于 ir/bytes.tsexport interface ByteSourceDescriptor { readonly etag?: string; readonly localFile?: File; readonly readProfile?: ByteSourceReadProfile; readonly sizeBytes?: string; readonly sourceId: string; readonly url: string; }其中readProfile是传输中立层共享的稳定取值bytes.ts取值常量含义localBYTE_SOURCE_READ_PROFILE.LOCAL本地文件直接以 File 对象读取remoteBYTE_SOURCE_READ_PROFILE.REMOTE远程资源以 URL 进行字节范围读取readProfile被字节资源层用作缓存行为提示源码注释明确 Source-locality hint used by byte resources to choose cache behavior。本地源描述符createLocalMcapSourceDescriptor(file)source-descriptors.ts先经isMcapFile做扩展名校验/\.mcap$/i大小写不敏感不合法直接抛出Choose an .mcap file生成稳定的本地源 IDlocal-file:${name}:${size}:${lastModified}其中包含文件名、字节大小与最后修改时间三个要素描述符携带localFile对象本身、sizeBytes字符串形式、readProfile LOCALurl复用源 ID。这个复合源 ID 让同一文件的不同打开行为可被稳定识别与去重测试用例 source-descriptors.test.ts 验证了Drive.MCAP会得到local-file:Drive.MCAP:4:123这样的 ID且大小写不敏感的后缀校验生效。远程源描述符resolveRemoteMcapSourceDescriptor(value)source-descriptors.ts是 URL 输入的统一入口处理流程为trim后必须非空否则报Enter an HTTP(S) MCAP URL or cloud path用new URL(trimmed)解析解析失败报Enter a valid HTTP(S) URL or cloud pathHTTP(S) 直接放行protocol为http:或https:时走createRemoteMcapSourceDescriptor通过parseHttpUrl二次确认协议合法性非 HTTP(S) 报Only HTTP(S) MCAP URLs are supported并做trim归一化其他scheme://路径先校验形如/^[a-z][a-z\d.-]*:\/\//i的协议头然后查询已注册的云解析器getMcapCloudSourceResolver()——未注册时报Only HTTP(S) MCAP URLs are supported已注册则调用解析器换取签名 URL解析器返回的 URL 同样必须通过parseHttpUrl校验仅接受 HTTP(S)否则报The server did not return a valid signed MCAP URL。远程源的源 ID 恒为remote-url:${sourceIdentity}其中sourceIdentity是用户输入的原始标识如s3://bucket/run.mcap。这一点是刻意的安全设计签名 URL 中携带的 token/secret 不会进入源 ID从而避免凭证泄漏到缓存键或日志中。测试用例明确验证了这一点source-descriptors.test.ts解析gs://bucket/runs/drive.mcap得到的sourceId是remote-url:gs://bucket/runs/drive.mcap而url才是https://signed.example.com/file.mcap?tokensecret。路径语义的保留resolveRemoteMcapSourceDescriptor对云路径不做路径规范化而是原样传给解析器。测试覆盖了一个容易出错的边界source-descriptors.test.tss3://bucket/runs/../drive.mcap中的..可能是字面量的云对象键因此实现保留原样preserves dot segments that may be literal cloud object keys解析器收到的就是未经改写的完整路径。云端路径解析扩展点McapCloudSourceResolverREADME 提到的产品入口点可注册 cloud-source resolver在字节读取开始前将配置的存储路径换为浏览器可读 URL在代码中由 extensions/mcap-explorer/registry.ts 实现export type McapCloudSourceResolver (cloudPath: string) Promisestring;注册表的设计要点使用Symbol.for(fiftyone/multimodal:mcap-cloud-source-resolver)作为全局键将状态挂载在globalThis上天然支持跨模块、跨包共享包括不同产品版本之间的协作registerMcapCloudSourceResolver(resolver)遵循单例注册约束重复注册会抛错An MCAP cloud-source resolver is already registered相同 resolver 重复注册则视为幂等返回一个unregister函数用于注销getMcapCloudSourceResolver()返回当前 resolver 或nullhasMcapCloudSourceResolver()以布尔值告知面板当前版本是否支持云路径面板据此切换占位提示与提示文案HTTP(S) and configured cloud paths. 或 HTTP(S) sources must support CORS and byte-range reads.导出面收敛在 index.ts外部只可见注册、查询、判断三个函数与类型。这种产品入口点注册、面板按能力探测的模式让 OSS 版本默认只支持 HTTP(S)而特定产品版本可以通过注册解析器透明地获得 S3/GS 等云存储路径支持同时面板代码完全不需要了解具体云厂商。从字节源到 Episode中立能力组装打开成功后面板通过episodeSourceFromByteSource(source, EXPLORER_SOURCE_FACTS_SCOPE)episode-source.ts将单个字节源组装为 Episode 源assets.list()返回一个{ id: source.sourceId, role: recording }的单资产列表assets.resolve(assetId)只接受与sourceId匹配的资产否则抛Unknown episode assetepisodeId直接复用sourceId通过getSourceSessionHints(source, SOURCE_FACTS_MCAP_ADAPTER_ID)附带manifestHint/playbackHint存在时当传入SourceFactsScope时额外提供resolveHints将源事实解析委托给resolveSourceFactsHints。面板为此定义了一个专用的 SourceFactsScopeMcapExplorerPanel.tsxconst EXPLORER_SOURCE_FACTS_SCOPE: SourceFactsScope { cachePartition: OSS_SOURCE_FACTS_CACHE_PARTITION, // fiftyone-oss-origin datasetId: mcap-explorer, mediaField: null, };对照 runtime/source-facts.tsSourceFactsScope是安全与数据集边界的载体由于 Explorer 打开的录制不属于任何数据集样本datasetId被固定为mcap-explorer、mediaField为null、分区使用 OSS 原始命名空间fiftyone-oss-origin。源事实manifest、时间范围、时间轴会以 V1 schemaSOURCE_FACTS_SCHEMA_VERSION 1写入 IndexedDB 做持久化键由sourceFactsKey将 schema 版本、分区、数据集、媒体字段、源 ID、规范定位符组合而成持久化的内容证据本地文件的lastModified/name/sizeBytes或远程资源的etag会在下次打开时通过validateSourceFactsContent校验返回validated / provisional / stale三种信任级别从而在本地文件被替换或远程资源变化时自动判定缓存失效。由于本地文件没有数据集样本背书面板在播放界面固定使用无托盘tray的纯侧边栏RightSidebar注释明确说明No dataset sample backs a local file dropped here, so this surface hosts no trays见 McapExplorerPanel.tsx。运行前提与约束根据面板提示文案与源码校验逻辑远程源的可用性取决于以下前提HTTP(S) 源必须支持 CORS 与字节范围读取byte-range reads——这是面板在未注册云解析器时直接展示给用户的约束因为 Episode 播放器需要按范围拉取数据而非一次性下载本地文件仅 .mcap 后缀合法且只在当前浏览器会话内被直接读取不离开客户端云路径需要产品版本注册McapCloudSourceResolver且解析器必须返回合法的 HTTP(S) URL面板是单选语义同一时刻只挂载一个录制已挂载时拖拽、选择与 URL 提交均被忽略需先点击 Unmount recording 卸载。测试覆盖行为即规格模块配有两组 Vitest 测试将上述行为固化为可回归验证的规格McapExplorerPanel.test.tsx组件级mockSourcePlayback与useEpisodeSession初始为空状态展示 Drag drop an MCAP file打开直接 HTTP(S) URL 后切换到播放界面source携带readProfile: REMOTE与remote-url:前缀的sourceId文件选择器与拖拽均可打开本地文件layoutScopeKey为any-mcap:${sourceId}前缀兼容files为空时通过items读取拖拽文件卸载后恢复选择界面已挂载时再次拖入新文件被忽略注册云解析器后s3://bucket/run.mcap被正确解析为签名 URL且解析器以原始路径为入参被调用未注册解析器时s3://输入展示 Only HTTP(S) MCAP URLs are supported非 .mcap 文件展示 Choose an .mcap file。source-descriptors.test.ts单元级覆盖后缀校验、本地/远程源 ID 的确定性、HTTP(S) 校验、云路径解析、签名 URL 不进源 ID、点段保留、解析器返回非 HTTP 结果时报错等全部校验分支。小结MCAP Explorer 是 FiftyOne App 中一个边界清晰的入口域它把任意本地或远程 MCAP 录制转化为格式中立、可被统一 Episode 体系消费的字节源描述符并通过McapCloudSourceResolver注册表实现云存储路径的按版本扩展。理解 mcap-explorer/README.md 中格式名描述产品表面、而非实现边界这一原则是阅读整个app/packages/multimodal回放体系的最佳起点——后续无论是扩展新的录制来源还是深入 Episode 适配器实现都可以沿 source-descriptors.ts、episode-source.ts 与 registry.ts 三条主线继续跟进。【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考