Skip to content

Guide

Setup and example usage. For design/architecture see Architecture; for pipeline details see Transcoding.


Setup

  1. Clone all required repositories and install β€” follow Installation
  2. cd Quickstart
  3. docker login registry.nexus.castis.io
  4. make media-d
  5. Test: curl localhost:3000/api/v1/media

Required services: SeaweedFS (object storage, S3 API :8333 + Filer API :8888), seaweedfs_init (one-shot bucket creation), tusd (resumable upload server, calls CoreAPI's /hooks/tusd on finish). All in the LITE infra group used by make media.

Document rasterization also needs LibreOffice (headless, PPT/PPTX/ODP β†’ PDF) and ghostscript β€” both baked into CoreAPI's own Docker image (apk add libreoffice ghostscript), not separate compose services. Rebuild the CoreAPI image if it predates this (docker compose build coreapi).


Example usage

All examples assume localhost:3000; swap for staging as needed β€” see the servers: list in media.yaml.

1. Pick a profile (seeded profiles always present β€” see Transcoding Β§ Seeded Profiles):

curl "localhost:3000/api/v1/media/transcoding-profiles?category=image"

2. Prepare + upload with that profile's id:

curl -X POST localhost:3000/api/v1/media/prepare \
  -H 'Content-Type: application/json' \
  -d '{"title":"deck","originalName":"deck.pptx","fileSize":123456,"tenant":"jastv","folder":"test","transcodingProfileId":<id>}'
# β†’ { "token": "...", "expiresAt": "..." }
Then TUS-upload the file to /tusd/ (suite-wide shared path) with metadata.uploadToken set to that token β€” easiest driven through PlayoutAdmin's "Add content" sheet rather than a hand-rolled TUS client.

3. Verify, per category:

curl localhost:3000/api/v1/media/<id> | jq '.data.transcodingStage, .data.optimizedKey'
curl localhost:3000/api/v1/media/<id>/slides | jq       # document only β€” [] until rasterized

4. Passthrough: repeat step 2 with the seeded *-PASSTHROUGH profile's id for the category β€” expect transcodingStage: "done" quickly, no optimizedKey/slides produced.

5. Purge + audit:

curl -X DELETE localhost:3000/api/v1/media/<id>              # purge defaults to true
curl "localhost:3000/api/v1/media/storage-audit?prefix=test/"


Frontend integration notes

Things not obvious from the route list alone β€” relevant if you're building or porting a client against this API (see also the capability apps that already do this for PlayoutAdmin):

  • No auth is enforced by this domain today β€” media routes aren't wired to the RS256 JWT validator at registration (unlike identity/tenancy). Don't assume a bearer token is required or checked.
  • VITE_CDN_HOST must already include the serving route + bucket, not just a bare host β€” see Architecture Β§ Asset URL Strategy for the exact staging bug this caused (source/optimized/slide links breaking while the plain download link kept working).
  • purge defaults to true on DELETE /media/:id β€” pass ?purge=false explicitly to keep the old DB-only soft-delete.
  • GET /media/:id/slides always returns an array, never 404, for a document that hasn't been rasterized or was passthrough β€” treat [] as "no slides yet," not an error.
  • No mime-type allowlist/rejection at POST /media/prepare or upload time β€” mediaType/mimeType are stored as given and used to pick a pipeline; validate on the client if you want to reject unsupported files before spending an upload.
  • /assets/* may not be CoreAPI in your deployment β€” in the PlayoutAdmin/Quickstart topology, nginx routes /assets/ straight to cproxyβ†’SeaweedFS, bypassing CoreAPI's own ServeAsset route entirely. Confirm which one your environment actually points at before relying on CoreAPI-specific behavior (e.g. presigned URLs) for asset delivery.
  • /hooks/tusd has no signature check β€” if you're standing up your own tusd instance against this API, know that only the uploadToken value gates the webhook, not a shared secret.
  • ValidatePrepare only checks 3 fields (title, originalName, fileSize > 0) β€” everything else on the prepare payload is optional and unvalidated server-side.