---
title: "Get video rotation in C#"
url: https://recursiveai.org/onemedia/cookbook/get-video-rotation/
description: "Find out whether a phone video is portrait or landscape in C#: read the MP4 or MOV rotation (0, 90, 180 or 270 degrees) and the display width and height, without decoding."
version: "0.1.0-preview.1"
---

# Get video rotation in C#

A phone records portrait video as landscape frames plus a rotation that tells the player to turn them. `media.Rotation` reads that rotation from the MP4 or MOV track header as 0, 90, 180 or 270 degrees clockwise, and the frame-size fact gives the width and height as displayed. To have a rotated file you can share, the setup line below makes one from MDN’s CC0 flower clip with FFmpeg (6.0 or later), the way a phone held upright marks its video: the same frames, a 90° display matrix.

```shell
dotnet new console -o Rotation && cd Rotation
dotnet add package RecursiveAI.OneMedia --version 0.1.0-preview.1
curl -L -o flower.mp4 https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4
ffmpeg -v error -display_rotation -90 -i flower.mp4 -c copy portrait.mp4
```

Put this in `Program.cs` and run `dotnet run`:

```csharp
using RecursiveAI.OneMedia;
using RecursiveAI.OneMedia.Metadata;

foreach (string path in new[] { "flower.mp4", "portrait.mp4" })
{
    using MediaFile media = Media.Open(path);

    // Clockwise degrees to turn the picture for display, and a mirror flag.
    VideoOrientation turn = media.Rotation.Value;
    FrameSize size = media.Metadata.Facts.FrameSize.Value;

    string shape = size.DisplayHeight > size.DisplayWidth ? "portrait" : "landscape";
    Console.WriteLine($"{path}: rotate {turn.RotationDegrees}° clockwise" +
                      $"{(turn.MirrorHorizontal ? ", mirrored" : "")}");
    Console.WriteLine($"  stored {size.CodedWidth}x{size.CodedHeight}," +
                      $" shown {size.DisplayWidth}x{size.DisplayHeight} ({shape})");
    Console.WriteLine($"  from {media.Rotation.Best?.Source}" +
                      $" {media.Rotation.Best?.RawValue}");
}
```

```text
flower.mp4: rotate 0° clockwise
  stored 960x540, shown 960x540 (landscape)
  from tkhd.matrix [00010000 00000000 00000000 00010000]
portrait.mp4: rotate 90° clockwise
  stored 960x540, shown 540x960 (portrait)
  from tkhd.matrix [00000000 00010000 FFFF0000 00000000]
```

The rotation comes from the matrix in the first video track’s header (`tkhd`): its four unit entries are a rotation by a multiple of 90°, possibly mirrored. `RawValue` shows them as stored. The same number is on the track as `media.Video.Video.RotationDegrees`, and the `onemedia info` tool prints it as `rotate 90`.

## Clockwise or counterclockwise

OneMedia counts clockwise. FFmpeg counts counterclockwise: `-display_rotation -90` above asks for 90° clockwise, and ffprobe reports the file as `-90`:

```shell
ffprobe -v error -select_streams v -show_entries stream_side_data=rotation -of csv=p=0 portrait.mp4
```

```text
-90
```

So a file ffprobe calls `90` is 270 here. Both describe the same matrix.

## Limits

- **No decoding, no rotating.** OneMedia reads the rotation; it doesn’t turn the frames or rewrite the file.
- **MP4 family only.** The rotation is read from the MP4, MOV and 3GP track matrix. 0.1 reads none from Matroska or WebM: there `media.Rotation` has no candidate, and `Value` is the default, 0.
- **Quarter turns.** Only the eight matrices of 0, 90, 180 or 270°, mirrored or not, give a candidate; a scaled or skewed matrix gives none. A vertical flip reads as 180° and mirrored.

For the other basic facts of a video, see [Get video duration, resolution and codec](https://recursiveai.org/onemedia/cookbook/get-video-duration-resolution-codec/).
