一、实验内容
1.1要求一
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
1.2要求二
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控
1.3Nuget程序包中的Naudi.Vorbis控件安装说明
步骤一:右键解决方案,选中管理解决方案的NuGet程序包
步骤二:点击浏览项,在浏览界面中搜索需要下载的库
步骤三:勾选项目,点击安装
步骤四:点击已安装项,查看是否安装成功
二、基本思路
1. 选择音频文件:通过点击按钮,打开文件对话框,用户可以选择一个或多个音频文件(支持 MP3、WAV 和 FLAC 格式)。
2. 显示音频文件列表:将选择的音频文件路径显示在一个列表框中,用户可以从列表中选择要播放的音频文件。
3. 播放音频文件:通过 Windows Media Player 控件(`axWindowsMediaPlayer1`)来播放音频文件。当用户从列表中选择一个音频文件时,将其路径传递给 Windows Media Player 控件,并开始播放该文件。
4. 音量调节:通过滑动滑块控件(`trackBar1`)来调节音频的音量,可以实时更新音量值的显示。
5. 停止播放:提供一个停止按钮,用户可以点击该按钮停止当前正在播放的音频文件。
6. 播放下一首:提供一个按钮,用户可以点击该按钮播放列表中的下一首音频文件。
7. 打开并播放 OGG 文件:提供一个按钮,用户可以打开文件对话框选择 OGG 格式的音频文件,并使用 `VorbisWaveReader` 类来读取和播放该文件。
三、窗体构建
3.1窗体构建步骤说明
步骤一:点击视图项,选中视图中的工具箱项
步骤二:打开工具箱,选中需要的控件,并拖到设计框上;在属性栏修改控件名称、外观等
3.2如何添加Windows Media Player控件
步骤一:右键工具箱中的常规,点击选择项
步骤二:点击COM组件,勾选需要的组件后点击确认
3.3完整界面
四、代码实现
1.引入
NAudio.Vorbis
和NAudio.Wave
using NAudio.Vorbis; using NAudio.Wave;
说明:这两个库提供了音频处理和播放的功能
2.定义了一个名为
Form1
的类,继承自Form
类public partial class Form1 : Form
说明:
Form1
是应用程序的主窗体
3.在
Form1
类中声明一些变量string[] files; List<string> localmusiclist = new List<string> { };
说明:
(1)string[] files;
:用于存储选择的音频文件的路径数组
(2)List<string> localmusiclist = new List<string> { };
:用于存储选择的音频文件的路径列表
4.初始化窗体组件
public Form1() { InitializeComponent(); }
4.1播放mp3音频
5.
musicplay(string filename)
方法用于播放音频文件private void musicplay(string filename) { string extension = Path.GetExtension(filename); if (extension == ".ogg") { Console.WriteLine("this is ogg file"); } else { Console.WriteLine("this is not ogg"); axWindowsMediaPlayer1.Ctlcontrols.play(); } }
说明:该方法根据文件扩展名判断文件是否为 OGG 文件,如果是则输出提示信息,否则使用 Windows Media Player 控件播放音频
6.
button1_Click(object sender, EventArgs e)
方法用于选择音频文件并将其添加到列表框中private void button1_Click(object sender, EventArgs e) { openFileDialog1.Filter = "选择音频|*mp3;*.wav;*.flac"; openFileDialog1.Multiselect = true; if (openFileDialog1.ShowDialog() == DialogResult.OK) { listBox1.Items.Clear(); if (files != null) { Array.Clear(files, 0, files.Length); } files = openFileDialog1.FileNames; string[] array = files; foreach (string x in array) { listBox1.Items.Add(x); localmusiclist.Add(x); } } }
说明:
(1) openFileDialog1.Filter = "选择音频|*mp3;*.wav;*.flac";:只允许用户选择 MP3、WAV 和 FLAC 格式的音频文件
(2)openFileDialog1.Multiselect = true;:允许用户选择多个文件
(3)if (openFileDialog1.ShowDialog() == DialogResult.OK):如果用户在文件对话框中点击了“确定”按钮,则执行下面的代码
(4) listBox1.Items.Clear();:清空列表框中的所有项
(5)if (files != null):检查之前存储音频文件路径的数组是否为空
(6)Array.Clear(files, 0, files.Length);:如果数组不为空,则清空该数组
(7)files = openFileDialog1.FileNames;:将用户选择的音频文件的路径存储在名为 `files` 的字符串数组中
(8)string[] array = files;:将 `files` 数组的引用存储在一个新的字符串数组中
(9) foreach (string x in array):对新的字符串数组中的每个路径进行迭代
(10)listBox1.Items.Add(x);:将每个音频文件的路径添加到列表框中
(11)localmusiclist.Add(x);:将每个音频文件的路径添加到 `localmusiclist` 列表中
7.
listBox1_SelectedIndexChanged(object sender, EventArgs e)
方法用于选择播放列表中的音频文件private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { if (localmusiclist.Count > 0) { axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex]; musicplay(axWindowsMediaPlayer1.URL); label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]); } }
说明:
(1)if (localmusiclist.Count > 0):检查 `localmusiclist` 列表中是否有音频文件路径
(2) axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];:将 Windows Media Player 控件的 URL 属性设置为所选音频文件的路径
(3) musicplay(axWindowsMediaPlayer1.URL);:调用 `musicplay` 方法,并将所选音频文件的路径作为参数传递
(4) label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);:将标签的文本设置为所选音频文件的文件名,以便用户可以看到当前正在播放的音频文件
8.
trackBar1_Scroll(object sender, EventArgs e)
方法用于调整播放器的音量,并更新音量值显示标签private void trackBar1_Scroll(object sender, EventArgs e) { axWindowsMediaPlayer1.settings.volume = trackBar1.Value; label2.Text = trackBar1.Value + "%"; }
说明:
(1)axWindowsMediaPlayer1.settings.volume = trackBar1.Value;:将 Windows Media Player 控件的音量设置为滑动条的当前值
(2)label2.Text = trackBar1.Value + "%";:将标签的文本设置为滑动条的当前值,显示当前音量的百分比
9.
button2_Click(object sender, EventArgs e)
方法用于停止当前正在播放的音频private void button2_Click(object sender, EventArgs e) { axWindowsMediaPlayer1.Ctlcontrols.stop(); }
说明:
(1) axWindowsMediaPlayer1.Ctlcontrols.stop();:调用 Windows Media Player 控件的 `Ctlcontrols.stop()` 方法,该方法用于停止当前正在播放的音频
10.
button3_Click(object sender, EventArgs e)
方法用于播放列表中的下一曲private void button3_Click(object sender, EventArgs e) { int nextIndex = listBox1.SelectedIndex + 1; if (nextIndex >= localmusiclist.Count) { nextIndex = 0; } axWindowsMediaPlayer1.URL = localmusiclist[nextIndex]; musicplay(axWindowsMediaPlayer1.URL); label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[nextIndex]); listBox1.SelectedIndex = nextIndex; }
说明:
(1) int nextIndex = listBox1.SelectedIndex + 1;:获取下一首音频的索引
(2)if (nextIndex >= localmusiclist.Count):检查是否到达列表的末尾。如果已经播放到最后一首音频,将 `nextIndex` 设置为 0,从列表的开头重新开始播放
(3) axWindowsMediaPlayer1.URL = localmusiclist[nextIndex];:将 Windows Media Player 控件的 URL 属性设置为下一首音频的路径
(4) musicplay(axWindowsMediaPlayer1.URL);:调用 `musicplay` 方法,并将下一首音频的路径作为参数传递
(5) label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[nextIndex]);:将标签的文本设置为下一首音频的文件名
(6) listBox1.SelectedIndex = nextIndex;:将列表框的选定索引设置为下一首音频的索引
4.2播放ogg音频
11.
button4_Click(object sender, EventArgs e)
方法用于打开 OGG 文件并播放OGG音频private void button4_Click(object sender, EventArgs e) { string oggFilePath = "\"D:\\CloudMusic\\我不存在的世界 - 潘韵淇.ogg\""; OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "我不存在的世界 - 潘韵淇|*.ogg"; if(openFileDialog .ShowDialog() == DialogResult.OK) { oggFilePath = openFileDialog .FileName; } using (var vorbisReader = new VorbisWaveReader(oggFilePath)) { using (var outputDevice = new WaveOutEvent()) { outputDevice.Init(vorbisReader); outputDevice.Play(); while (outputDevice.PlaybackState == PlaybackState.Playing) { System.Threading.Thread.Sleep(1000); } } } }
说明:
(1)string oggFilePath = "\"D:\\CloudMusic\\我不存在的世界 - 潘韵淇.ogg\"";:存储要播放的 OGG 文件的路径
(2)创建一个 `OpenFileDialog` 对象,并设置 `Filter` 属性,约束用户只能选择ogg文件
(3)if(openFileDialog.ShowDialog() == DialogResult.OK):如果用户在文件对话框中选择了一个文件并点击了“确定”按钮,则执行下面的代码块
(4)oggFilePath = openFileDialog.FileName;:将 `oggFilePath` 设置为用户选择文件的完整路径
(5)创建一个 `VorbisWaveReader` 对象,用于读取 OGG 文件的音频数据
(6)创建一个 `WaveOutEvent` 对象,用于将音频数据输出到音频设备
(7)outputDevice.Init(vorbisReader);:初始化 `WaveOutEvent` 对象,准备播放音频
(8)outputDevice.Play();:开始播放音频
(9) while (outputDevice.PlaybackState == PlaybackState.Playing):进入一个循环,检查播放状态,直到播放完成
(10)System.Threading.Thread.Sleep(1000);:在循环中,暂停当前线程一秒钟,以减轻 CPU 负载
五、运行结果
5.1播放mp3文件
(1)点击添加音乐,选择音乐
(2)选择音乐并播放
5.2播放ogg文件
六、小结
通过本次实验我学习了如何在 C# 中使用 NAudio 库来处理音频文件:
1. 使用 `OpenFileDialog` 对象可以方便地创建一个文件对话框,让用户选择要操作的文件
2. 通过设置 `Filter` 属性,可以限制用户在文件对话框中只能选择指定类型的文件
3. 使用 `VorbisWaveReader` 对象可以读取 OGG 格式音频文件的音频数据,为后续的播放做准备
4. `WaveOutEvent` 对象是 NAudio 库中用于播放音频数据的主要类之一,它能够将音频数据输出到音频设备
5. 通过调用 `Init` 方法和 `Play` 方法,可以初始化 `WaveOutEvent` 对象并开始播放音频数据
七、完整代码
using NAudio.Vorbis;
using NAudio.Wave;
using System;
using System.IO;
namespace WinFormsApp4
{
public partial class Form1 : Form
{
string[] files;
List<string> localmusiclist = new List<string> { };
public Form1()
{
InitializeComponent();
}
private void musicplay(string filename)
{
string extension = Path.GetExtension(filename);
if (extension == ".ogg") { Console.WriteLine("this is ogg file"); }
else
{
Console.WriteLine("this is not ogg");
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*mp3;*.wav;*.flac";
openFileDialog1.Multiselect = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
if (files != null)
{
Array.Clear(files, 0, files.Length);
}
files = openFileDialog1.FileNames;
string[] array = files;
foreach (string x in array)
{
listBox1.Items.Add(x);
localmusiclist.Add(x);
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (localmusiclist.Count > 0)
{
axWindowsMediaPlayer1.URL = localmusiclist[listBox1.SelectedIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[listBox1.SelectedIndex]);
}
}
private void label1_Click(object sender, EventArgs e)
{
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
label2.Text = trackBar1.Value + "%";
}
private void label2_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
private void button3_Click(object sender, EventArgs e)
{
int nextIndex = listBox1.SelectedIndex + 1;
if (nextIndex >= localmusiclist.Count)
{
nextIndex = 0;
}
axWindowsMediaPlayer1.URL = localmusiclist[nextIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[nextIndex]);
listBox1.SelectedIndex = nextIndex;
}
private void button4_Click(object sender, EventArgs e)
{
string oggFilePath = "\"D:\\CloudMusic\\我不存在的世界 - 潘韵淇.ogg\"";
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "我不存在的世界 - 潘韵淇|*.ogg";
if(openFileDialog .ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog .FileName;
}
using (var vorbisReader = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisReader);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
}
}