VIDEO_CONCAT_UNMATCHING_DIMENSIONS - but they match!

Hey Transloadit community! Sorry to bug y’all, but I got an “VIDEO_CONCAT_UNMATCHING_DIMENSIONS” error.

Background: Have a template that makes videos of matching dimensions. Have a template that is supposed to concat those videos together… and has worked in previous tests.

I understand you could force matching dimensions, but the error is surprising since each of the 10 videos is made with the same template with the same dimension specs… any clue what may be going on?

Hi, can you share you template instructions and a assembly ID where the error happened?

Hey there,

It could be that one of your videos has a different aspect ratio. Imagine 9 videos in landscape and one in portrait. The /video/encode robot set up with some resolutions will then produce videos maintaining their aspect ratio if resize_strategy: „fit“ is used (the default resize strategy).

We‘ll implement smart encoding inside the concat robot so that these case will „just work“ as well.

In the meantime you could switch your /video/encode step to resize_strategy „pad“. That will fix the issue and cause black bars around the portrait video to match the landscape resolution.

@tim-kos1

Hey Merlijn & Tim,

Tim - We aren’t using /video/encode in the concat template, just concat.

This is the setup, we have 10 audio urls and 10 image urls, each processed with the following template. It is beyond perplexing because even the sources of audio/images are templated respectively from Suno + Leonardo to be consistent.

To combine audio + image to create video of 1920x1080 dimension:

{
  "steps": {
    "imported_image": {
      "robot": "/http/import",
      "url": "${fields.image_url}"
    },
    "imported_audio": {
      "robot": "/http/import",
      "url": "${fields.audio_url}"
    },
    "resized_image": {
      "robot": "/image/resize",
      "use": "imported_image",
      "result": true,
      "width": 1920,
      "height": 1080,
      "resize_strategy": "fillcrop",
      "imagemagick_stack": "v3.0.1",
      "gravity": "center",
      "strip": true
    },
    "merged": {
      "robot": "/video/merge",
      "use": {
        "steps": [
          {
            "name": "imported_audio",
            "as": "audio"
          },
          {
            "name": "resized_image",
            "as": "image"
          }
        ]
      },
      "preset": "ipad-high",
      "result": true,
      "ffmpeg_stack": "v6.0.0",
      "width": 1920,
      "height": 1080,
      "ffmpeg": {
        "f": "mp4",
        "codec:v": "libx264",
        "codec:a": "aac",
        "map_metadata": "-1"
      }
    },
    "exported": {
      "robot": "/google/store",
      "use": "merged",
      "credentials": "<creds>",
      "path": "<path>/${file.url_name}"
    }
  },
  "notify_url": "<our url here>"
}

The above template is ran 10 times to create 10 individual videos.

We then take those 10 videos and run it through this template to try and concat (link them together):

