Skip to content

Expose video posters for already-published snaps from Pinata keyvalues #42

Description

@Bielcx

Problem

Video snaps published so far carry no poster image anywhere in their post data, so
any client showing a video has to download the video itself (~5 MB) before it can
render anything. Verified against production via condenser_api.get_content:

// xvlad/sh-20260727t031059 — posted from the mobile app
{"app":"mycommunity-mobile","tags":["hive-173115"]}

// web-gnar/4e174d2d-786a-4f3b-870b-0ef2bcfc8b39 — posted from the web app
{"app":"Skatehive App 3.0","tags":["hive-173115","snaps"],"images":[],"crosspost":{}}

No image, no thumbnail. The body is a bare
<iframe src="https://ipfs.skatehive.app/ipfs/<cid>">.

Measured impact on mobile: opening a profile grid shows ~8 seconds of grey tiles.
Gateway numbers for ipfs.skatehive.app: TTFB 1.0–1.8s, clips ~5 MB average
(0.8 / 6.1 / 7.3 MB sampled), Range requests supported. A ~30 KB poster instead of
a ~5 MB video is roughly 150× less data.

The posters already exist

SkateHive/video-transcoder generates a thumbnail with ffmpeg for every video it
processes, uploads it to Pinata, and records the URL in the Pinata keyvalues
under thumbnailUrl, keyed by the video's CID.

SkateHive/video-transcoder#2 (merged) now also returns thumbnailUrl in the
/transcode response, so new uploads can persist it at publish time.

That does nothing for everything already posted — and those posts cannot be fixed
by a backfill, because json_metadata is only editable by the post's author. There
is no central way to rewrite thousands of third-party snaps.

Proposal

Expose the existing posters at read time, resolving CID → thumbnailUrl from the
Pinata keyvalues. Two shapes worth considering:

  1. A lookup endpoint (/api/video-thumbnail?cid=…, batchable) that clients call for
    video snaps they are about to render.
  2. Enriching video snaps in the existing feed responses with the resolved poster,
    so clients get it for free.

Option 2 is nicer for clients but doesn't cover every consumer today — see below.

Constraint worth deciding up front

The SkateHive mobile profile grid does not go through this API. It reads
comments straight from Hive RPC (lib/hooks/useUserComments.ts
bridge.get_account_posts), so feed-level enrichment would not reach the screen
where the problem was actually reported. Either that screen moves to the API, or it
needs a lookup endpoint it can call directly.

Whichever way it goes, it would help to settle the metadata key across clients:
the web writes posters to json_metadata.thumbnail, while the mobile app reads
json_metadata.image / images. Picking one and documenting it avoids the next
round of this.

Context

Investigated in SkateHive/mobileapp#23, where the full measurements live.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions