# Handling Portrait vs. Landscape Source Videos in video-use: A Complete Guide

> video-use automatically handles portrait vs landscape videos with ffprobe and FFmpeg scaling. Preserve aspect ratios during segment extraction. Learn how.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: how-to-guide
- Published: 2026-07-07

---

**`video-use` detects video orientation using `ffprobe` and applies orientation-specific FFmpeg scaling filters during the segment extraction phase, ensuring portrait videos scale by height while landscape videos scale by width to preserve native aspect ratios.**

The `browser-use/video-use` repository provides a Python-based rendering pipeline that automatically adapts to mixed-orientation source material. When processing an editing decision list (EDL) containing both vertical mobile footage and traditional horizontal clips, the library distinguishes between portrait and landscape sources to prevent distortion and black bars in the final output.

## Orientation Detection with ffprobe

The pipeline determines orientation before any scaling occurs. In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), the `is_portrait_source()` function executes `ffprobe` to analyze the source video dimensions.

```python
from pathlib import Path
from helpers.render import is_portrait_source

video = Path("example_portrait.mp4")
print(is_portrait_source(video))   # → True

```

This helper returns `True` when **height > width**, identifying the clip as portrait orientation. According to the source code at lines 134-136, this boolean flag propagates through the rendering logic to dictate subsequent filter parameters.

## Conditional Scaling Logic in extract_segment()

The core differentiation happens inside `extract_segment()` where the orientation flag directs FFmpeg's scaling behavior. The `video-use` library constructs filter graphs dynamically based on the `portrait` boolean value.

### Draft Builds (Fast, Low-Resolution)

For quick previews, the system applies a 1280-pixel constraint:

- **Portrait sources** receive `scale=-2:1280` (fixed height of 1280 pixels, width calculated automatically)
- **Landscape sources** receive `scale=1280:-2` (fixed width of 1280 pixels, height calculated automatically)

This logic appears at lines 173-176 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py).

### Final and Draft-Preview Builds (1080p Output)

For production-quality output, the constraints increase to 1920 pixels:

- **Portrait sources** use `scale=-2:1920` (fixed height of 1920 pixels)
- **Landscape sources** use `scale=1920:-2` (fixed width of 1920 pixels)

These filters appear at lines 177-178 in the same file.

The **`-2` placeholder** instructs FFmpeg to maintain the original aspect ratio while enforcing the dominant dimension, ensuring that vertical videos intended for TikTok or Instagram Reels retain their 9:16 format without stretching.

## Impact on the Rendering Pipeline

The orientation check executes **once per source** at line 173, and the resulting scale filter concatenates with optional HDR tone-mapping and grading filters. This design means every segment inherits the correct orientation-aware scaling without manual intervention.

To render an EDL containing mixed orientations:

```bash

# Basic render – auto-detects portrait vs. landscape

python helpers/render.py my_edl.json -o final.mp4

# Draft (fast) render – uses 1280-pixel scaling rules

python helpers/render.py my_edl.json -o draft.mp4 --draft

```

For portrait-specific workflows, you can leverage the preview flag:

```bash
python helpers/render.py edl_portrait.json -o portrait.mp4 \
    --preview   # uses 1920-pixel height scaling for portrait sources

```

## Summary

- **Orientation detection** occurs via `is_portrait_source()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), which uses `ffprobe` to compare height and width dimensions.
- **Scaling filters** are conditionally applied in `extract_segment()` based on the orientation flag, with draft builds targeting 1280px and final builds targeting 1920px on the dominant axis.
- **Aspect ratio preservation** relies on FFmpeg's `-2` placeholder to calculate the secondary dimension automatically.
- **Pipeline efficiency** is maintained by checking orientation once per source and applying it to all extracted segments uniformly.

## Frequently Asked Questions

### How does video-use detect if a video is portrait or landscape?

The library calls `ffprobe` through the `is_portrait_source()` helper function in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py). This function returns `True` when the video's height exceeds its width, identifying the clip as portrait orientation before any processing begins.

### What happens if I mix portrait and landscape videos in the same EDL?

The rendering pipeline handles each source independently. When `extract_segment()` processes each clip, it checks the orientation flag and applies the appropriate `scale` filter—either fixing the height for portrait sources or the width for landscape sources—ensuring all clips maintain their native aspect ratios in the final composition.

### Why does video-use use -2 in the FFmpeg scale filters?

The `-2` value tells FFmpeg to automatically calculate the secondary dimension while preserving the aspect ratio. For example, `scale=-2:1920` fixes the height at 1920 pixels and computes the width proportionally, preventing distortion that would occur with fixed-width scaling on vertical videos.

### Can I force portrait scaling for all videos regardless of source orientation?

While the library automatically detects orientation, you would need to modify the `extract_segment()` function in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) to override the `portrait` flag or manually specify the scale filter. The default behavior requires no manual configuration and adjusts per-source based on the `ffprobe` analysis.