Skip to content

feat(core): support animated webp#52

Open
andykais-claude wants to merge 4 commits into
mainfrom
cursor/animated-webp-parser-2d95
Open

feat(core): support animated webp#52
andykais-claude wants to merge 4 commits into
mainfrom
cursor/animated-webp-parser-2d95

Conversation

@andykais-claude

Copy link
Copy Markdown
Collaborator

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.


Open in Web Open in Cursor 

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

cursor Bot commented Feb 24, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@andykais andykais changed the title Animated webp parser feat(core): support animated webp Feb 25, 2026
Comment thread packages/core/src/lib/file_processor.ts Outdated
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()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cursoragent I think this if condition can be removed. Ffprobe will never get this far into parsing an animated webp

@cursor cursor Bot Feb 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ 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.


Open in Web Open in Cursor 

Learn more about Cursor Agents

Comment thread packages/core/src/lib/file_processor.ts Outdated
* Uses a pure TypeScript RIFF/WebP parser to extract metadata.
* See https://trac.ffmpeg.org/ticket/4907
*/
async #get_info_webp_fallback(): Promise<FileInfo> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent is starting up. I'll add your follow-up shortly.

Open in Web Open in Cursor 

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cursoragent lets rename this file to packages/core/src/lib/file_processor_webp_shim.ts

@cursor cursor Bot Feb 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ 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.


Open in Web Open in Cursor 

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>
@andykais andykais marked this pull request as ready for review February 26, 2026 22:43
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) => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cursor replace this test with an integrated test in media.test.ts that checks these values from the forager.media.create return value

@cursor cursor Bot Feb 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ 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.


Open in Web Open in Cursor 

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants