Open Videocore
Open Videocore is a headless media asset management (MAM) system from Eyevinn Technology. It stores, transcodes, packages, and delivers video content through a single API. Under the hood it integrates SVT Encore for transcoding, Shaka Packager for packaging, MinIO for object storage, and CouchDB for the asset catalogue.
Getting Started
Deploy an Open Videocore instance at app.osaas.io/dashboard/service/eyevinn-open-videocore.
Getting from a new instance to a playable asset takes five steps: create the instance, provision a media stack, bootstrap the transcoding profiles, ingest a source, and transcode it. Steps 4 and 5 below are required — the ingest call will not work without them.
Prerequisites
- An OSC account on a paid plan (sign up at app.osaas.io)
- A Parameter Store instance (required for configuration)
- An OSC Personal Access Token (PAT) — create one at app.osaas.io/dashboard/tokens
Configuration Options
| Field | Required | Description |
|---|---|---|
name |
Yes | Alphanumeric instance name |
OscAccessToken |
Yes | OSC PAT used by Open Videocore to spin up Encore transcoding jobs (sensitive) |
ParameterStoreApiKey |
Yes | API key for the Parameter Store instance |
ParameterStore |
Yes | Name of the Parameter Store instance |
MinioRootPassword |
Yes | Root password for the MinIO object storage backend (sensitive) |
CouchdbAdminPassword |
Yes | Admin password for the CouchDB asset catalogue (sensitive) |
EncoreMaxInstances |
No | Maximum concurrent Encore transcoding instances |
EncoreMinInstances |
No | Minimum Encore instances to keep warm |
EncoreIdleTimeoutMs |
No | Milliseconds before idle Encore instances are scaled down |
The effective values of the three Encore* fields on a running instance are readable from GET /api/v1/scaler/status, and can be changed at runtime without a restart via PATCH /api/v1/scaler/config. See Tuning the Encore auto-scaler.
Token Costs
Short answer: yes, the services Open Videocore provisions are billed in addition to Open Videocore itself, and the on-demand Encore instances are by far the largest component.
Open Videocore is an orchestration layer. Its own service page rate covers only the Open Videocore instance. Everything it provisions on your behalf is a separate OSC service instance with its own token rate, running in your workspace and billed to you.
Always running once you provision a stack:
| Service | What it does |
|---|---|
eyevinn-open-videocore |
the API and orchestrator itself |
minio-minio |
object storage for sources and packaged output |
apache-couchdb |
the asset catalogue |
valkey-io-valkey |
the job queue |
Provisioned on demand, and torn down again:
| Service | When it appears |
|---|---|
encore |
spun up by the auto-scaler when transcode jobs arrive, torn down after EncoreIdleTimeoutMs of idle time. This is the dominant cost and the one worth tuning. |
eyevinn-encore-packager |
created lazily on the first packaging job, then reused; removed when the stack is deprovisioned |
eyevinn-ffmpeg-s3 |
per-job, for technical metadata extraction |
To see the current rate for any of these before you commit to it, ask your MCP-connected agent to estimate the cost, or check each service's page in the dashboard. Rates are quoted per instance-day and are ceilings — the maximum if the instance ran continuously — so a stack whose Encore instances scale to zero between jobs bills well below the ceiling. See Pricing.
The lever that matters. Encore dominates the bill and only runs while it has work. If your jobs arrive in bursts, lowering EncoreIdleTimeoutMs tears instances down sooner between bursts. If they arrive steadily, leaving the timeout higher avoids paying the cold-start on every job. GET /api/v1/scaler/status shows what the pool is doing right now.
Step-by-Step Guide
1. Create a Parameter Store
Open Videocore requires a Parameter Store to hold configuration. Create one first:
- Go to My Apps → Parameter Store and click Create parameter store
- Note the store name and API key shown on creation
2. Store sensitive credentials as service secrets
osc create-secret miniopwd <your-minio-root-password>
osc create-secret couchdbpwd <your-couchdb-admin-password>
osc create-secret oscpat <your-osc-pat>
osc create-secret paramstorekey <your-parameter-store-api-key>
3. Create the Open Videocore instance
osc create eyevinn-open-videocore myvideocore \
-o OscAccessToken="{{secrets.oscpat}}" \
-o ParameterStoreApiKey="{{secrets.paramstorekey}}" \
-o ParameterStore="my-param-store" \
-o MinioRootPassword="{{secrets.miniopwd}}" \
-o CouchdbAdminPassword="{{secrets.couchdbpwd}}"
Via API:
curl -s -X POST \
-H "x-pat-jwt: Bearer $PAT" \
-H "Content-Type: application/json" \
-d '{
"name": "myvideocore",
"OscAccessToken": "{{secrets.oscpat}}",
"ParameterStoreApiKey": "{{secrets.paramstorekey}}",
"ParameterStore": "my-param-store",
"MinioRootPassword": "{{secrets.miniopwd}}",
"CouchdbAdminPassword": "{{secrets.couchdbpwd}}"
}' \
https://eyevinn-open-videocore.svc.prod.osaas.io/eyevinn-open-videocoreinstance
The instance URL is shown in the dashboard. It is written as https://<instance-url> in the rest of this guide.
4. Provision a media stack
Required before you can ingest anything. This stands up the backing infrastructure for a workspace: MinIO, CouchDB, and Valkey. Encore is not created here — the auto-scaler spins it up when the first transcode job arrives — and the packager is created lazily on the first packaging job.
curl -s -X POST https://<instance-url>/api/v1/provision/ \
-H "Content-Type: application/json" \
-d '{"name": "mystack"}'
Provisioning is asynchronous. The call returns an operationId. Poll it until status is done:
curl -s https://<instance-url>/api/v1/provision/operations/<operationId>
Inspect or tear down stacks later:
curl -s https://<instance-url>/api/v1/provision/ # list stacks
curl -s https://<instance-url>/api/v1/provision/mystack # inspect one
curl -s -X DELETE https://<instance-url>/api/v1/provision/mystack
By default the stack provisions its own MinIO instance and buckets, and no storage configuration is needed. To point the source or packaged-output roles at an existing AWS-region or S3-compatible bucket instead, pass the optional sourceStorage and packagedStorage blocks. The provisioning with external S3-compatible storage guide documents every field, including the CDN-origin pattern.
5. Bootstrap the transcoding profiles
Also required. This seeds the profile store from the default Encore profile index. Without it there are no profiles for a transcode job to reference.
curl -s -X POST https://<instance-url>/api/v1/profiles/bootstrap
Pass ?force=true to re-seed. Profiles are stored in CouchDB and can be listed, created, replaced, and deleted through /api/v1/profiles, or managed in the Profiles tab of the ops dashboard.
6. Ingest a source video
curl -s -X POST https://<instance-url>/api/v1/assets/ingest-url \
-H "Content-Type: application/json" \
-d '{"sourceUrl": "https://example.com/source.mp4", "name": "My first asset"}'
Only sourceUrl is required; name, description, title, and tags are optional. The response contains the asset ID used in every call below.
Other ingest routes are available for media you are not pulling from a URL: PUT /api/v1/assets/:id/upload for a direct upload, POST /api/v1/assets/:id/upload-url for a presigned single-part upload, and the POST /api/v1/assets/:id/multipart/initiate family for large files. Watch-folder ingest from a bucket is available through /api/v1/storage/buckets/:bucket/watch-folder/toggle.
7. Transcode
curl -s -X POST https://<instance-url>/api/v1/assets/<asset-id>/transcode \
-H "Content-Type: application/json" \
-d '{"profile": "program"}'
All body fields are optional: profile names a bootstrapped profile, customProfile supplies profile YAML inline, and profileParams passes parameters to a parametrised profile.
This is the first call that causes an Encore instance to be created, so the first job on a cold pool takes noticeably longer than later ones. Track progress with GET /api/v1/jobs/ and GET /api/v1/jobs/<job-id>.
To package for adaptive streaming, POST /api/v1/assets/<asset-id>/package. POST /api/v1/assets/<asset-id>/execute runs transcode and packaging as one pipeline execution.
8. Get playback URLs
curl -s https://<instance-url>/api/v1/assets/<asset-id>/delivery
Returns the packaged HLS/DASH manifest URLs, or a presigned download URL for the source.
Webhooks
Rather than polling /api/v1/jobs/, register a webhook and Open Videocore will notify you on asset and job lifecycle events.
curl -s -X POST https://<instance-url>/api/v1/webhooks/ \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/videocore",
"events": ["transcode.complete", "transcode.failed"],
"secret": "<shared-secret-for-signature-verification>"
}'
url and events are required, secret is optional. Available events:
| Event | Fires when |
|---|---|
asset.ready |
an ingested asset is ready |
asset.failed |
ingest failed |
transcode.complete |
a transcode job finished |
transcode.failed |
a transcode job failed |
package.complete |
a packaging job finished |
package.failed |
a packaging job failed |
List with GET /api/v1/webhooks/ and remove with DELETE /api/v1/webhooks/<id>.
Ops dashboard
Every instance serves a built-in dashboard at https://<instance-url>/ui for managing assets, jobs, profiles, and buckets. Interactive API documentation is at https://<instance-url>/api-docs, and a generated openapi.json is committed in the repository if you prefer to read the contract without a running instance.
Other capabilities
| Capability | Endpoint |
|---|---|
| Thumbnails / poster frames | POST and GET /api/v1/assets/:id/thumbnails |
| Clip and trim into a new asset | POST /api/v1/assets/:id/clip |
| Container re-wrap without re-encode | POST /api/v1/assets/:id/export |
| Technical metadata extraction | POST /api/v1/assets/:id/extract-metadata |
| Audio and subtitle track management | /api/v1/assets/:id/tracks, /audio-tracks, /subtitle-tracks |
| Collections | /api/v1/collections |
| Full-text and metadata search | GET /api/v1/search/ |
| Object storage and buckets | /api/v1/storage/buckets |
Note that GET /api/v1/assets/search is a deprecated free-text-only alias kept for backward compatibility. New integrations should use GET /api/v1/search/.
Tuning the Encore auto-scaler
curl -s https://<instance-url>/api/v1/scaler/status
curl -s https://<instance-url>/api/v1/scaler/config
curl -s -X PATCH https://<instance-url>/api/v1/scaler/config \
-H "Content-Type: application/json" \
-d '{"maxInstances": 3, "idleTimeoutMs": 120000}'
maxInstances, minInstances, and idleTimeoutMs can all be changed at runtime without restarting the instance. idleTimeoutMs must be at least 10000.
scalerActive reads false until a stack is provisioned. The auto-scaler activates against the provisioned stack's Valkey immediately after POST /api/v1/provision/ completes, with no restart needed.
Important Notes
- Configuration updates not supported. Open Videocore does not support in-place configuration updates via
update-service-instance. To change the fields in the table above, delete the instance and create a new one. The auto-scaler settings are the exception and are changeable at runtime, as described above. - Data persistence. Asset data is stored in MinIO and CouchDB within the instance. Deleting the instance will delete all stored assets and the asset catalogue.
- Provisioning and profile bootstrap are one-time per stack, but both are required before the first ingest. A
404or an empty profile list on your first transcode almost always means one of them was skipped.
Resources
- GitHub repository
- Service page
- SVT Encore — the transcoding engine used internally
- Parameter Store
- Pricing