{
  "steps": {
    "import1": {
      "robot": "/http/import",
      "url": [
        "${fields.video_1_url}"
      ]
    },
    "import2": {
      "robot": "/http/import",
      "url": [
        "${fields.video_2_url}"
      ]
    },
    "import3": {
      "robot": "/http/import",
      "url": [
        "${fields.video_3_url}"
      ]
    },
    "import4": {
      "robot": "/http/import",
      "url": [
        "${fields.video_4_url}"
      ]
    },
    "import5": {
      "robot": "/http/import",
      "url": [
        "${fields.video_5_url}"
      ]
    },
    "import6": {
      "robot": "/http/import",
      "url": [
        "${fields.video_6_url}"
      ]
    },
    "import7": {
      "robot": "/http/import",
      "url": [
        "${fields.video_7_url}"
      ]
    },
    "import8": {
      "robot": "/http/import",
      "url": [
        "${fields.video_8_url}"
      ]
    },
    "import9": {
      "robot": "/http/import",
      "url": [
        "${fields.video_9_url}"
      ]
    },
    "import10": {
      "robot": "/http/import",
      "url": [
        "${fields.video_10_url}"
      ]
    },
    "concat_videos": {
      "robot": "/video/concat",
      "use": {
        "steps": [
          {
            "name": "import1",
            "as": "video_1"
          },
          {
            "name": "import2",
            "as": "video_2"
          },
          {
            "name": "import3",
            "as": "video_3"
          },
          {
            "name": "import4",
            "as": "video_4"
          },
          {
            "name": "import5",
            "as": "video_5"
          },
          {
            "name": "import6",
            "as": "video_6"
          },
          {
            "name": "import7",
            "as": "video_7"
          },
          {
            "name": "import8",
            "as": "video_8"
          },
          {
            "name": "import9",
            "as": "video_9"
          },
          {
            "name": "import10",
            "as": "video_10"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "empty",
      "ffmpeg": {
        "f": "${video_1.ext}"
      },
      "video_fade_seconds": 3,
      "audio_fade_seconds": 3,
      "result": true
    },
    "exported": {
      "robot": "/google/store",
      "use": "concat_videos",
      "credentials": "<creds>",
      "path": "<path>"
    }
  },
  "notify_url": "<server url>",
  "allow_steps_override": true
}

OK, I used the template below (thanks o3) to force encoding. But my question is, how would I get my 1st template I shared (the one that creates the individual videos by merging audio + image) to consistently output a format that will not force me to do the extra encoding steps below? I’ll just be forcing my client to pay a bunch of extra data for something that should have been processed correctly in the previous step :slight_smile:

Truly appreciate your time y’all!

@Merlijn @tim-kos1


{
  "steps": {
    "import1": {
      "robot": "/http/import",
      "url": ["${fields.video_1_url}"]
    },
    "import2": {
      "robot": "/http/import",
      "url": ["${fields.video_2_url}"]
    },
    "import3": {
      "robot": "/http/import",
      "url": ["${fields.video_3_url}"]
    },
    "import4": {
      "robot": "/http/import",
      "url": ["${fields.video_4_url}"]
    },
    "import5": {
      "robot": "/http/import",
      "url": ["${fields.video_5_url}"]
    },
    "import6": {
      "robot": "/http/import",
      "url": ["${fields.video_6_url}"]
    },
    "import7": {
      "robot": "/http/import",
      "url": ["${fields.video_7_url}"]
    },
    "import8": {
      "robot": "/http/import",
      "url": ["${fields.video_8_url}"]
    },
    "import9": {
      "robot": "/http/import",
      "url": ["${fields.video_9_url}"]
    },
    "import10": {
      "robot": "/http/import",
      "url": ["${fields.video_10_url}"]
    },
    "encode1": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import1",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode2": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import2",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode3": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import3",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode4": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import4",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode5": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import5",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode6": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import6",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode7": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import7",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode8": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import8",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode9": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import9",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "encode10": {
      "robot": "/video/encode",
      "use": {
        "steps": [
          {
            "name": "import10",
            "as": "video"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "web/mp4/1080p",
      "resize_strategy": "pad",
      "width": 1920,
      "height": 1080
    },
    "concat_videos": {
      "robot": "/video/concat",
      "use": {
        "steps": [
          {
            "name": "encode1",
            "as": "video_1"
          },
          {
            "name": "encode2",
            "as": "video_2"
          },
          {
            "name": "encode3",
            "as": "video_3"
          },
          {
            "name": "encode4",
            "as": "video_4"
          },
          {
            "name": "encode5",
            "as": "video_5"
          },
          {
            "name": "encode6",
            "as": "video_6"
          },
          {
            "name": "encode7",
            "as": "video_7"
          },
          {
            "name": "encode8",
            "as": "video_8"
          },
          {
            "name": "encode9",
            "as": "video_9"
          },
          {
            "name": "encode10",
            "as": "video_10"
          }
        ]
      },
      "ffmpeg_stack": "v6.0.0",
      "preset": "empty",
      "ffmpeg": {
        "f": "mp4",
        "c:v": "libx264",
        "c:a": "aac",
        "movflags": "+faststart"
      },
      "video_fade_seconds": 3,
      "audio_fade_seconds": 3,
      "result": true
    },
    "exported": {
      "robot": "/google/store",
      "use": "concat_videos",
      "credentials": "<variables>",
      "path": "<variables>"
    }
  },
  "notify_url": "<variables>",
  "allow_steps_override": true
}
````Preformatted text`

I am -REALLY- happy nobody got to this before I dug deeper.

It seems the issue was that I had a filler video url as the variable for import that was supposed to be over-written with the correctly transloadit-modified video.

Well because of the queue, sometimes the job of creating those individual video URLs needed for concatenate was taking long enough that it would start the Concat job before they finished!

Hopefully the issue is resolved, thanks so much y’all for the time.

This was on my todo for today so you saved me some time there :slight_smile: I appreciate you letting us know!!

1 Like

Enjoy!! I truly think I over-complicated both templates terribly because I was trying to compensate for dimension issues when the real issue was timing of my solution :slight_smile: