目录
(1)添加依赖项NAudio包和NAudio.Vorbis包
(8)listbox1和label1功能:显示音频列表和显示当前播放的音乐名
一、程序功能
要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控件
二、设计思路
2.1 架构选择
考虑到需求中的界面友好和跨版本兼容性,我们可以选择选择Windows Forms作为开发平台,Windows Forms提供了一个简单而强大的方法来创建桌面应用程序,并且与C#高度兼容,在开发过程,我们选择.NETFramework 4.8.0进行程序设计。
2.2 设计思路
1). 界面设计: 使用Windows Forms工具箱中的控件如按钮、标签和文件对话框构建用户界面。
2). 功能编码: 使用OpenFileDialog允许用户选择音频文件。 根据文件扩展名调用相应的播放器对象进行播放。 播放控制,包括开始、暂停和停止。
3). 异常处理: 捕获并响应各种可能的运行时错误,如文件读取失败、文件格式不支持等,为用户提供清晰的错误信息。
2.3 难点分析
1). 文件格式支持: 处理多种音频格式(MP3,OGG等)要求使用不同的库,这可能导致代码复杂度增加。
2). 异常处理: 音频文件的播放中可能遇到多种异常情况,如文件损坏、编解码器不支持等。
三、窗体设计
1.button1修改为“选择歌曲”,用于播放mp3音乐文件。
2.button2修改为“停止播放”,用于停止音乐文件。
3.button3修改为“下一曲”,用于切换到下一个音乐文件。
4.button4修改为“播放ogg”,用于播放ogg音乐文件。
5.label1用于显示正在播放的歌曲名称。
6.listbox1用于显示歌单。
7.openFileDialog1用于获取音乐文件。
8.trackBar用于调节音量。
四、代码实现
4.1代码逐步实现
(1)添加依赖项NAudio包和NAudio.Vorbis包
在“解决方案资源管理器”中,右键点击项目名称,选择“管理NuGet程序包”,在“NuGet包管理器”中搜索安装NAudio包和NAudio.Vorbis包。
(2)定义音频名称和音频列表
分别定义一个字符串和字符串列表,用于储存音频名称和多个音频文件(实现选取多个音乐文件)。
string[] files;
List<string> localmusiclist = new List<string> { };
(3)播放.mp3格式的音乐
1)将Windows Media Player控件的URL属性设置为传入的filename参数。
2)将文件的扩展名单独提取出来,通过判断扩展名格式,来区分文件类型。
3)判断文件类型,如果是.ogg文件,那么需要别的音乐播放方法来处理这个文件;如果是.mp3文件,那么开始播放这个音乐文件,调用Windows Media Player控件的Ctlcontrols来播放这个音乐文件:axWindowsMediaPlayer1.Ctlcontrols.play(); 否则无法播放。
private void musicplay(string filename)
{
axWindowsMediaPlayer1.URL = filename;
string extension = Path.GetExtension(filename);
if (extension == ".ogg")
{
Console.WriteLine("这是.ogg文件");
}
else if (extension == ".mp3")
{
axWindowsMediaPlayer1.Ctlcontrols.play();
}
else
{
Console.WriteLine("无法识别的文件格式");
}
}
(4)button1功能:选择MP3音乐文件
用openFileDialog1.Filter设置openFileDialog1的过滤器,只显示.mp3文件,实现只能选择.mp3音乐文件的功能。
openFileDialog1.Filter = "选择音频|*.mp3";
可以选择多个音频文件。
openFileDialog1.Multiselect = true;
清除原来的旧列表,以获取新的音频列表。
listBox1.Items.Clear();
localmusiclist.Clear();
检查files中是否为空,不为空则要完全清除,否则不能将音频文件传输给files变量。
if (files != null)
{
Array.Clear(files, 0, files.Length);
}
将files清空之后,将选取的多个音频文件传给files变量,为了避免foreach循环会直接修改files,创建一个新的数组array,用于存放多个音频文件。
files = openFileDialog1.FileNames;
string[] array = files;
再用foreach来遍历数组中的所有元素,并分别存入listBox1的列表和localmusiclist列表中。
foreach (string x in array)
{
listBox1.Items.Add(x);
localmusiclist.Add(x);
}
button1的完整代码:
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*.mp3";
openFileDialog1.Multiselect = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
localmusiclist.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);
}
}
}
(5)button2功能:音频停止播放
使用axWindowsMediaPlayer控件中的Ctlcontrols来停止播放。
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
(6)button3功能:音频切换到下一曲
如果音频文件的数量大于0,那么先将文件列表的索引加1,获取下一个音频文件。
当索引加1后超出音频文件的数量,则意味着已经到了最后一个音频,需要将索引置为0,循环播放列表音频。
private void button3_Click(object sender, EventArgs e)
{
if (localmusiclist.Count > 0)
{
int index = listBox1.SelectedIndex + 1;
if (index >= localmusiclist.Count())
{
index = 0;
}
axWindowsMediaPlayer1.URL = localmusiclist[index];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
listBox1.SelectedIndex = index;
}
}
(7)button4功能:播放.ogg音频文件
首先获取音频文件地址。创建一个新的OpenFileDialog实例,用openFileDialog.Filter过滤其余类型文件,在对话框中选取.ogg文件,将文件地址赋值给对应的变量oggFilePath。
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
使用VorbisWaveReader类来读取oggFilePath指定的 .ogg 音频文件。再创建一个WaveOutEvent实例,用于播放音频。初始化outputDevice,使用reader作为音频源,然后使用play函数来播放选取的音频源。
using (var reader = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(reader);
outputDevice.Play();
}
}
为了确认音频当前时刻是否还在播放,可以在播放音频文件之后,使用while循环来检查。如果还在播放,则线程休眠100毫秒后再次检查。
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(100);
}
button4的完整代码
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
using (var reader = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(reader);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(100);
}
}
}
}
(8)listbox1和label1功能:显示音频列表和显示当前播放的音乐名
如果选择的音频文件数量大于0,则根据当前listBox1中的索引来确定当前播放的音乐,然后将axWindowsMediaPlayer1控件的URL属性设置为当前播放的音乐文件,调用musicplay传递URL参数,实现音频播放。
根据当前正在播放的音频文件的文件路径,获取扩展名以外的音频文件名,赋值给label1的文本Text,则可以实现label1中显示正在播放的音乐名称。
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]);
}
}
(9)trackBar1功能:实现音量调节
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}
4.2完整代码
using System.Diagnostics.Eventing.Reader;
using System.Threading;
using NAudio;
using NAudio.Wave;
using NAudio.Vorbis;
using System.Diagnostics;
namespace WinFormsmusic1
{
public partial class Form1 : Form
{
string[] files;
List<string> localmusiclist = new List<string> { };
public Form1()
{
InitializeComponent();
}
private void musicplay(string filename)
{
axWindowsMediaPlayer1.URL = filename;
string extension = Path.GetExtension(filename);
if (extension == ".ogg")
{
Console.WriteLine("这是.ogg文件");
}
else if (extension == ".mp3")
{
axWindowsMediaPlayer1.Ctlcontrols.play();
}
else
{
Console.WriteLine("无法识别的文件格式");
}
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*.mp3";
openFileDialog1.Multiselect = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
localmusiclist.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 button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
private void button3_Click(object sender, EventArgs e)
{
if (localmusiclist.Count > 0)
{
int index = listBox1.SelectedIndex + 1;
if (index >= localmusiclist.Count())
{
index = 0;
}
axWindowsMediaPlayer1.URL = localmusiclist[index];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
listBox1.SelectedIndex = index;
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
}
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
using (var reader = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(reader);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(100);
}
}
}
}
}
}