Play .fb FlatBuffer log files containing JPEG frame sequences as video, directly inside VS Code.
This is not a generic FlatBuffer browser. It targets a specific log layout: a stream of RawMessage records, each carrying a topic, msg_type, nanosecond timestamp, and an opaque data byte vector. When data is a ROS2 sensor_msgs/CompressedImage CDR payload, the embedded JPEG is extracted and rendered.
Features
- Open any
*.fbfile in a custom editor — no schema files, noflatc, no Python. - Scrub and play through the JPEG frames like a video.
- Per-frame metadata sidebar: timestamp, topic, message type, payload size, JPEG dimensions, decoded JPEG byte count.
- FPS auto-derived from the timestamp range; falls back to 30 fps if timestamps are missing or non-monotonic.
- Keyboard controls:
←/→to step,Spaceto toggle play. - Theme-aware (VS Code dark/light), CSP-locked webview.
How it works
The extension performs three things in pure TypeScript:
- FlatBuffer parsing. The
.fbsschema is unknown, so the parser is data-driven. It tries three buffer framings (plain root, 4-byte size prefix, concatenated size-prefixed records) and probes every vtable slot of the root and message tables, classifying fields by content (int64 timestamp range, length-prefixed printable strings, length-prefixed binary blobs). - CDR decoding. For
sensor_msgs/msg/CompressedImagepayloads, it walks the CDR-encodedHeader.stamp/frame_id/format/datalayout with proper 4-byte alignment, then returns the JPEG byte slice. If CDR parsing fails, it falls back to scanning for JPEG SOI/EOI markers. - JPEG dimension reading. Walks JPEG marker segments to find any SOFn marker and reads the width/height from its payload.
The full file buffer stays in the extension host. The webview receives only frame index metadata ({index, timestampNs, topic, msgType, dataLength}); JPEG frames are delivered on demand as base64 data URLs and cached in an LRU of 30 in the webview.
Schema assumed
table RawMessage {
timestamp_ns: long;
topic: string;
msg_type: string;
data: [ubyte];
}
table Log { messages: [RawMessage]; }
root_type Log;
Field IDs need not be exactly 0..3 — the parser probes every slot. Additional fields on either table are tolerated.
Usage
- Open the folder containing your
.fbfiles in VS Code. - Click a
.fbfile (or use Open With… → FB Video Viewer). - Use the play button, the timeline scrubber, or the arrow keys.
Limitations
- Only JPEG payloads are rendered. PNG, raw YUV, and other compression formats inside
CompressedImageare not decoded. - Streaming chunks larger than ~1 GB will hit the V8 string size limit when base64-encoding individual JPEGs (each frame is bounded, so this is unlikely in practice).
- The webview shows one frame at a time; there is no thumbnail strip.
Development
npm install
npm run watch # background type-check + dual esbuild bundle
Press F5 to launch the Extension Development Host.