Flag of Ukraine

Transcode, resize, or watermark videos

The /video/encode Robot encodes, resizes, applies watermarks to videos and animated GIFs.

On watermarking

With watermarking you can add an image to a video. This is usually used for logos, but you could also Surround a video with a frame if you cut out a transparent center from your image.

Supplying the watermark via an Assembly Step

You can also also pass both the video and the watermark image to an Assembly Step via the use parameter, allowing you to have both be part of the upload, or to use the results of other Assembly Steps as input to your /video/encode Step.

For this to work, you just need to use the as-syntax:

"my_video_step": {
  "bundle_steps": true,
  "robot": "/video/encode",
  "use": {
    "steps": [
      { "name": ":original", "as": "video" },
      { "name": ":original", "as": "watermark" }
    ]
  }
}

Here both the video and the watermark image are taken from the uploaded files. They are recognized automatically based on their file type.

If you use several file input fields, then you can tell Transloadit which field supplies the base video and which the watermark. Suppose you have two file input fields named the_video and the_watermark. These Assembly Instructions will make it work using the fields condition:

"my_video_step": {
  "bundle_steps": true,
  "robot": "/video/encode",
  "use": {
    "steps": [
      { "name": ":original", "fields": "the_video", "as": "video" },
      { "name": ":original", "fields": "the_watermark", "as": "watermark" }
    ]
  }
}

Please note that the Robot's watermark_url parameter will still continue to work.

