Skip to content

feat(media): video HLS transcode + PDF thumbnails+text + migration (copy/proxy) - #476

Merged
tayebmokni merged 5 commits into
mainfrom
feat/media-video-pdf-migration
May 26, 2026
Merged

feat(media): video HLS transcode + PDF thumbnails+text + migration (copy/proxy)#476
tayebmokni merged 5 commits into
mainfrom
feat/media-video-pdf-migration

Conversation

@tayebmokni

Copy link
Copy Markdown
Contributor

Closes #52, #60, #187.

  • Asynq tasks: media.video.transcode (ffmpeg → HLS), media.pdf.process (pdftoppm + pdftotext)
  • packages/go/migrate/importer media migration with copy + proxy modes
  • Migrations 000036/000037/000038
  • Skip-graceful when ffmpeg/pdftoppm not on PATH

🤖 Generated with Claude Code

@tayebmokni
tayebmokni enabled auto-merge (squash) May 25, 2026 22:12
@tayebmokni
tayebmokni force-pushed the feat/media-video-pdf-migration branch 2 times, most recently from 434a879 to 9ebb225 Compare May 26, 2026 17:59
tib0o0o and others added 5 commits May 26, 2026 23:41
- 000036: media.hls_url for the video transcode pipeline (#52)
- 000037: media_text table for PDF text extraction (#60)
- 000038: media.is_proxied + media.source_url for migration proxy mode (#187)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Closes part of #52 and #60.

- packages/go/media/videoproc: ffmpeg-based HLS transcode taskspec
  (media.video.transcode) with injectable Runner. NewSpec for the
  available path, NewStubSpec for boot when ffmpeg is missing.
- packages/go/media/pdfproc: pdftoppm+pdftotext taskspec
  (media.pdf.process) with pdfcpu fallback. Skip-graceful when
  binaries are absent.
- Both packages ship recording-runner-based tests that never spawn a
  subprocess.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
- admin/media: route video uploads to media.video.transcode and
  PDF uploads to media.pdf.process. Both fail-soft on enqueue
  error (upload still succeeds; row stays committed).
- Asset wire: add hls_url, has_extracted_text, is_proxied,
  source_url so the admin detail page can surface the new state.
- apps/worker/internal/media: boot-time spec registration with
  skip-graceful fallback to stubs when ffmpeg/pdftoppm are
  missing on PATH.
- apps/worker/cmd/worker: register the heavy-media tasks on boot.

Closes part of #52 and #60.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Closes #187.

- packages/go/migrate/importer/media.go: MediaMigrator orchestrates
  per-asset ingestion. Copy mode downloads bytes locally and stores
  them via the destination's putter. Proxy mode skips the fetch
  and registers the row with is_proxied=true + source_url; the
  runtime image proxy (#37) serves the bytes read-through.
- Idempotency: FindBySourceURL probe lets a re-run of a partially-
  failed migration pick up where it left off without re-fetching
  or re-inserting.
- RewriteContent rewrites old→new URL pairs in post bodies (both
  modes feed it a pre-computed map).
- Options.MediaMigrator + Options.MediaUploaderID are the importer's
  wiring contract; Report grows MediaCopied/MediaProxied/
  MediaSkipped/MediaBytesFetched counters.
- gonext migrate wp gains a --media-mode flag (copy|proxy|off).
- Tests cover: copy mode (server hit, bytes stored, row inserted),
  proxy mode (no fetch, no upload), idempotency, ErrSourceNot200,
  ErrTooLarge, RewriteContent, flag parsing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
Surfaces the new asset state on the media detail page:

- HLS playlist link for transcoded video uploads (#52)
- "View extracted text" link for PDFs with media_text rows (#60)
- Proxy source URL for assets registered in proxy mode (#187)

The panel renders nothing when no derivatives are present, so the
common case (a directly-uploaded image) sees no layout change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.com>
@tayebmokni
tayebmokni force-pushed the feat/media-video-pdf-migration branch from 9ebb225 to e2fc860 Compare May 26, 2026 21:42
@tayebmokni
tayebmokni merged commit 97a46c8 into main May 26, 2026
12 of 17 checks passed
@tayebmokni
tayebmokni deleted the feat/media-video-pdf-migration branch May 26, 2026 21:42
tayebmokni pushed a commit that referenced this pull request May 28, 2026
next.config.ts no longer carries \`typescript: { ignoreBuildErrors:
true }\`, so the 12 pre-existing errors that flag was hiding now
fail \`next build\` and CI's \`pnpm lint\`. Address them all here.

- media/types.ts: \`MediaAsset\` was missing four fields the detail
  view (\`MediaDetailClient.tsx\`) actually reads — \`hls_url\`,
  \`source_url\`, \`is_proxied\`, \`has_extracted_text\`. Added as
  optional per the on-wire shape (worker pipeline #476 populates
  them on a subset of asset types). Resolves 11/12 errors across
  MediaDetailClient.tsx and its test fixture.

- appearance/menus/MenusClient.tsx:157: \`Array.splice\` returns
  \`T[]\` so the destructured element typechecks as \`T | undefined\`
  under noUncheckedIndexedAccess. Added an explicit guard before
  re-inserting so the array can't get a stray undefined.

\`pnpm exec tsc --noEmit\` is now clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Tayeb Mokni <tayeb.mokni@gmail.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.

Video transcoding (HLS via ffmpeg + Asynq)

2 participants