---
title: "Getting started with OneMedia"
url: https://recursiveai.org/onemedia/docs/getting-started/
description: "Install OneMedia 0.1.0-preview.1 for .NET 10, open an MP4 or a Matroska file, and read its tracks, codecs, tags and capture facts. OneMedia reads media…"
version: "0.1.0-preview.1"
---

# Getting started with OneMedia

Install OneMedia 0.1.0-preview.1 for .NET 10, open an MP4 or a Matroska file, and read its tracks, codecs, tags and capture facts. OneMedia reads media containers in managed code with no dependency beyond .NET.

## Before you use it

- **It decodes nothing.** OneMedia reads containers: tracks, packets, codec headers and tags. It never decodes or encodes a video or audio sample, so it can’t give you frames, thumbnails or pixels. Audio can be decoded by [OneAudio](https://recursiveai.org/oneaudio/) through the `RecursiveAI.OneMedia.Audio` adapter.
- **Reading only.** 0.1 reads MP4, MOV, 3GP/3G2, M4A/M4V and fragmented MP4, and Matroska and WebM (MKV, MKA, MK3D). Writing, tag editing, remuxing, subtitles, repair and HLS/DASH packaging are not in this release, nor are other containers.
- **A preview.** The API can change between previews.

## Install

The packages target `net10.0`, so you need the .NET 10 SDK, and `dotnet add package` needs `--prerelease` or the exact version.

```shell
dotnet new console -o OneMediaStart && cd OneMediaStart
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
```

Three packages are on NuGet:

| Package | What it is |
|---|---|
| `RecursiveAI.OneMedia` | the library; depends on nothing but .NET |
| `RecursiveAI.OneMedia.Audio` | hands audio tracks to OneAudio for decoding; depends on the core package and `RecursiveAI.OneAudio` |
| `RecursiveAI.OneMedia.Tool` | the `onemedia` command-line tool (`dotnet tool install`) |

`flower.mp4` is a five-second clip from MDN’s CC0 sample videos (public domain).

## A first program

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

```csharp
using RecursiveAI.OneMedia;

// Media.Open reads the file's structure only: no packet payload is read here.
using MediaFile media = Media.Open("flower.mp4");
Console.WriteLine($"Format:   {media.Format}");
Console.WriteLine($"Duration: {media.Duration}");

foreach (MediaTrack track in media.Tracks)
{
    string detail = track.Video is { } v ? $"{v.Width}x{v.Height}"
                  : track.Audio is { } a ? $"{a.SampleRate} Hz, {a.Channels} ch"
                  : "";
    Console.WriteLine($"Track {track.Index}: {track.Kind} {track.Codec} {detail}");
}

// Capture facts are candidate lists: the first candidate is the value.
var created = media.CaptureTime.Best;
Console.WriteLine($"Created:  {created?.Value} (from {created?.Source})");
Console.WriteLine($"Rotation: {media.Rotation.Value.RotationDegrees}°");
```

```text
Format:   isobmff
Duration: 00:00:05.0550000
Track 0: Video h264 960x540
Track 1: Audio aac 48000 Hz, 2 ch
Created:  2018-03-07T15:21:21Z (from mvhd)
Rotation: 0°
```

`Duration` is a `TimeSpan?`: the container’s figure, unless a track without an edit list runs longer. `ExactDuration` is the same as an exact rational `MediaTime`. The format is `isobmff` for the MP4 family and `matroska` for MKV and WebM. `Media.Open` reads by content, not by file extension.

## What else it reads

- **Tags.** `media.Tags` is a common view (`Title`, `Artist`, `Comment`, `Encoder` and more) over the native tags: iTunes `ilst`, QuickTime `udta` and `mdta` keys, 3GPP, XMP, and Matroska tags with their targets. `media.Native["ilst", "©nam"]` reads one native tag. See [Read MP4 metadata](https://recursiveai.org/onemedia/cookbook/read-mp4-metadata/).
- **Facts.** `CaptureTime`, `Location`, `Device` (make, model, software) and `Rotation` each list every candidate the file holds, best first, with where it came from. See [When and where a video was recorded](https://recursiveai.org/onemedia/cookbook/video-recording-date-location/).
- **Packets.** `media.Packets(track)` gives each packet’s bytes with exact timestamps, keyframe flag and byte range in the file. See [Keyframe timestamps](https://recursiveai.org/onemedia/cookbook/video-keyframes/).
- **Codec headers.** `CodecParameterReader.TryDescribe` parses the codec configuration: profile, level, bit depth, chroma, color and the RFC 6381 codec string (`avc1.64001F`). See [Duration, resolution and codec](https://recursiveai.org/onemedia/cookbook/get-video-duration-resolution-codec/).
- **Remote files.** `Media.OpenAsync(length, readRange)` reads through any ranged reader, such as HTTP range requests. See [Read video metadata from a URL](https://recursiveai.org/onemedia/cookbook/read-video-metadata-from-url/).

## Damaged files

A file that isn’t in a format OneMedia reads throws `UnsupportedMediaException`. A file it can open but that has damage opens anyway: each problem is a typed entry in `media.Defects` with its byte offset, and reading continues where it safely can.

## Next

The [cookbook](https://recursiveai.org/onemedia/cookbook/) has a complete program for each common task. [MP4, MOV and 3GP](https://recursiveai.org/onemedia/docs/isobmff/) and [Matroska and WebM](https://recursiveai.org/onemedia/docs/matroska-differential/) describe how each container is read and where the result differs from ffprobe, and [Tags and capture facts](https://recursiveai.org/onemedia/docs/tags/) lists the order in which candidates are ranked.
