---
title: "Get video duration, resolution and codec in C#"
url: https://recursiveai.org/onemedia/cookbook/get-video-duration-resolution-codec/
description: "Read a video’s duration, width and height, frame rate and codec (with its RFC 6381 string) from MP4, MOV, MKV or WebM in C#, without FFmpeg or ffprobe."
version: "0.1.0-preview.1"
---

# Get video duration, resolution and codec in C#

`Media.Open` reads a video file’s structure and gives you its duration, each track’s codec, the frame size and frame rate, and the audio sample rate, in managed code with no FFmpeg or ffprobe. It reads MP4, MOV, 3GP and fragmented MP4, and MKV and WebM. The two inputs here are the same five-second clip from MDN’s CC0 sample videos, as H.264/AAC in MP4 and VP8/Vorbis in WebM.

```shell
dotnet new console -o VideoInfo && cd VideoInfo
dotnet add package RecursiveAI.OneMedia --version 0.1.0-preview.1
m=https://interactive-examples.mdn.mozilla.net/media/cc0-videos
curl -L -o flower.mp4 $m/flower.mp4
curl -L -o flower.webm $m/flower.webm
```

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

```csharp
using RecursiveAI.OneMedia;
using RecursiveAI.OneMedia.Codecs;

foreach (string path in new[] { "flower.mp4", "flower.webm" })
{
    using MediaFile media = Media.Open(path);
    Console.WriteLine($"{path}: {media.Format}, {media.Duration:mm\\:ss\\.fff}");

    if (media.Video is { Video: { } v } video)
    {
        double fps = (double)v.FrameRateNumerator / v.FrameRateDenominator;
        Console.WriteLine($"  video {video.Codec} {v.Width}x{v.Height} {fps:0.###} fps"
                          + $" {CodecString(video)}");
    }
    if (media.Audio is { Audio: { } a } audio)
        Console.WriteLine($"  audio {audio.Codec} {a.SampleRate} Hz {a.Channels} ch"
                          + $" {CodecString(audio)}");
}

// Parses the codec configuration (avcC, esds, CodecPrivate...) for the details.
static string CodecString(MediaTrack track) =>
    CodecParameterReader.TryDescribe(track.Codec, track.Configuration,
                                     out CodecParameters? p) && p is not null
        ? $"[{p.Rfc6381}{(p.ProfileName is { Length: > 0 } n ? $", {n}" : "")}]"
        : "";
```

```text
flower.mp4: isobmff, 00:05.055
  video h264 960x540 29.97 fps [avc1.64001F, High]
  audio aac 48000 Hz 2 ch [mp4a.40.2, LC]
flower.webm: matroska, 00:05.059
  video vp8 960x540 29.97 fps
  audio vorbis 44100 Hz 2 ch [vorbis]
```

`media.Duration` is a `TimeSpan?`; it is null only when the file doesn’t state one. `media.Video` and `media.Audio` are the first video and audio tracks; `media.Tracks` lists them all (see [List the tracks of a video](https://recursiveai.org/onemedia/cookbook/list-video-tracks/)). The frame size is the coded size; `RotationDegrees` on the same record says whether a player turns it (see [Get video rotation](https://recursiveai.org/onemedia/cookbook/get-video-rotation/)).

The RFC 6381 string is what an HTML `<source type="video/mp4; codecs=…">` or a DASH/HLS manifest wants. The same `CodecParameters` record carries the profile and level, bit depth, chroma format, color description, pixel aspect ratio and, for audio, the sample rate and channel count from the codec header itself.

## Check it with ffprobe

If you have FFmpeg installed, ffprobe reports the same figures:

```shell
ffprobe -v error -show_entries format=duration:stream=codec_name,width,height,r_frame_rate,sample_rate -of compact flower.mp4
```

```text
stream|codec_name=h264|width=960|height=540|r_frame_rate=30000/1001
stream|codec_name=aac|sample_rate=48000|r_frame_rate=0/0
format|duration=5.055000
```

## Limits

- **No decoding.** OneMedia reads what the container and codec headers state. It can’t grab a frame, make a thumbnail or measure anything that needs decoded pixels or samples.
- **Formats.** MP4, MOV, 3GP/3G2, M4A/M4V, fragmented MP4, MKV, MKA, MK3D and WebM only in 0.1. AVI, MPEG-TS, Ogg, FLV and the rest throw `UnsupportedMediaException`.
- **Codec strings.** `Rfc6381` comes from the codec header parsers, so a track whose codec has none (VP8 here) gets no string. The parsers cover H.264, HEVC, H.266, AV1, VP8/VP9, AAC, MP3, Opus, Vorbis, FLAC, AC-3 and others: [Codec headers](https://recursiveai.org/onemedia/docs/codecs/).
- **Frame rate.** It is the nominal rate the container states: the sample durations in MP4, `DefaultDuration` in Matroska (which gives fractions such as 500000000/16683333). Both are 0 when the file doesn’t say, so check before dividing.
- **Fragmented MP4 duration** is structural: it comes from the headers, and the fragments are not scanned. See [MP4, MOV and 3GP](https://recursiveai.org/onemedia/docs/isobmff/).

For tags such as title and artist, see [Read MP4 metadata](https://recursiveai.org/onemedia/cookbook/read-mp4-metadata/).
