Using Vorbis and NAudio to play OGG files in C#

788 views Asked by At

I'm trying to play OGG file stream with NVorbis and NAudio, as described in the documention, I'm trying to run this code when on a Button click, but I get an exception:

System.ArgumentException: 'Could not initialize container!'

I'm targeting .Net Framework 4.5

Here is my code:

private void button1_Click(object sender, EventArgs e)
{
   using (var vorbisStream = new NAudio.Vorbis.VorbisWaveReader(@"OGG file path"))
    using (var waveOut = new NAudio.Wave.WaveOutEvent())
    {
        waveOut.Init(vorbisStream);
        waveOut.Play();
     
        // wait here until playback stops or should stop
    }
}
1

There are 1 answers

2
Jimi On BEST ANSWER

Two issues here:

  • The first is that you cannot declare with using statements either the WaveOutReader or WaveOut object, since the latter is playing the sound asynchronously and it needs the WaveOutReader's Stream open
  • You were targeting .Net Framework 4.5, which is not suitable to handle the current version of both NAudio and NVorbis

I assume you have already successfully installed the NAudio 2.1.0 and NAudio.Vorbis 1.5.0 packages in a new .Net 6+ Project.
You just need to add references to NAudio.Vorbis and NAudio.Wave

Targeting .Net 6+, nullable enabled.

Add two Button Controls to a Form, one named btnPlayAudio and the other btnStopPlayback, initially disabled; subscribe to their Click event using the event handlers shown here.

The WaveOutReader and the WaveOut object that acts as player are declared as instance Fields, initially set to null.

When you press the Play Audio Button, the audio Stream and the Player are initialized, calling the WaveOutInit() method, which also subscribes to the WaveOut object's PlaybackStopped event.
When you call the WaveOut object's Stop() method or the OGG playback terminates, this event is raised. Here, the Stop() method is called in the btnStopPlayback click handler.

When this happens, another method, WaveOutReset(), is called; this method disposes of the WaveOut object and the Stream of the WaveOutReader. The event handler is also removed.

using NAudio.Vorbis;
using NAudio.Wave;

public partial class MainForm : Form {

    private VorbisWaveReader? vorbis = null;
    private WaveOut? oggPlayer = null;

    private void btnPlayAudio_Click(object sender, EventArgs e)
    {
        btnPlayAudio.Enabled = false;
        btnStopPlayback.Enabled = true;
        vorbis = new VorbisWaveReader("OGG File path"));
        oggPlayer = WaveOutInit(vorbis);
        oggPlayer.Play();
    }

    private void btnStopPlayback_Click(object sender, EventArgs e)
    {
        oggPlayer?.Stop();
        btnStopPlayback.Enabled = false;
    }

    private void WaveOut_PlaybackStopped(object? sender, StoppedEventArgs e)
    {
        WaveOutReset(oggPlayer, vorbis);
        btnPlayAudio.Enabled = true;
    }

    private WaveOut WaveOutInit(IWaveProvider reader)
    {
        var waveOut = new WaveOut();
        waveOut.PlaybackStopped += WaveOut_PlaybackStopped;
        waveOut.Init(reader);
        return waveOut;
    }

    private void WaveOutReset(WaveOut? player, VorbisWaveReader? reader)
    {
        if (player != null) {
            player.PlaybackStopped -= WaveOut_PlaybackStopped;
            player.Dispose();
        }
        reader?.Dispose();
    }
}