Как записать звук со звуковой карты (системное аудио) с помощью C # с помощью NAudio в WinForms

Пару лет назад было действительно сложно записать звук, который в данный момент воспроизводится в ваших колонках, благодаря звуковой карте вашего компьютера с использованием C #. К счастью, со временем в Windows Vista появился полезный API. Windows Audio Session API (WASAPI) — это самый современный метод Microsoft для общения со звуковыми устройствами. Он доступен в Windows Vista, Windows 7 и более поздних версиях Windows. Он позволяет доставлять неизмененный битовый поток на звуковое устройство и обеспечивает преимущества, аналогичные тем, которые предоставляются драйверами ASIO. NAudio предлагает действительно полезную оболочку для этого API, которая позволяет легко записывать звук с вашей звуковой карты с помощью C #.

В этой статье мы покажем вам, как записывать звук, поступающий с вашей звуковой карты, с помощью NAudio с C # в WinForms.

1. Установите NAudio с NuGet

Вам нужно будет установить библиотеку NAudio в свой проект, используя менеджер пакетов NuGet. Откройте проект Winforms C # и откройте менеджер пакетов NuGet в обозревателе решений:

Перейдите на вкладку Обзор и найдите NAudio:

NAudio Установить пакет NuGet

Из списка выберите пакет NAudio от Mark Heath и установите его, просто нажав кнопку Install. После завершения установки вы сможете импортировать пространство имен Wave NAudio в класс, где вы хотите использовать его следующим образом:

using NAudio.Wave;

Если у вас уже установлена ​​программа NAudio, вы можете перейти к следующему шагу.

2. Понять логику записи звука

Благодаря NAudio большая часть сложной логики, лежащей в основе сложного процесса записи звука, исходящего из ваших динамиков (звуковой карты), к счастью, была абстрагирована и написана так, что почти каждый разработчик может понять и использовать. WasapiLoopbackCapture — это класс из NAudio, который вы будете использовать для записи, этот класс является очень хорошо написанной оболочкой WASAPI (Windows Audio Session API), которую можно использовать вместе с некоторыми классами записи файлов NAudio для простой записи аудио из источник звука по умолчанию вашей системы.

Логика, которую вам нужно будет обработать для записи аудио, минимальна, изначально вам необходимо создать экземпляр классов WaveFileWriter и WasapiLoopBackCapture. WaveFileWriter ожидает в качестве первого аргумента путь, куда должен быть записан файл wav (тот, с записанным аудио из динамиков / звуковой карты) и в качестве второго аргумента свойство WaveFormat экземпляра устройства захвата. Делая это, вы готовы записать звук, исходящий от звуковой карты, однако это не делается автоматически, так как вам нужно подключить слушателя к экземпляру устройства захвата, а именно к DataAvailable. Это событие вызывается при получении некоторого аудио, в этом обратном вызове вам нужно использовать устройство записи звука, предоставляя в качестве первого аргумента метода записи буфер и остаток от записанных байтов и сами записанные байты. Вам также необходимо утилизировать устройство записи звука, как только устройство захвата остановится, чтобы файл был доступен. Наконец, вы можете просто запустить рекордер, используя метод StartRecording.

Стоит сказать, что код асинхронный, поэтому вам не нужно заботиться в основном о многопоточности или других сложных вещах (возможно, изначально):

// Define the output wav file of the recorded audio
string outputFilePath = @"C:\Users\sdkca\Desktop\system_recorded_audio.wav";
// Redefine the capturer instance with a new instance of the LoopbackCapture class
WasapiLoopbackCapture CaptureInstance = new WasapiLoopbackCapture();
// Redefine the audio writer instance with the given configuration
WaveFileWriter RecordedAudioWriter = new WaveFileWriter(outputFilePath, CaptureInstance.WaveFormat);
// When the capturer receives audio, start writing the buffer into the mentioned file
CaptureInstance.DataAvailable += (s, a) =>
{
// Write buffer into the file of the writer instance
RecordedAudioWriter.Write(a.Buffer, 0, a.BytesRecorded);
};
// When the Capturer Stops, dispose instances of the capturer and writer
CaptureInstance.RecordingStopped += (s, a) =>
{
RecordedAudioWriter.Dispose();
RecordedAudioWriter = null;
CaptureInstance.Dispose();
};
// Start audio recording !
CaptureInstance.StartRecording();

