Our /video/ondemand Robot
Beta

Stream videos with on-demand encoding

πŸ€–/video/ondemand generates HTTP Live Streaming (HLS) playlists and segments on-demand for adaptive and cost-efficient playback.

Warning: This feature is still in an experimental stage. Its behavior, parameters, and pricing may change while we continue to work on it. If you encounter any bugs or odd behavior, please contact us.

This Robot provides an adaptive and cost-efficient solution for video streaming in combination with Transloadit's Smart CDN. Adaptive video playback enables the video player to choose from multiple video variants with different resolutions and bitrates to optimize for different devices and network conditions. Furthermore, video encoding work is only performed on-demand when necessary to fulfill the data requests from video players. Thereby, only the portions of the video that are actually loaded by a player are imported and encoded, avoiding costs for encoding entire or portions of videos that are never watched. This is in stark contrast to traditional encoding methods, provided by the /video/encode and /video/adaptive Robots, that process the entire video upfront, regardless of whether the content is consumed or not.

This cost-effective approach is particularly beneficial for:

  • Long-form content where viewers often watch only specific sections
  • Video libraries with low watch-through rates
  • Applications where bandwidth and processing efficiency are priorities
  • Providing a new codec or higher resolution for a small subset of players that support it

How it works

πŸ€–/video/ondemand enables video playback using HTTP Live Streaming (HLS). With HLS, a video is divided into multiple segments that are usually just a few seconds long. These segments are referenced in a playlist file, allowing the video player to load the segments needed for the current playback position. In addition, playlists can reference different video variants with varying resolutions and bitrates. Players can freely choose from these variants and optimize for the current network connectivity and device capabilities. When a video is then played back over HLS, the video player sends individual HTTP requests to fetch the playlists and segments.

This Robot takes advantage of HLS' segmentation and generates playlist and segment files on-demand when requested by the video player. When a video is played back for the first time, the Robot will quickly generate the necessary HLS playlist and segment files as they are requested by the video player. Subsequent requests for these files will be served directly from Smart CDN's edge network, avoiding the need to re-generate the files. If certain segments of a video are not requested by the viewer, they will not be generated β€” therefore, no encoding costs are incurred.

Video files are imported from a storage service, such as AWS S3, S3-compatible providers, or HTTP servers. To optimize delivery and cost, this Robot will only import parts of the video that are necessary for the video sections requested by the viewer.

πŸ€–/video/ondemand does currently not support playback methods other than HLS, such as MPEG-DASH.

How to set it up

To get started, create a Template that uses the πŸ€–/video/ondemand. The following example Template will import a video from S3 and encode it into three variants (480p, 720p, 1080p). Please note the return_file_stubs parameter, which enables this Robot to avoid importing the entire video and only load the necessary parts for the requested video sections. Currently, only the /s3/import and /http/import Robots support this parameter.

{
  "steps": {
    "import": {
      "robot": "/s3/import",
      "path": "${fields.input}",
      "credentials": "YOUR_AWS_CREDENTIALS",
      "return_file_stubs": true
    },
    "vod": {
      "robot": "/video/ondemand",
      "use": "import",
      "variants": {
        "480p": {
          "preset": "hls/480p",
          "ffmpeg_stack": "v6.0.0"
        },
        "720p": {
          "preset": "hls/720p",
          "ffmpeg_stack": "v6.0.0"
        },
        "1080p": {
          "preset": "hls/1080p",
          "ffmpeg_stack": "v6.0.0"
        }
      }
    },
    "serve": {
      "use": "vod",
      "robot": "/file/serve"
    }
  }
}

The video playback is then accessible through Transloadit's Smart CDN and can be accessed through the following URL:

https://[workspace].tlcdn.com/[template]/[path]

Where:

  • [workspace] is the name of your Workspace
  • [template] is the name of your Template
  • [path] is the path to the video file in your storage service (e.g. S3)

For the Template above, the URL https://my-workspace.tlcdn.com/my-template/my-video.mp4 will serve the video file my-video.mp4 from the S3 bucket configured with YOUR_AWS_CREDENTIALS.

When Smart CDN receives a request to play the video, it will either serve cached assets or generate the necessary files on-demand.

To test playback, you can open the playlist URL with an HLS-compatible video player, such as VLC Media Player or the hls.js online demo.

Costs

One of the main benefits of on-demand video encoding is that it only encodes the parts of a video that are actually requested by the viewer. This means you only pay for the encoding that is performed β€” not for the entire video upfront.

