av-club claims HEIC for the file browser

`fileTypes` in the manifest, and two GET routes behind it: /v1/thumb and
/v1/render. the platform calls them when it meets a `.heic` and nothing in the
platform knows which plugin answered.

THIS IS THE REASON TO INSTALL av-club FOR SOMEBODY WHO NEVER CONVERTS ANYTHING.
sharp's libheif has no HEVC decoder, so without this a folder of iPhone photographs
is a wall of file icons and opening one offers a download. with it, they thumbnail
and they open.

only heic and heif are claimed. everything else the browser shows — jpeg, png,
webp, avif, svg, and every video ffmpeg reads — core already handles, and claiming
those would take work off a path that is faster and needs no plugin.

size and width are CLAMPED here rather than trusted. the caller is the platform
rather than a browser, but a route that resizes to whatever number arrives is one
query string from an allocation the size of the machine, and "the only caller is
trusted" stops being true the first time somebody adds a second caller.

THE DERIVED ASSET IS DELETED AFTER THE BYTES ARE READ. runSharp without an
outputPath stores its result — right for the API, wrong here: this is a view of a
file that already exists, asked for on every folder listing, and keeping them would
fill the asset store with thumbnails nothing owns and nothing expires. read fully
rather than streamed, because a streamed Bun.file would still be reading when the
delete lands.

jpeg for the thumbnail (small, universal), webp for the render (the viewer wants
the quality back).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-29 07:51:06 +01:00
co-authored by Claude Opus 5
parent cb5dfabce2
commit 69f4cc9cae
2 changed files with 80 additions and 1 deletions
+18 -1
View File
@@ -18,7 +18,7 @@ import type { PluginManifest } from '@@/plugins/manifest';
*/
export const manifest: PluginManifest = {
publisher: 'officerdev',
version: '2026.08.28.01',
version: '2026.08.29.01',
platform: '>=1.0.0',
label: 'AV Club',
summary: 'Convert and treat images, video and audio — sharp, ffmpeg and ffprobe behind one API',
@@ -56,6 +56,23 @@ export const manifest: PluginManifest = {
No `binary:` that means anything on its own — it is a shared library plugin, not a command. The
binary named is the one that USES it, which is what makes the check meaningful.
*/
/*
The formats the platform cannot read, and which this plugin can.
HEIC is why av-club is worth installing for somebody who never converts anything: sharp's libheif
has no HEVC decoder, so without this a folder of iPhone photographs is a wall of file icons and
opening one offers a download. With it, they thumbnail and they open.
Only HEIC and HEIF are claimed. Everything else the file browser shows — jpeg, png, webp, avif, svg,
and every video ffmpeg reads — core already handles, and claiming those would be taking work away
from a path that is faster and needs no plugin.
*/
fileTypes: {
extensions: ['heic', 'heif'],
thumbnail: '/v1/thumb',
render: '/v1/render',
},
osDependencies: [
{
binary: 'ffmpeg',