实现MP3文件和OGG文件音乐播放的WinForm程序
1.作业要求
1.1 要求1:
- 程序应能够读取MP3文件,并播放其中的音频。
- 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
- 程序应具有良好的用户界面,方便用户进行操作。
- 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
1.2 要求2:
- 程序应能够播放ogg文件。
- 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
- 程序应具有良好的用户界面,方便用户进行操作。
- 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控件
2.效果展示
20240510-173654
3.UI界面设计
设计思路:通过listbox控件显示导入的歌曲列表,并可以通过点击选择歌曲进行播放;后通过添加三个button控件,分别实现导入歌曲、暂停与播放、下一首功能;再添加trackbar控件,以实现对系统音量的控制;在下方以WIndows Media Player的进度条实现对音乐播放进度的展示。
4.难点分析
4.1 文件格式:
对于MP3和OGG文件,需要调用不同的解码器和库进行不同功能的实现
4.2.异常处理:
对于运行过程中诸多异常问题,如文件读取失败、播放格式不支持等异常进行异常处理。
5核心功能实现
5.1 准备工作:
通过Nuget程序包安装NAudio和NAudio.Vorbis库以对ogg文件进行处理
5.2 变量定义
private WaveOutEvent waveOut;//实例化WaveOutEvent类,后用于播放、暂停音乐和获取音乐播放状态
private VorbisWaveReader reader;//实例化VorbisWaveReader类,用于读取OGG格式文件
int num = 1;//定义一个计数器,用于技术播放列表中载入的音乐
private MMDeviceEnumerator deviceEnumerator;
private MMDevice defaultDevice;//定义两个类用于对设备音量调节
string[] files;//定义一个string数组,用于存储歌曲文件的地址
List<string> localmuscallist = new List<string> { };//定义listbox控件用用于显示播放列表的list
5.3 音频文件导入
下代码允许用户从文件系统中选择一组音频文件,清除当前选择,然后将新选择的文件添加到listBox1控件中显示,同时管理一个音频文件路径的列表。如果在这个过程中有任何错误发生,程序会通知用户具体的错误信息。
private void button2_Click(object sender, EventArgs e)
{
try
{
openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav;*.ogg";//定义文件格式筛选器
openFileDialog1.Multiselect = true;//支持一次选入多个文件
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
localmuscallist.Clear();
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(num + "、" + Path.GetFileNameWithoutExtension(x));//通过GetFileNameWithoutExtension()函数获取没有扩展名的歌曲的文件名
localmuscallist.Add(x);
num++;
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Error playing file: {ex.Message}");//异常处理,抛出异常信息
}
}
5.4 滑块音量调节
以下代码允许用户通过滑动 trackBar1来调整系统的主音量,并将滑动条的初始位置设置为反映当前系统音量级别的位置。这样用户就能通过图形界面控件来直观地调整声音。
private void trackBar1_Scroll(object sender, EventArgs e)
{
// 设置系统音量为滑动条的当前值
if (defaultDevice != null)
{
defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBar1.Value / 100f;
}
}
deviceEnumerator = new MMDeviceEnumerator();
defaultDevice = deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
trackBar1.ValueChanged += trackBar1_Scroll;
// 将滑动条当前值设定为系统音量的当前水平
trackBar1.Value = (int)(defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
5.5 音乐的播放与暂停
以下代码分别实现对listbox列表的歌名进行点击播放和通过button1对正在播放的音乐进行暂停播放于继续播放功能
5.5.1 listbox列表点击播放
首先定义ogg播放函数用于处理ogg格式音乐文件,再定义一个总的音乐播放函数,用于音乐播放时文件调用
private void oggplay(string oggFileName)//ogg播放函数
{
if (waveOut.PlaybackState == PlaybackState.Playing || waveOut.PlaybackState == PlaybackState.Paused)
{
waveOut.Stop(); // 停止播放
waveOut.Dispose(); // 释放所有资源
waveOut = new WaveOutEvent(); // 创建一个新的WaveOut实例
}
try
{
// 初始化你的reader
reader = new VorbisWaveReader(oggFileName);
waveOut.Init(reader);
waveOut.Play();
}
catch (Exception ex)
{
MessageBox.Show($"Error re-initializing audio device: {ex.Message}");//抛出异常信息
}
}
private void musicplay(string filename)//音乐播放函数
{
axWindowsMediaPlayer1.URL = filename;
string extension = Path.GetExtension(filename);
if (extension == ".ogg") { oggplay(filename); }
else
{
axWindowsMediaPlayer1.Ctlcontrols.play();//对于非ogg格式音频文件,直接调用Windows Media player控件进行播放
}
}
5.5.2 播放/暂停按钮
因为是通过不同解码器进行播放ogg文件,所以当ogg歌曲播放时点击播放其他格式文件,ogg歌曲不会停止所以需要写一个函数主动停止播放ogg文件并释放资源,再进行下一个歌曲的播放
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (localmuscallist.Count > 0)
{
string filename = localmuscallist[listBox1.SelectedIndex];
if (waveOut.PlaybackState == PlaybackState.Playing)
{
waveOut.Stop();
waveOut.Dispose();
}
musicplay(filename);
}
}
通过对不同播放类的播放状态的判断,确定播放音频文件类型,以调用不同播放类的音频播放、暂停功能。并在按钮为播放时点击后,播放音乐并将按钮文本置为暂停。;在按钮为暂停时点击后,暂停音乐并将按钮文本置为播放
private void button1_Click(object sender, EventArgs e)
{
if (waveOut.PlaybackState == PlaybackState.Playing)
{
// 如果正在播放,则停止
waveOut.Pause();
button1.Text = "播放";
}
else if (waveOut.PlaybackState == PlaybackState.Paused)
{
waveOut.Play();
button1.Text = "暂停";
}
else if (axWindowsMediaPlayer1.playState == WMPPlayState.wmppsPlaying)
{
axWindowsMediaPlayer1.Ctlcontrols.pause();
button1.Text = "播放";
}
else
{
axWindowsMediaPlayer1.Ctlcontrols.play();
button1.Text = "暂停";
}
}
5.6 下一首
以下代码使按钮具备了控制音乐播放列表播放下一首歌曲的功能,并能在列表播放到最后一首时自动回到列表开始进行循环播放。
private void button3_Click(object sender, EventArgs e)
{
if (localmuscallist.Count > 0)
{
if (waveOut.PlaybackState == PlaybackState.Playing)
{
waveOut.Stop();
waveOut.Dispose();
}//检查播放状态,暂停并释放资源
int index = listBox1.SelectedIndex + 1;
if (index >= localmuscallist.Count()) { index = 0; }//当在播放最后列表一首音乐时点击下一首按钮,将转跳到列表首
string filename = localmuscallist[index];
musicplay(filename);
listBox1.SelectedIndex = index;
}
}
6.Gitee仓库克隆地址
https://gitee.com/qk1xcn/windows.git
7.总结
此项目程序基于Windows Forms,主要功能是播放各种音频格式,特别注重对Ogg Vorbis(.ogg)格式的支持。应用程序利用了NAudio库的功能,可以解码并播放Ogg Vorbis音频文件,同时还保持了对其他常见音频格式(如MP3、WAV等)的兼容性。