Skip to content

Vertical video from landscape sources

After this recipe you can turn 16:9 footage into a 9:16 video for phones, either by showing the whole picture over a blurred copy of itself or by cropping it to fill the frame and panning across it.

The output size is the project’s settings. For 1080×1920 at 30 fps:

"settings": {
"width": 1080,
"height": 1920,
"frame_rate": { "num": 30, "den": 1 },
"sample_rate": 48000
}

Nothing else in the project names pixels: positions are fractions of the canvas, and lengths are fractions of its shorter side. The same document renders at 720×1280 if you change only width and height.

A clip with the default visual (scale 1) shows its source contained in the canvas: as large as it can be while the whole source stays visible, centred. A 1920×1080 source on a 1080×1920 canvas is drawn 1080 pixels wide and 607.5 tall, with empty space above and below.

To cover the canvas instead, scale it by the source’s aspect ratio divided by the canvas’s (for a source wider than the canvas). For a 16:9 source on a 9:16 canvas that is (16/9) ÷ (9/16) = (16/9)² ≈ 3.1605. The picture is then 1920 pixels tall and about 3413 wide, and the sides are cut off.

Source Canvas Scale to cover
16:9 9:16 3.1605
16:9 1:1 1.7778
16:9 4:5 2.2222

Two tracks show the same source. The lower one covers the canvas, blurred and darkened by a composition. The upper one shows the whole picture, contained.

{
"schema_version": 1,
"id": "vertical",
"name": "Vertical from landscape",
"settings": {
"width": 1080,
"height": 1920,
"frame_rate": {
"num": 30,
"den": 1
},
"sample_rate": 48000
},
"sources": [
{
"id": "coast",
"locator": "asset://coast",
"kind": "image"
}
],
"compositions": [
{
"id": "backdrop",
"output": "darker",
"nodes": [
{
"id": "clip",
"op": {
"type": "clip"
}
},
{
"id": "blur",
"op": {
"type": "effect",
"input": "clip",
"effect": {
"id": "alpha2.effect.gaussian-blur",
"version": 1,
"params": {
"radius": {
"mode": "constant",
"value": {
"type": "float",
"value": 0.03
}
}
}
}
}
},
{
"id": "darker",
"op": {
"type": "effect",
"input": "blur",
"effect": {
"id": "alpha2.effect.color-controls",
"version": 1,
"params": {
"exposure": {
"mode": "constant",
"value": {
"type": "float",
"value": -1
}
}
}
}
}
}
]
}
],
"timeline": {
"tracks": [
{
"id": "back",
"name": "Blurred fill",
"kind": "video",
"clips": [
{
"id": "fill",
"source_id": "coast",
"timeline_range": {
"start": 0,
"end": 480000
},
"source_range": {
"start": 0,
"end": 480000
},
"visual": {
"scale": {
"mode": "constant",
"value": {
"x": 3.1605,
"y": 3.1605
}
}
},
"composition": {
"id": "backdrop"
}
}
],
"transitions": []
},
{
"id": "front",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "picture",
"source_id": "coast",
"timeline_range": {
"start": 0,
"end": 480000
},
"source_range": {
"start": 0,
"end": 480000
}
}
],
"transitions": []
}
]
}
}

The backdrop composition runs the clip through alpha2.effect.gaussian-blur and then alpha2.effect.color-controls with exposure −1. The composition builds the clip’s picture, and the clip’s visual.scale then enlarges the result to cover the canvas. Both clips read the same source, so with a video both show the same frame.

To fill the frame with the picture, keep only the covering clip and move it. position is where the source’s centre (its default anchor) lands on the canvas. At scale 3.1605 the picture is about 3.16 canvas widths wide, so its centre can move between about −0.58 and 1.58 before an edge shows. Keying position.x from 1.2 to −0.2 pans from the left part of the picture to the right part over four seconds.

{
"schema_version": 1,
"id": "vertical-pan",
"name": "Vertical crop and pan",
"settings": {
"width": 1080,
"height": 1920,
"frame_rate": {
"num": 30,
"den": 1
},
"sample_rate": 48000
},
"sources": [
{
"id": "coast",
"locator": "asset://coast",
"kind": "image"
}
],
"timeline": {
"tracks": [
{
"id": "picture",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "picture",
"source_id": "coast",
"timeline_range": {
"start": 0,
"end": 480000
},
"source_range": {
"start": 0,
"end": 480000
},
"visual": {
"scale": {
"mode": "constant",
"value": {
"x": 3.1605,
"y": 3.1605
}
},
"position": {
"mode": "keyframes",
"keyframes": [
{
"time": 0,
"value": {
"x": 1.2,
"y": 0.5
},
"interpolation": {
"type": "cubic_bezier",
"x1": 0.65,
"y1": 0,
"x2": 0.35,
"y2": 1
}
},
{
"time": 480000,
"value": {
"x": -0.2,
"y": 0.5
},
"interpolation": {
"type": "hold"
}
}
]
}
}
}
],
"transitions": []
}
]
}
}
Terminal window
alpha2-host export --project vertical.json \
--asset coast=coast.jpg \
--out vertical.mp4