HTTP Live Streaming (HLS) splits a video into multiple segments, each just a few seconds long, controlled by the segment_duration parameter. Video players load only the segments needed for the current playback position, plus a few additional segments for buffering. However, especially for longer videos, they typically do not load all segments.

Since πŸ€–/video/ondemand only charges for segments and playlist files that are actually generated and requested by video players, you will not be charged for video segments that are never requested. In addition, you will also not be charged for videos that are never played at all.

This makes on-demand encoding a cost-efficient solution for applications where videos are often partially watched β€” or not watched at all. Because segments are created on-demand, no storage costs are incurred for unused segments.

Access control through signed URLs

While some videos are public and can be accessed by anyone, you may want to restrict access to your videos. For example, only authenticated users are allowed to watch certain videos.

These restrictions can be implemented by using signed URLs. First, enable the sign_urls_for parameter for the /video/ondemand Robot in the Template. The generated HLS playlist files will then contain signed URLs, that are valid for the specified duration. Please be aware that the duration shouldn't be too short or otherwise the signatures will expire while the video is being played back, which can cause the video to halt.

Next, you need to enforce the use of signature authentication. You can either require it for all Assemblies in a workspace by enabling the Require a correct Signature setting. Alternatively, signatures can be required for specific Templates only through enabling the Signature Auth setting when editing a Template or through the require_signature_auth parameter when using Transloadit's API to manage Templates. When either of these is enabled, our services will reject corresponding Assemblies that do not include a valid signature without incurring any costs.

The final step is to generate signed Smart CDN URLs for authorized users. When you want to allow an authorized user to watch a video, you need to generate a signed URL for as outlined in the Smart CDN Signatures documentation. For example, a signed URL then looks like this:

https://my-workspace.tlcdn.com/my-template/my-video.mp4?exp=1741681323604&sig=sha256:d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3

The player can then load the playlist thanks to the signature, while all following video assets can be loaded through their signed URLs in the playlist file.

This method can also be used to restrict access to certain variants of a video. For example, you may want to allow users to watch the 480p and 720p variants of a video, but not the 1080p variant. The enabled_variants parameter can be used to restrict the variants that are available to the viewer, as /video/ondemand will refuse to generate files for non-enabled variants. To utilize this capability, define the enabled_variants parameter to be a value from the URL query parameter, e.g. vars:

[...]
"vod": {
  "robot": "/video/ondemand",
  "use": "import",
  "variants": {
    [...]
  },
  "enabled_variants": "${fields.vars}"
},
[...]

When you then sign a URL to be delivered to the viewer, you can set the vars URL query parameter to a comma-separated string of the variant names that are enabled for the viewer, e.g. vars=480p,720p. A signed URL might then look like this:

https://my-workspace.tlcdn.com/my-template/my-video.mp4?exp=1741681323604&vars=480p,720p&sig=sha256:d65165279105ca6773180500688df4bdc69a2c7b771752f0a46ef120b7fd8ec3

This will allow the player to only discover and load the 480p and 720p variants, while other variants (such as 1080p) will not be available. Since the URL query parameter is protected against tampering through signed URLs, the viewer will not be able to gain access to non-enabled variants by modifying the vars parameter.

Watermarking

This Robot supports watermarking. To add a watermark to a video, you need to import the watermark image in a separate Step and then use it in the /video/ondemand Step. For example:

{
  "steps": {
    "video-import": {
      "robot": "/s3/import",
      "path": "${fields.input}",
      "credentials": "YOUR_AWS_CREDENTIALS",
      "return_file_stubs": true
    },
    "watermark-import": {
      "robot": "/http/import",
      "path": "https://example.com/watermark.png"
    },
    "vod": {
      "robot": "/video/ondemand",
      "use": {
        "steps": [
          { "name": "video-import", "as": "video" },
          { "name": "watermark-import", "as": "watermark" }
        ]
      },
      "variants": {
        "720p": {
          "preset": "hls/720p",
          "ffmpeg_stack": "v6.0.0",
          "watermark_size": "50%",
          "watermark_position": "bottom-right"
        },
        "1080p": {
          "preset": "hls/1080p",
          "ffmpeg_stack": "v6.0.0",
          "watermark_size": "50%",
          "watermark_position": "bottom-right"
        }
      }
    },
    "serve": {
      "use": "vod",
      "robot": "/file/serve"
    }
  }
}

