C#中NAudio音頻庫(kù)的安裝與使用教程詳解
NAudio安裝
項(xiàng)目=>NuGet包管理器 搜索NAudio點(diǎn)擊安裝,自動(dòng)安裝依賴庫(kù)。

安裝成功后工具箱會(huì)新增NAudio.WinForms控件

NAudio簡(jiǎn)述
NAudio為.NET平臺(tái)下的開源庫(kù),采用ML-PL協(xié)議,開源地址:https://github.com/naudio/NAudio支持多種音頻操作,可實(shí)現(xiàn)多種API播放與錄制、多種不同音頻格式、音頻格式轉(zhuǎn)換(重采樣、位深、聲道等)、音頻編碼、多通道播放、音頻效果處理等等。
常用類:
- WaveIn 表示波形輸入, 繼承了 IWaveIn, 例如麥克風(fēng)輸入, 或者計(jì)算機(jī)正在播放的音頻流。
- WaveOut 表示波形輸出, 繼承了 IWavePlayer, 用來(lái)播放音頻, 以 IWaveProvider 作為播放源播放音頻, 通過(guò)拓展方法也支持以 ISampleProvider 作為播放源播放音頻。
- WaveStream 表示波形流, 它繼承了 IWaveProvider, 可以用來(lái)作為播放源。
- WaveFileReader 繼承了 WaveStream, 用來(lái)讀取波形文件。
- WaveFileWriter 繼承了Stream, 用來(lái)寫入文件, 常用于保存音頻錄制的數(shù)據(jù)。
- AudioFileReader 通用的音頻文件讀取器, 可以讀取波形文件, 也可以讀取其他類型的音頻文件例如 Aiff, MP3
常用接口:
- IWaveProvider 波形提供者, 上面已經(jīng)提到, 是音頻播放的提供者, 通過(guò)拓展方法可以轉(zhuǎn)換為 ISampleProvider。
- ISampleProvider 采樣提供者, 上面已經(jīng)提到, 通過(guò)拓展方法可以作為 WaveOut 的播放源。
簡(jiǎn)單示例1
自定義錄音機(jī)類:Recorder.cs
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NAudioDemo
{
internal class Recorder
{
public WaveIn mWaveIn;
public WaveFileWriter mWaveFileWriter;
public int secondsRecorded;
/// <summary>
/// 開始錄音
/// </summary>
/// <param name="filePath"></param>
public void RecorderStart(string filePath)
{
// 創(chuàng)建WaveIn對(duì)象
mWaveIn = new WaveIn();
// 添加DataAvailable事件處理回調(diào)
mWaveIn.DataAvailable += OnDataAvailable;
// 創(chuàng)建WaveFileWriter對(duì)象
mWaveFileWriter = new WaveFileWriter(filePath, mWaveIn.WaveFormat);
// 開始錄音
mWaveIn.StartRecording();
}
/// <summary>
/// 停止錄音
/// </summary>
public void RecorderStop()
{
mWaveIn?.StopRecording();
mWaveIn?.Dispose();
mWaveFileWriter?.Close();
mWaveFileWriter = null;
}
/// <summary>
/// 錄音數(shù)據(jù)回調(diào)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
// 寫入錄音數(shù)據(jù)
mWaveFileWriter.Write(e.Buffer, 0, e.BytesRecorded);
// 計(jì)算已錄制的秒數(shù)
secondsRecorded = (int)mWaveFileWriter.Length / mWaveFileWriter.WaveFormat.AverageBytesPerSecond;
}
}
}using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using NAudio.Wave;
using System.Drawing.Text;
using System.Media;
using NAudio.Dsp;
namespace NAudioDemo
{
public partial class Form1 : Form
{
// 創(chuàng)建錄音機(jī)類實(shí)例
Recorder recorder = new Recorder();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
button2.Enabled = true;
recorder.RecorderStart(@"D:\1.wav");
}
private void button2_Click(object sender, EventArgs e)
{
button1.Enabled = true;
button2.Enabled = false;
recorder.RecorderStop();
}
private void button3_Click(object sender, EventArgs e)
{
SoundPlayer player = new SoundPlayer(@"D:\1.wav");
player.Play();
}
}
}
錄制麥克風(fēng)
借助 WaveIn 類, 我們可以輕易的捕獲麥克風(fēng)輸入, 在每一次錄制到數(shù)據(jù)時(shí), 將數(shù)據(jù)寫入到文件或其他流, 這就實(shí)現(xiàn)了保存錄音
在保存波形文件時(shí)需要借助 WaveFileWriter, 當(dāng)然, 如果你想保存為其他格式, 也可以使用其它的 Writer, 例如 CurWaveFileWriter 以及AiffFileWriter, 美中不足的是沒(méi)有直接寫入到 MP3 的 FileWriter
需要注意的是, 桌面程序可以直接使用 WaveIn, 其回調(diào)基于 Windows 消息, 所以無(wú)法在控制臺(tái)應(yīng)用中使用 WaveIn
如果要在控制臺(tái)應(yīng)用中實(shí)現(xiàn)錄音, 只需要使用 WaveInEvent, 它的回調(diào)基于事件而不是 Windows 消息, 所以可以通用
示例代碼:
WaveIn cap = new WaveIn(); // cap, capture WaveFileWriter writer = new WaveFileWriter(); cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded); // 訂閱事件 cap.StartRecording(); // 開始錄制 cap.StopRecording(); // 停止錄制 writer.Close(); // 關(guān)閉 FileWriter, 保存數(shù)據(jù)
另外, 除了使用 WaveIn, 你還可以使用 WasapiCapture, 它與 WaveIn 的使用方式是一致的, 可以用來(lái)錄制麥克風(fēng)
Wasapi 全稱 Windows Audio Session Application Programming Interface (Windows音頻會(huì)話應(yīng)用編程接口)
具體 WaveIn, WaveInEvent, WasapiCapture 的性能, 筆者還沒(méi)有測(cè)試過(guò), 但估計(jì)不會(huì)有太大差異.
提示: WasapiCapture 和 WasapiLoopbackCapture 位于 NAudio.Wave 命名空間下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio;
using NAudio.Wave;
namespace NAudioDemo2
{
public partial class Form2 : Form
{
private WaveIn waveIn = null;
private WaveFileWriter writer = null;
public Form2()
{
InitializeComponent();
button2.Enabled = false;
button3.Enabled = false;
}
/// <summary>
/// 設(shè)置保存文件名稱
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
saveFileDialog1.Filter = "audio files (*.wav)|*.wav| all files (*.*)|*.*"; // 文件類型過(guò)濾
saveFileDialog1.DefaultExt = "*.wav"; // 默認(rèn)文件擴(kuò)展名
//saveFileDialog1.FileName = "1.wav"; // 默認(rèn)文件名
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string fName = saveFileDialog1.FileName; // 獲取文件名
textBox1.Text = fName;
button2.Enabled = true;
}
}
/// <summary>
/// 開始錄音
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
//waveIn = new WaveIn { WaveFormat = new WaveFormat(44100, 1) };
waveIn = new WaveIn();
waveIn.WaveFormat = new WaveFormat(44100, 1);
writer = new WaveFileWriter(textBox1.Text.Trim(), waveIn.WaveFormat);
waveIn.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded);
waveIn.StartRecording();
button2.Enabled = false;
button3.Enabled = true;
}
/// <summary>
/// 停止錄音
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
waveIn.Dispose();
waveIn = null;
writer.Flush();
writer.Close();
writer.Dispose();
button2.Enabled = true;
button3.Enabled = false;
}
}
}錄制系統(tǒng)聲卡
錄制聲卡輸出, 也就是錄制計(jì)算機(jī)正在播放的聲音, 借助 WasapiLoopbackCapture 即可簡(jiǎn)單實(shí)現(xiàn), 使用方式與 WasapiCapture 無(wú)異
WasapiLoopbackCapture cap = new WasapiLoopbackCapture(); WaveFileWriter writer = new WaveFileWriter(); cap.DataAvailable += (s, args) => writer.Write(args.Buffer, 0, args.BytesRecorded); cap.StartRecording();
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NAudioDemo2
{
public partial class Form3 : Form
{
private WasapiLoopbackCapture loopCap = new WasapiLoopbackCapture();
private WaveFileWriter fileWriter;
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "wave file *.wav|*.wav|all filse *.*|*.*";
saveFileDialog.DefaultExt = ".wav";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
string fName = saveFileDialog.FileName;
textBox1.Text = fName;
}
}
/// <summary>
/// 錄制聲卡開始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
fileWriter = new WaveFileWriter(textBox1.Text.Trim(), loopCap.WaveFormat) ;
loopCap.DataAvailable += (s, args) => fileWriter.Write(args.Buffer, 0, args.BytesRecorded);
loopCap.StartRecording();
}
/// <summary>
/// 錄制聲卡停止
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
loopCap.StopRecording();
fileWriter.Flush();
fileWriter.Close();
fileWriter.Dispose();
}
}
}WAV格式播放
NAudio 中, 通過(guò) WaveFileReader 來(lái)讀取波形數(shù)據(jù), 在實(shí)例化時(shí), 你可以指定文件名或者是輸入流, 這意味著你可以讀取內(nèi)存流中的音頻數(shù)據(jù).
WaveFileReader reader = new WaveFileReader(filepath); WaveOut wout = new WaveOut(); wout.Init(reader); // 通過(guò) IWaveProvider 為音頻輸出初始化 wout.Play(); // 至此, wout 將從指定的 reader 中提供的數(shù)據(jù)進(jìn)行播放
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NAudioDemo2
{
public partial class Form4 : Form
{
private WaveOut wout_wav;
WaveFileReader reader;
public Form4()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "audio file *.wav|*.wav";
ofd.DefaultExt = "*.wav";
if (ofd.ShowDialog() == DialogResult.OK)
{
string fName = ofd.FileName;
textBox1.Text = fName;
}
}
private void button2_Click(object sender, EventArgs e)
{
reader = new WaveFileReader(textBox1.Text.Trim());
wout_wav = new WaveOut();
wout_wav.Init(reader);
wout_wav.Play();
}
private void button3_Click(object sender, EventArgs e)
{
wout_wav.Pause();
}
private void button4_Click(object sender, EventArgs e)
{
wout_wav.Resume();
}
private void button5_Click(object sender, EventArgs e)
{
wout_wav.Stop();
wout_wav.Dispose();
reader.Close();
}
}
}MP3格式播放
播放 MP3 音樂(lè)其實(shí)與播放波形音樂(lè)沒(méi)有太大區(qū)別, 只不過(guò)將 WaveFileReader 換成Mp3FileReader 罷了
Mp3FileReader reader = new Mp3FileReader(filepath); WaveOut wout = new WaveOut(); wout.Init(reader); wout.Play();
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NAudioDemo2
{
public partial class Form5 : Form
{
Mp3FileReader reader;
WaveOut wout_mp3;
public Form5()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "audio file *.mp3|*.mp3";
ofd.DefaultExt = "*.mp3";
if (ofd.ShowDialog() == DialogResult.OK)
{
string fName = ofd.FileName;
textBox1.Text = fName;
}
}
private void button2_Click(object sender, EventArgs e)
{
reader = new Mp3FileReader(textBox1.Text);
wout_mp3 = new WaveOut();
wout_mp3.Init(reader);
wout_mp3.Play();
}
private void button3_Click(object sender, EventArgs e)
{
wout_mp3.Pause();
}
private void button4_Click(object sender, EventArgs e)
{
wout_mp3.Resume();
}
private void button5_Click(object sender, EventArgs e)
{
wout_mp3.Stop();
wout_mp3.Dispose();
reader.Close();
reader.Dispose();
}
}
}AudioFileReader讀取播放音頻
通過(guò)AudioFileReader讀取音頻文件可以播放.mp3, .wav, .flac等多種格式
AudioFileReader reader = new AudioFileReader (@“d:\1.mp3”); WaveOut wout = new WaveOut (); wout.Init(reader ); wout.Play(); wout.Pause(); wout.Resume(); wout.Stop();
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NAudioDemo2
{
public partial class Form6 : Form
{
AudioFileReader reader;
WaveOut wout;
public Form6()
{
InitializeComponent();
}
private void Form6_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "audio file *.mp3|*.mp3|all files *.*|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
string fName = ofd.FileName;
textBox1.Text = fName;
}
}
private void button2_Click(object sender, EventArgs e)
{
reader = new AudioFileReader(textBox1.Text.Trim());
wout = new WaveOut();
wout.Init(reader);
wout.Play();
}
private void button3_Click(object sender, EventArgs e)
{
wout.Pause();
}
private void button4_Click(object sender, EventArgs e)
{
wout.Resume();
}
private void button5_Click(object sender, EventArgs e)
{
wout.Stop();
wout.Dispose();
reader.Close();
reader.Dispose();
}
}
}MediaFoundationReader 讀取播放音頻
通過(guò)MediaFoundationReader 讀取音頻文件可以播放.mp3, .wav, .flac等多種格式
MediaFoundationReader reader = new MediaFoundationReader (@“d:\1.mp3”); WaveOut wout = new WaveOut (); wout.Init(reader ); wout.Play(); wout.Pause(); wout.Resume(); wout.Stop();
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NAudioDemo2
{
public partial class Form7 : Form
{
MediaFoundationReader reader;
WaveOut wout;
public Form7()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "audio file *.mp3|*.mp3|all files *.*|*.*";
ofd.DefaultExt = "*.mp3";
if (ofd.ShowDialog() == DialogResult.OK)
{
string fName = ofd.FileName;
textBox1.Text = fName;
}
}
private void button2_Click(object sender, EventArgs e)
{
reader = new MediaFoundationReader(textBox1.Text.Trim());
wout = new WaveOut();
wout.Init(reader);
wout.Play();
}
private void button3_Click(object sender, EventArgs e)
{
wout.Pause();
}
private void button4_Click(object sender, EventArgs e)
{
wout.Resume();
}
private void button5_Click(object sender, EventArgs e)
{
wout.Stop();
wout.Dispose();
reader.Close();
reader.Dispose();
}
}
}以上就是C#中NAudio音頻庫(kù)的安裝與使用教程詳解的詳細(xì)內(nèi)容,更多關(guān)于C# NAudio的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot?配置多個(gè)JdbcTemplate的實(shí)現(xiàn)步驟
本文介紹了在SpringBoot中配置多個(gè)JdbcTemplate的方法,包括創(chuàng)建項(xiàng)目、添加依賴、配置數(shù)據(jù)源和多個(gè)JdbcTemplate的使用,感興趣的可以了解一下2024-11-11
Java使用WebView實(shí)現(xiàn)桌面程序的技術(shù)指南
在現(xiàn)代軟件開發(fā)中,許多應(yīng)用需要在桌面程序中嵌入 Web 頁(yè)面,例如,你可能需要在 Java 桌面應(yīng)用中嵌入一部分 Web 前端,或者加載一個(gè) HTML5 界面以增強(qiáng)用戶體驗(yàn),所以本文給大家介紹了Java使用WebView實(shí)現(xiàn)桌面程序的技術(shù)指南,需要的朋友可以參考下2025-05-05
Java List轉(zhuǎn)換成String數(shù)組幾種實(shí)現(xiàn)方式詳解
這篇文章主要介紹了Java List轉(zhuǎn)換成String數(shù)組幾種實(shí)現(xiàn)方式詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12
Spring Boot 項(xiàng)目中使用Swagger2的示例
本篇文章主要介紹了Spring Boot 項(xiàng)目中使用Swagger2的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Java將CSV的數(shù)據(jù)發(fā)送到kafka的示例
這篇文章主要介紹了Java將CSV的數(shù)據(jù)發(fā)送到kafka得示例,幫助大家更好得理解和使用Java,感興趣的朋友可以了解下2020-11-11
springBoot和spring security版本對(duì)應(yīng)關(guān)系詳解
文章主要介紹了Spring Boot和Spring Security之間的版本對(duì)應(yīng)關(guān)系,通過(guò)整理不同版本的依賴關(guān)系,幫助開發(fā)者更好地理解和使用這兩個(gè)框架2026-03-03
MongoDB中ObjectId的誤區(qū)及引起的一系列問(wèn)題
這篇文章主要介紹了MongoDB中ObjectId的誤區(qū)及引起的一系列問(wèn)題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12

