Я пытаюсь воспроизвести поток файла OGG с помощью NVorbis
и NAudio
, как описано в документации, я пытаюсь запустить этот код при нажатии кнопки, но получаю исключение:
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
}
}
Здесь две проблемы:
using
ни объект WaveOutReader, ни объект WaveOut, поскольку последний воспроизводит звук асинхронно и ему требуется открыть поток WaveOutReader.NAudio
, так и NVorbis
.Я предполагаю, что вы уже успешно установили пакеты NAudio 2.1.0 и NAudio.Vorbis 1.5.0 в новом проекте .Net 6+.
Вам просто нужно добавить ссылки на NAudio.Vorbis
и NAudio.Wave
Таргетинг на .Net 6+, nullable
включен.
Добавьте в форму два элемента управления «Кнопка», один с именем btnPlayAudio
, а другой btnStopPlayback
, изначально отключенные; подпишитесь на их событие Click, используя показанные здесь обработчики событий.
WaveOutReader и объект WaveOut, который действует как проигрыватель, объявляются как поля экземпляра, изначально установленные в null
.
Когда вы нажимаете кнопку «Воспроизвести аудио», аудиопоток и проигрыватель инициализируются, вызывая метод WaveOutInit()
, который также подписывается на событие PlaybackStopped
объекта WaveOut.
Когда вы вызываете метод Stop()
объекта WaveOut или воспроизведение OGG завершается, возникает это событие. Здесь метод Stop()
вызывается в обработчике кликов btnStopPlayback
.
Когда это происходит, вызывается другой метод, WaveOutReset()
; этот метод удаляет объект WaveOut и поток WaveOutReader. Обработчик событий также удален.
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();
}
}
Поскольку это просто то, что вы читаете, оно может быть сохранено в папке приложения. В этом случае вы обычно добавляете папку в проект, щелкните ее правой кнопкой мыши и выберите Add -> Existing Item
, добавьте файл OGG, выберите его и панель его свойств, выберите Copy to Output Directory -> Copy if newer
Или вы можете добавить его как ресурс проекта, как объект файла . В этом случае он хранится в виде массива байтов, поэтому вам нужно создать из него поток, как, например, var oggStream = new MemoryStream(Properties.Resources.YourOGGobject)
он возвращает System.ArgumentException: «Не удалось инициализировать контейнер!»