---
title: "Read audio metadata"
url: https://recursiveai.org/oneaudio/cookbook/read-audio-metadata/
description: "Read the sample rate, channels, bit depth, duration and tags of WAV, MP3, Ogg Vorbis, Opus and FLAC files in C# with oneaudio, without decoding the audio."
version: "1.2.1"
---

# Read audio metadata

Read the sample rate, channels, bit depth, duration and tags of WAV, MP3, Ogg Vorbis, Opus and FLAC files in C# with oneaudio, without decoding the audio.

```csharp
using OneAudio;
using OneAudio.Flac;
using OneAudio.Vorbis;

// Format, length and tags of every file in the folder, without decoding
// the audio.
foreach (string path in Directory.GetFiles(".").Order())
{
    try
    {
        using IAudioDecoder d = Audio.Open(path);
        AudioFormat f = d.Format;
        string length = d.LengthFrames >= 0
            ? $"{d.LengthFrames / (double)f.SampleRate:F2} s"
            : "unknown length";
        string name = Path.GetFileName(path);
        Console.WriteLine($"{name,-19}{d.GetType().Name,-18}{f.SampleRate,6} Hz " +
                          $"{f.Channels} ch  {f.NativeType,-12}{length}");

        IReadOnlyList<string>? tags = d switch
        {
            VorbisDecoder v => v.Comments,
            FlacDecoder fl => fl.Comments,
            _ => null,                  // Opus and MP3 tags aren't exposed in 1.2.1
        };
        foreach (string tag in tags ?? [])
        {
            int eq = tag.IndexOf('=');  // NAME=value, in any case
            Console.WriteLine($"{"",19}{tag[..eq].ToUpperInvariant()}: {tag[(eq + 1)..]}");
        }
    }
    catch (UnsupportedAudioFormatException)
    {
        Console.WriteLine($"{Path.GetFileName(path),-19}not an audio format oneaudio reads");
    }
}
```

```text
chained.ogg        VorbisDecoder      44100 Hz 2 ch  Lossy       38.03 s
                   ENCODER: Lavc62.11.100 libvorbis
                   ARTIST: Test signal
                   TITLE: Four chords
game-mix.wav       WavDecoder         48000 Hz 2 ch  PcmSigned16 16.00 s
hit.wav            WavDecoder         48000 Hz 1 ch  PcmSigned16 0.40 s
music-noheader.mp3 Mp3Decoder         44100 Hz 2 ch  Lossy       32.03 s
music.flac         FlacDecoder        44100 Hz 2 ch  PcmSigned16 32.00 s
                   DATE: 2026
                   TITLE: Four chords
                   ARTIST: Test signal
                   ENCODER: Lavf62.3.100
music.mp3          Mp3Decoder         44100 Hz 2 ch  Lossy       32.00 s
music.ogg          VorbisDecoder      44100 Hz 2 ch  Lossy       32.00 s
                   ENCODER: Lavc62.11.100 libvorbis
                   ARTIST: Test signal
                   TITLE: Four chords
music.opus         OpusStreamDecoder  48000 Hz 2 ch  Lossy       32.00 s
music.wav          WavDecoder         44100 Hz 2 ch  PcmSigned16 32.00 s
voice.wav          WavDecoder         16000 Hz 1 ch  PcmSigned16 6.03 s
```

## What you can read

| | Format and length | Tags |
|---|---|---|
| WAV / RF64 | Yes | No |
| FLAC | Yes, plus the true bit depth (`FlacDecoder.BitsPerSample`) and the MD5 signature | `FlacDecoder.Comments` and `Vendor` |
| Ogg Vorbis | Yes | `VorbisDecoder.Comments` and `Vendor` |
| Ogg Opus | Yes | Not exposed in 1.2.1 |
| MP3 | Yes | Not exposed in 1.2.1: ID3 tags are skipped |

- Opening a file reads its headers, not its audio. For an MP3 with no Xing, Info or VBRI header, opening makes one pass over the frame headers to find the length.
- `AudioFormat.NativeType` says how the samples are stored: `PcmUnsigned8`, `PcmSigned16`, `PcmSigned24`, `PcmSigned32`, `IeeeFloat32`, `IeeeFloat64`, or `Lossy` for MP3, Vorbis and Opus. `ChannelMask` gives the speaker layout as `WAVE_FORMAT_EXTENSIBLE` speaker bits.
- `chained.ogg` shows the first link’s tags until the decoder reaches the second link. See [Decode Ogg Vorbis](https://recursiveai.org/oneaudio/cookbook/decode-ogg-vorbis/#chained-files).
- To write tags, pass `Comments` in `FlacEncoderSettings` or `OpusFileWriterSettings`. WAV files are written without tags.
