Skip to navigation

Automate a VOD pipeline

This guide walks the complete Video on Demand (VOD) path through the Media API, from a source asset to a playable URL. The individual resources have their own guides; the goal here is to show how they connect so you can build a pipeline with less trial and error.

The sequence is:

  • Create an input asset that points to the source content.

  • Create or reuse a transform.

  • Create a job that applies the transform to the input asset.

  • Wait for the job to finish and the output asset to be ready.

  • Create a streaming locator on the output asset.

  • Start a streaming endpoint and call listPaths for the playback URLs.

You need a project with storage already configured, a personal API token, and source content in that storage.

Step 1: Create the input asset

  • Terminal window
curl -X PUT "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/assets/input-video-001" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"storageAccountName": "primary-azure",
"container": "input-video-001",
"description": "Source video for transcoding"
}
}'

This asset is the input reference for the job. See Assets for the full set of fields.

Step 2: Create or reuse the transform

Because transforms are reusable, you usually do this once per processing profile, not once per asset.

curl -X PUT "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/transforms/standard-encoding" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"description": "H.264 1080p multi-bitrate encoding",
"outputs": [
{
"preset": {
"@odata.type": "#Microsoft.Media.BuiltInStandardEncoderPreset",
"presetName": "H264MultipleBitrate1080p"
},
"relativePriority": "Normal"
}
]
}
}'

presetName must be one of the documented enum values. See Transforms and jobs for the available presets.

Step 3: Create the job

curl -X PUT "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/transforms/standard-encoding/jobs/job-001" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"input": {
"@odata.type": "#Microsoft.Media.JobInputAsset",
"assetName": "input-video-001"
},
"outputs": [
{
"@odata.type": "#Microsoft.Media.JobOutputAsset",
"assetName": "output-video-001"
}
],
"description": "Transcode input-video-001 with the standard transform"
}
}'

The job creates and populates the output asset named here.

Step 4: Wait for the job to finish

Poll the job state until it reaches Finished:

curl -X GET "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/transforms/standard-encoding/jobs/job-001/state" \
-H "Authorization: Bearer <YOUR_TOKEN>"

For background automation, subscribe to the MediaKind.JobStarted and MediaKind.JobFinished webhooks instead of polling.

Step 5: Publish the output asset

Create a streaming locator on the output asset, not the source:

curl -X PUT "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/streamingLocators/locator-001" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"assetName": "output-video-001",
"streamingPolicyName": "Predefined_ClearStreamingOnly"
}
}'

Step 6: Start the endpoint and get the URLs

Start the streaming endpoint if it is not already running, then list the locator paths:

curl -X POST "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/streamingEndpoints/default/start" \
-H "Authorization: Bearer <YOUR_TOKEN>"
curl -X POST "https://app.mk.io/api/v1/projects/<PROJECT_NAME>/media/streamingLocators/locator-001/listPaths" \
-H "Authorization: Bearer <YOUR_TOKEN>"

Combine each path with the endpoint hostName to build the playback URLs. See Streaming and publishing for URL construction.

What goes wrong

Publishing too early. A locator can only publish the asset you point it at. In a VOD pipeline, publish the output asset created by the job, after it reaches Finished, not the source asset.

  • Confusing the endpoint and the locator. The endpoint provides the delivery hostname; the locator provides the asset-specific path. You need both, and the endpoint must be running.

What comes next

  • Transforms and jobs: deeper detail on jobs and presets.

  • Content protection: add DRM to the published output.

  • Webhooks: replace polling with event-driven completion.