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:
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:
- A lookup endpoint (
/api/video-thumbnail?cid=…, batchable) that clients call for
video snaps they are about to render.
- 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.
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:No
image, nothumbnail. 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-transcodergenerates a thumbnail with ffmpeg for every video itprocesses, 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 returnsthumbnailUrlin the/transcoderesponse, 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_metadatais only editable by the post's author. Thereis no central way to rewrite thousands of third-party snaps.
Proposal
Expose the existing posters at read time, resolving CID →
thumbnailUrlfrom thePinata keyvalues. Two shapes worth considering:
/api/video-thumbnail?cid=…, batchable) that clients call forvideo snaps they are about to render.
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 screenwhere 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 readsjson_metadata.image/images. Picking one and documenting it avoids the nextround of this.
Context
Investigated in SkateHive/mobileapp#23, where the full measurements live.