Parameters

  • use

    String / Array of Strings / Objectrequired

    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:

    › Advanced use cases
    • Step bundling. Some Robots can gather several Step results for a single invocation. For example, the /file/compress Robot would normally create one archive for each file passed to it. If you'd set bundle_steps to true, however, it will create one archive containing all the result files from all Steps you give it. To enable bundling, provide an object like the one below to the use parameter:

      "use": {
        "steps": [
          ":original",
          "encoded",
          "resized"
        ],
        "bundle_steps": true
      }
      

      This is also a crucial parameter for the /video/adaptive Robot, otherwise you'll generate 1 playlist for each viewing quality.
      Keep in mind that all input Steps must be present in your Template. If one of them is missing (for instance it is rejected by a filter), no result is generated because the Robot waits indefinitely for all input Steps to be finished.

      Here’s a demo that showcases Step bundling.

    • Group by original. Sticking with the /file/compress Robot example, you can set group_by_original to true, in order to create a separate archive for each of your uploaded or imported files, instead of creating one archive containing all originals (or one per resulting file). This is important for for the /media/playlist Robot where you'd typically set:

      "use": {
        "steps": [
          "segmented"
        ],
        "bundle_steps": true,
        "group_by_original": true
      }
      
    • Fields. You can be more discriminatory by only using files that match a field name by setting the fields property. When this array is specified, the corresponding Step will only be executed for files submitted through one of the given field names, which correspond with the strings in the name attribute of the HTML file input field tag for instance. When using a back-end SDK, it corresponds with myFieldName1 in e.g.: $transloadit->addFile('myFieldName1', './chameleon.jpg').

      This parameter is set to true by default, meaning all fields are accepted.

      Example:

      "use": {
        "steps": [ ":original" ],
        "fields": [ "myFieldName1" ]
      }
      
    • Use as. Sometimes Robots take several inputs. For instance, the /video/merge Robot can create a slideshow from audio and images. You can map different Steps to the appropriate inputs.

      Example:

      "use": {
        "steps": [
          { "name": "audio_encoded", "as": "audio" },
          { "name": "images_resized", "as": "image" }
        ]
      }
      

      Sometimes the ordering is important, for instance, with our concat Robots. In these cases, you can add an index that starts at 1. You can also optionally filter by the multipart field name. Like in this example, where all files are coming from the same source (end-user uploads), but with different <input> names:

      Example:

      "use": {
        "steps": [
          { "name": ":original", "fields": "myFirstVideo", "as": "video_1" },
          { "name": ":original", "fields": "mySecondVideo", "as": "video_2" },
          { "name": ":original", "fields": "myThirdVideo", "as": "video_3" }
        ]
      }
      

      For times when it is not apparent where we should put the file, you can use Assembly Variables to be specific. For instance, you may want to pass a text file to the /image/resize Robot to burn the text in an image, but you are burning multiple texts, so where do we put the text file? We specify it via ${use.text_1}, to indicate the first text file that was passed.

      Example:

      "watermarked": {
        "robot": "/image/resize",
        "use"  : {
          "steps": [
            { "name": "resized", "as": "base" },
            { "name": "transcribed", "as": "text" },
          ],
        },
        "text": [
          {
            "text"  : "Hi there",
            "valign": "top",
            "align" : "left",
          },
          {
            "text"    : "From the 'transcribed' Step: ${use.text_1}",
            "valign"  : "bottom",
            "align"   : "right",
            "x_offset": 16,
            "y_offset": -10,
          }
        ]
      }
      
  • preset

    String ⋅ default: "flash"

    Converts a video according to pre-configured settings.

    If you specify your own FFmpeg parameters using the Robot's and/or do not not want Transloadit to set any encoding setting, starting ffmpeg_stack: "v3.3.3", you can use the value 'empty' here.

  • width

    Integer(1-1920) ⋅ default: Width of the input video

    Width of the new video, in pixels.

    If the value is not specified and the preset parameter is available, the preset's supplied width will be implemented.

  • height

    Integer(1-1080) ⋅ default: Height of the input video

    Height of the new video, in pixels.

    If the value is not specified and the preset parameter is available, the preset's supplied height will be implemented.

  • resize_strategy

    String ⋅ default: "pad"
  • zoom

    Boolean ⋅ default: true

    If this is set to false, smaller videos will not be stretched to the desired width and height. For details about the impact of zooming for your preferred resize strategy, see the list of available resize strategies.

  • crop

    Object / JSON String ⋅ default: null

    Specify an object containing coordinates for the top left and bottom right corners of the rectangle to be cropped from the original video(s). Values can be integers for absolute pixel values or strings for percentage based values.

    For example:

    
    {
      "x1": 80,
      "y1": 100,
      "x2": "60%",
      "y2": "80%"
    }
    
    

    This will crop the area from (80, 100) to (600, 800) from a 1000×1000 pixels video, which is a square whose width is 520px and height is 700px. If crop is set, the width and height parameters are ignored, and the resize_strategy is set to crop automatically.

    You can also use a JSON string of such an object with coordinates in similar fashion: "{ \"x1\": <Integer>, \"y1\": <Integer>, \"x2\": <Integer>, \"y2\": <Integer> }"

  • background

    String ⋅ default: "00000000"

    The background color of the resulting video the "rrggbbaa" format (red, green, blue, alpha) when used with the "pad" resize strategy. The default color is black.

  • rotate

    Integer(0, 90, 180, 270, 360) / Boolean ⋅ default: auto[?]

    Forces the video to be rotated by the specified degree integer. Currently, only multiples of 90 are supported. We automatically correct the orientation of many videos when the orientation is provided by the camera. This option is only useful for videos requiring rotation because it was not detected by the camera. If you set rotate to false no rotation is performed, even if the metadata contains such instructions.

  • hint

    Boolean ⋅ default: false

    Enables hinting for mp4 files, for RTP/RTSP streaming.

  • turbo

    Boolean ⋅ default: false

    Splits the video into multiple chunks so that each chunk can be encoded in parallel before all encoded chunks are stitched back together to form the result video. This comes at the expense of extra Priority Job Slots and may prove to be counter-productive for very small video files.

  • chunk_duration

    Integer ⋅ default: auto[?]

    Allows you to specify the duration of each chunk when turbo is set to true. This means you can take advantage of that feature while using fewer Priority Job Slots. For instance, the longer each chunk is, the fewer Encoding Jobs will need to be used.

