feat(core): support animated webp#52
Conversation
Adds a RIFF/WebP binary format parser (webp_parser.ts) that extracts metadata from WebP files without depending on FFmpeg, which currently lacks proper animated WebP support (see ffmpeg ticket #4907). The parser handles: - VP8X extended format (animated + still, with alpha detection) - VP8 lossy bitstream dimension extraction - VP8L lossless bitstream dimension extraction - ANIM chunk (loop count, background color) - ANMF frame chunks (per-frame duration, dimensions, blending/disposal) Integration into file_processor.ts: - Falls back to the WebP parser when ffprobe fails on .webp files - Falls back when ffprobe returns zero width/height for .webp files - Replaces the old hard error with a functional shim Tests use synthetic RIFF buffers to validate all chunk types and error cases. Stubs for real file tests are left as comments pending sample animated/non-animated WebP resource files. Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>
|
Cursor Agent can help with this pull request. Just |
| if (media_type !== 'AUDIO' && width === 0 || height === 0) { | ||
| if (path.extname(this.#filepath) === '.webp') { | ||
| throw new errors.InvalidFileError(`webp decoding is not yet supported by ffmpeg. See here https://trac.ffmpeg.org/ticket/4907`, new Error(`width: ${width} and height: ${height} values cannot be zero`)) | ||
| return this.#get_info_webp_fallback() |
There was a problem hiding this comment.
@cursoragent I think this if condition can be removed. Ffprobe will never get this far into parsing an animated webp
There was a problem hiding this comment.
❌ Unable to add follow-up after multiple attempts. The agent may be experiencing issues.
Please try again later or Open in Web to view the status.
Learn more about Cursor Agents
| * Uses a pure TypeScript RIFF/WebP parser to extract metadata. | ||
| * See https://trac.ffmpeg.org/ticket/4907 | ||
| */ | ||
| async #get_info_webp_fallback(): Promise<FileInfo> { |
There was a problem hiding this comment.
@cursoragent this helper method is unnecessary in file_processor.ts. Lets move it to webp_parser.ts. That file should only expose a function that returns FileInfo. No need to expose a webp specific parsed format
There was a problem hiding this comment.
@cursoragent lets rename this file to packages/core/src/lib/file_processor_webp_shim.ts
There was a problem hiding this comment.
❌ Unable to add follow-up after multiple attempts. The agent may be experiencing issues.
Please try again later or Open in Web to view the status.
Learn more about Cursor Agents
- Rename webp_parser.ts to file_processor_webp_shim.ts - Move FileInfo conversion logic into the shim (get_webp_file_info) so it returns FileInfo directly, no webp-specific types exposed - Remove zero-dimension webp fallback in file_processor.ts since ffprobe will never get that far when parsing animated webp - Export FileInfo type from file_processor.ts for the shim to use - Update test imports to match renamed file Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>
Add nyan_cat.webp (400x400, 12 frames, 840ms, animated with alpha) as a test resource and integrate it into the WebP parser test suite. New test suite 'webp_parser - animated webp file from disk': - parse_webp: validates canvas dimensions, frame count, total duration, alpha flag, loop count, and per-frame durations from a real file - get_webp_file_info: validates the full FileInfo output including codec, media_type, content_type, framerate, and filename Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>
| }) | ||
|
|
||
|
|
||
| test('webp_parser - animated webp file from disk', async (ctx) => { |
There was a problem hiding this comment.
@cursor replace this test with an integrated test in media.test.ts that checks these values from the forager.media.create return value
There was a problem hiding this comment.
❌ Unable to add follow-up after multiple attempts. The agent may be experiencing issues.
Please try again later or Open in Web to view the status.
Learn more about Cursor Agents
Replace the unit-level get_webp_file_info test in webp_parser.test.ts with an end-to-end test in media.test.ts that validates animated WebP properties through forager.media.create. The integration test revealed two issues that needed fixing: - ffprobe succeeds on animated WebP but returns width=0/height=0, so the zero-dimension fallback to the webp shim is needed after all - ffmpeg cannot generate thumbnails for animated WebP, so create_thumbnails now skips thumbnail generation for animated webp (returning 0 thumbnails) instead of failing the entire media creation Co-authored-by: andykais-claude <andykais-claude@users.noreply.github.com>


Add a pure Deno WebP parser to support animated WebP files as a fallback when ffprobe fails or returns zero dimensions.
FFmpeg currently lacks proper support for animated WebP, making this parser a temporary shim to extract essential metadata like width, height, and duration until native FFmpeg support is available.