Чтобы остановить запись звука, вы просто запустите StopRecording метод захвата:

CaptureInstance.StopRecording();

Запись в буфер в нужном файле прекратится, и будет создан файл wav со звуком, созданным вашей системой во время выполнения процесса. Очевидно, не забудьте воспроизвести звук во время тестирования, иначе вы ничего не услышите!

Полный пример

В этом примере мы просто создадим форму с 2 кнопками: одна для запуска рекордера (кнопка 1) и другая для ее остановки (кнопка 2). Кнопка «Стоп» изначально отключена, и она будет активирована после запуска рекордера и наоборот с помощью кнопки «Пуск». Графически форма выглядит так:

Пример записи аудио формы

Логика, которую мы реализуем, очень проста, но функциональна. Когда пользователь нажимает кнопку «Пуск», звук системы записывается, а когда пользователь нажимает кнопку «Стоп», рекордер останавливается и завершает буфер записи желаемого выходного аудиофайла. Случаи WaveFileWriter и WasapiLoopbackCapture предназначены для того, чтобы быть доступными на уровне класса, поэтому наши кнопки «Пуск» и «Стоп» имеют к ним доступ, поскольку из-за этого поведения изначально установлено нулевое значение.

Далее прикрепите слушатель щелчка к обеим кнопкам и назначьте логику соответственно. Для кнопки запуска определите переменную, которая содержит путь к выходному аудиофайлу, и переопределите WaveFileWriter и WasapiLoopbackCapture экземпляры с новым. Затем присоедините обратные вызовы onDataAvailable и onRecordingStopped к экземпляру устройства захвата и, соответственно, запишите логику. В этом случае, когда данные доступны, запишите выходной буфер в объявленный файл, используемый средством записи волн. Когда запись останавливается, она, очевидно, должна удалить экземпляр захвата. Наконец, когда пользователь нажимает кнопку остановки, экземпляр устройства записи должен просто остановить устройство записи, отключив также кнопку остановки и снова включив кнопку запуска, чтобы снова можно было записать новый файл:

using System;
using System.Windows.Forms;
// Import Wave of NAudio
using NAudio.Wave;
namespace Sandbox
{
public partial class Form1 : Form
{
// Create class-level accessible variables to store the audio recorder and capturer instance
private WaveFileWriter RecordedAudioWriter = null;
private WasapiLoopbackCapture CaptureInstance = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Define the output wav file of the recorded audio
string outputFilePath = @"C:\Users\sdkca\Desktop\system_recorded_audio.wav";
// Redefine the capturer instance with a new instance of the LoopbackCapture class
this.CaptureInstance = new WasapiLoopbackCapture();
// Redefine the audio writer instance with the given configuration
this.RecordedAudioWriter = new WaveFileWriter(outputFilePath, CaptureInstance.WaveFormat);
// When the capturer receives audio, start writing the buffer into the mentioned file
this.CaptureInstance.DataAvailable += (s, a) =>
{
this.RecordedAudioWriter.Write(a.Buffer, 0, a.BytesRecorded);
};
// When the Capturer Stops
this.CaptureInstance.RecordingStopped += (s, a) =>
{
this.RecordedAudioWriter.Dispose();
this.RecordedAudioWriter = null;
CaptureInstance.Dispose();
};
// Enable "Stop button" and disable "Start Button"
this.button1.Enabled = false;
this.button2.Enabled = true;
// Start recording !
this.CaptureInstance.StartRecording();
}
private void button2_Click(object sender, EventArgs e)
{
// Stop recording !
this.CaptureInstance.StopRecording();
// Enable "Start button" and disable "Stop Button"
this.button1.Enabled = true;
this.button2.Enabled = false;
}
}
}
Ссылка на основную публикацию
Adblock
detector