winforms 在C#中使用Vorbis和NAudio播放OGG文件

u3r8eeie  于 2022-11-30  发布在  C#
关注(0)|答案(1)|浏览(488)

我正在尝试播放OGG文件流与NVorbisNAudio,如文档中所述,我正在尝试运行此代码时,在一个按钮点击,但我得到一个异常:
System.ArgumentException:'无法初始化容器!'
我的目标是.Net Framework 4.5
下面是我的代码:

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
    }
}
kninwzqo

kninwzqo1#

这里有两个问题:

  • 首先,您不能使用using语句声明WaveOutReader或WaveOut对象,因为后者异步播放声音,并且需要打开WaveOutReader的Stream
  • 您的目标是.Net Framework 4.5,它不适合处理当前版本的NAudioNVorbis

我假设您已经在新的.Net 6+项目中成功安装了NAudio 2.1.0和NAudio.Vorbis 1.5.0包。
只需添加对NAudio.VorbisNAudio.Wave的引用
目标.Net 6+,启用nullable
将两个按钮控件添加到窗体中,一个名为btnPlayAudio,另一个名为btnStopPlayback,最初是禁用的;使用此处显示的事件处理程序订阅其Click事件。
WaveOutReader和充当播放器的WaveOut对象被声明为示例Fields,初始设置为null
当您按下“播放音频”按钮时,将初始化音频流和播放器,调用WaveOutInit()方法,该方法还订阅WaveOut对象的PlaybackStopped事件。
当您呼叫WaveOut对象的Stop()方法或OGG播放终止时,会引发此事件。这里,Stop()方法是在btnStopPlayback按一下行程常式中呼叫。
当发生这种情况时,将调用另一个方法WaveOutReset();这个方法会处置WaveOut对象和WaveOutReader的数据流。2事件行程常式也会移除。

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();
    }
}

相关问题