FFmpeg parameters

  • ffmpeg_stack

    String ⋅ default: "v3.3.3"

    Selects the FFmpeg stack version to use for encoding. These versions reflect real FFmpeg versions.

    The current recommendation is to use "v4.3.1". Other valid values can be found here.

  • ffmpeg

    Object ⋅ default: {}

    A parameter object to be passed to FFmpeg. For available options, see the FFmpeg documentation. If a preset is used, the options specified are merged on top of the ones from the preset.

    The FFmpeg r parameter (framerate) has a default value of 25 and maximum value of 60.

    If you set r to null, you clear the default of 25 and can preserve the original video's framerate. For example:

    
    "steps": {
      "video_encode": {
        "robot": "/video/encode",
        "use": ":original",
        "ffmpeg_stack": "v4.3.1",
        "preset": "web/mp4/1080p",
        "ffmpeg": {
          "b:v": "600k"
        }
      }
    }
    
    

    You can also add input_options which will be used before the -i in ffmpeg. For example in the following case, the final command will look like ffmpeg -fflags +genpts -i input_video ...:

    
    "steps": {
      "video_encode": {
        "robot": "/video/encode",
        "use": ":original",
        "ffmpeg_stack": "v4.3.1",
        "preset": "web/mp4/1080p",
        "ffmpeg": {
          "input_options": {
            "fflags": "+genpts"
          },
          "b:v": "600k"
        }
      }
    }
    
    

Watermarking parameters

  • watermark_url

    String ⋅ default: ""

    A URL indicating a PNG image to be overlaid above this image. Please note that you can also supply the watermark via another Assembly Step.

  • watermark_position

    String / Array of Strings ⋅ default: "center"

    The position at which the watermark is placed. The available options are "center", "top", "bottom", "left", and "right". You can also combine options, such as "bottom-right".

    An array of possible values can also be specified, in which case one value will be selected at random, such as [ "center", "left", "bottom-left", "bottom-right" ].

    This setting puts the watermark in the specified corner. To use a specific pixel offset for the watermark, you will need to add the padding to the image itself.

  • watermark_x_offset

    Integer ⋅ default: 0

    The x-offset in number of pixels at which the watermark will be placed in relation to the position it has due to watermark_position.

    Values can be both positive and negative and yield different results depending on the watermark_position parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point.

  • watermark_y_offset

    Integer ⋅ default: 0

    The y-offset in number of pixels at which the watermark will be placed in relation to the position it has due to watermark_position.

    Values can be both positive and negative and yield different results depending on the watermark_position parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point.

  • watermark_size

    String ⋅ default: ""

    The size of the watermark, as a percentage, such as "50%". How the watermark is resized greatly depends on the watermark_resize_strategy.

  • watermark_resize_strategy

    String ⋅ default: "fit"

    Available values are "fit", "stretch" and "area".

    To explain how the resize strategies work, let's assume our target video size is 800×800 pixels and our watermark image is 400×300 pixels. Let's also assume, the watermark_size parameter is set to "25%".

    For the "fit" resize strategy, the watermark is scaled so that the longer side of the watermark takes up 25% of the corresponding video side. And the other side is scaled according to the aspect ratio of the watermark image. So with our watermark, the width is the longer side, and 25% of the video size would be 200px. Hence, the watermark would be resized to 200×150 pixels. If the watermark_size was set to "50%"", it would be resized to 400×300 pixels (so just left at its original size).

    For the "stretch" resize strategy, the watermark image is stretched (meaning, it is resized without keeping its aspect ratio in mind) so that both sides take up 25% of the corresponding video side. Since our video is 800×800 pixels, for a watermark size of 25% the watermark would be resized to 200×200 pixels. Its height would appear stretched, because keeping the aspect ratio in mind it would be resized to 200×150 pixels instead.

    For the "area" resize strategy, the watermark is resized (keeping its aspect ratio in check) so that it covers "xx%" of the video's surface area. The value from watermark_size is used for the percentage area size.

  • watermark_start_time

    Float ⋅ default: 0.0

    The delay in seconds from the start of the video for the watermark to appear. By default the watermark is immediately shown.

  • watermark_duration

    Float ⋅ default: -1.0

    The duration in seconds for the watermark to be shown. Can be used together with watermark_start_time to create nice effects. The default value is -1.0, which means that the watermark is shown for the entire duration of the video.

  • watermark_opacity

    Float ⋅ default: 1.0

    The opacity of the watermark. Valid values are between 0 (invisible) and 1.0 (full visibility).

HLS Parameters

This Robot used to support HLS parameters, but we now recommend using our specialized /video/adaptive Robot instead.

Demos

Related blog posts

Uppy
20% off any plan for the Uppy community
Use the UPPY20 code when upgrading.
Sign up
tus
20% off any plan for the tus community
Use the TUS20 code when upgrading.
Sign up
Product Hunt
20% off any plan for Product Hunters
Use the PRH20 code when upgrading.
Sign up