Please notice how in the example above, the watermark is imported in the watermark-import step via the /http/import Robot, although you can use any other import Robots. The watermark import step is then referenced in the vod using the advanced as syntax, so that /video/ondemand recognizes the file as the watermark image. Finally, the variants in the vod can then use instructions like watermark_size and watermark_position to specify how the watermark should be added to the video. Any of the watermark parameters supported by the /video/encode Robot can be used.

Usage example

Enable streaming of a video stored on S3 in three variants (480p, 720p, 1080p) with on-demand encoding:

{
  "steps": {
    "import": {
      "robot": "/s3/import",
      "path": "${fields.input}",
      "credentials": "YOUR_AWS_CREDENTIALS",
      "return_file_stubs": true
    },
    "vod": {
      "robot": "/video/ondemand",
      "use": "import",
      "variants": {
        "480p": {
          "preset": "hls/480p",
          "ffmpeg_stack": "v6.0.0"
        },
        "720p": {
          "preset": "hls/720p",
          "ffmpeg_stack": "v6.0.0"
        },
        "1080p": {
          "preset": "hls/1080p",
          "ffmpeg_stack": "v6.0.0"
        }
      }
    },
    "serve": {
      "use": "vod",
      "robot": "/file/serve"
    }
  }
}

Parameters

  • use

    String / Array of Strings / Object required

    Specifies which Step(s) to use as input.

    • You can pick any names for Steps except ":original" (reserved for user uploads handled by Transloadit)

    • You can provide several Steps as input with arrays:

      "use": [
        ":original",
        "encoded",
        "resized"
      ]
      

    πŸ’‘ That’s likely all you need to know about use, but you can view Advanced use cases.

  • variants

    Objectrequired

    Defines the variants the video player can choose from.

    The keys are the names of the variant as they will appear in the generated playlists and URLs. The values are objects defining the settings for each variant. They must contain at least:

    • the preset parameter, specifying an HLS-enabled video preset (e.g.,"hls/480p").
    • the ffmpeg_stack parameter, specifying the FFmpeg stack to use for this variant. We currently recommend using "v6.0.0".

    The variant definition can include additional parameters from πŸ€–/video/encode, such as resize_strategy for different resize strategies, the watermark_* parameters for adding a watermark to the video, and ffmpeg for adding custom FFmpeg parameters.

  • enabled_variants

    String / Array of Strings β‹… default: null

    Specifies which variants, defined in the variants parameter, are enabled. Non-enabled variants will not be included in the master playlist, and their variant playlists or segments will not be generated. This is useful to restrict the access of certain variants to authorized users in combination with signed URLs. See the Access control through signed URLs section for more information.

    If this parameter is not set (the default), all variants defined in the variants parameter are enabled. The value can be an array of strings, each containing the key of a variant defined in the variants parameter. Alternatively, variant names can be provided as a comma-separated string β€” useful when the value is passed via a URL query parameter.

  • segment_duration

    Integer β‹… default: 6

    The duration of each segment in seconds.

  • sign_urls_for

    Integer β‹… default: 0

    When signing URLs is enabled, the URLs in the generated playlist files will be signed as described in Smart CDN Signatures. This parameter specifies the duration (in seconds) that the signed URLs will remain valid.

    Enabling signed URLs is necessary if signatures are required for all Assemblies in a Workspace (see Signature Authentication) or for the corresponding Template that uses πŸ€–/video/ondemand (see the require_signature_auth parameter).

    If this parameter is set to 0, the URLs will not be signed.

  • asset

    String β‹… default: null

    Controls which file is generated. For example, if the parameter is unset, a master playlist referencing the variants is generated. If the value takes the form of {variant}/playlist.m3u8 or {variant}/seg__{num}.ts, a variant playlist or segment is generated, respectively. The values that are recognized by πŸ€–/video/ondemand may change over time as new features are added, so users should avoid relying on exact values.

    By default, the parameter value is taken from the Assembly field identified by the asset_param_name parameter. When the Smart CDN is used, Assembly fields are populated from URL query parameters, and the value is taken from the query parameter matching the key specified in asset_param_name. This means there is usually no need to explicitly set the asset parameter in your Templates.

  • asset_param_name

    String β‹… default: "asset"

    Specifies from which URL parameter the asset parameter value is taken and which URL parameter to use when generating playlist files. By default, the requested file is taken from the asset URL parameter. If you want to use the asset URL query parameter for other purposed in your Assembly, you can use the asset_param_name to use another URL query parameter for πŸ€–/video/ondemand. Otherwise, there is no need to set this parameter.