一、程序要求
要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
二、设计思路
1.基本思路
各个控件代码及其功能如下:
Lable1:用于实现显示当前正在播放的歌曲
AxWindowsMediaPlayer: 用于播放普通格式文件如MP3
OpenFileDialog:用于选择文件
Button:用于实现添加音乐、播放、暂停和下一曲功能
ListBox1:用来显示所有歌曲并选择歌曲。
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]);
}
}
TrackBar1:用来调节音量
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
label2.Text = trackBar1.Value + "%";
}
button1:音乐选择控件
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*.mp3;*,wav;*,flac;*.ogg";
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);
}
}
}
button2:音乐暂停控件
private void button2_Click(object sender, EventArgs e)
{
musicpause(axWindowsMediaPlayer1.URL);
}
button3:下一首歌曲控件
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;
}
button4:音乐继续播放控件
private void button4_Click(object sender, EventArgs e)
{
musicplay(axWindowsMediaPlayer1.URL);
}
完整代码如下
using NAudio.Wave;
using NAudio.Vorbis;
using System;
using System.IO;
using NVorbis;
using System.Reflection.Emit;
string[] files;
List<string> localmusiclist = new List<string> { };
private WaveOutEvent waveOut;
private VorbisWaveReader vorbisFileReader;
private void musicplay(string filename)
{
string extension = Path.GetExtension(filename);
if (extension == ".ogg")
{
if (vorbisFileReader != null)
{
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
vorbisFileReader.Dispose();
}
}
vorbisFileReader = new VorbisWaveReader(filename);
waveOut = new WaveOutEvent();
waveOut.Init(vorbisFileReader);
waveOut.Play();
else
{
if (vorbisFileReader != null)
{
if (waveOut.PlaybackState != PlaybackState.Stopped)
{
waveOut.Stop();
vorbisFileReader.Dispose();
}
}
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
}
private void musicpause(string filename)
{
string extension = Path.GetExtension(filename);
if (extension == ".ogg")
{
waveOut.Pause();
}
else
{
axWindowsMediaPlayer1.Ctlcontrols.pause();
}
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*.mp3;*,wav;*,flac;*.ogg";
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(axWindowsMediaPlayer1.URL);
}
}
private void button2_Click(object sender, EventArgs e)
{
musicpause(axWindowsMediaPlayer1.URL);
}
private void button4_Click(object sender, EventArgs e)
{
musicplay(axWindowsMediaPlayer1.URL);
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
label2.Text = trackBar1.Value + "%";
}
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;
}
2.窗体设计
音乐播放功能应该包含音乐文件获取、显示音乐列表、显示当前音乐、开始播放、停止播放、切换到下一首、调节音量等功能。
3.难点分析
关于要求1:使用WindowsMediaPlayer控件播放MP3文件
难点1:控件集成与初始化
Windows Media Player控件是一个COM组件,需要在Visual Studio中添加引用,并在设计视图中将其拖放到窗体上。
初始化控件时,需要确保控件的属性设置正确,以便能够播放音频文件。
难点2:异常处理
在尝试打开和播放MP3文件时,程序需要能够处理文件不存在的异常,以及其他可能的I/O错误。
需要编写健壮的错误处理代码,以确保程序不会因异常而崩溃。
难点3:用户界面设计
设计一个直观易用的界面,可能需要考虑播放、暂停、停止等常用功能的按钮布局。
还需要考虑进度条、音量控制等附加功能的集成。
难点4:跨版本兼容性
确保代码在不同版本的.NET Framework或.NET Core中都能正常工作,可能需要对API的可用性进行检查,并提供替代方案。
关于要求2使用NAudio库播放OGG文件
难点1:NuGet包管理与引用
使用NuGet包管理器安装NAudio库,并确保引用的正确性。
需要了解NAudio库的API,特别是与Vorbis编码相关的部分。
难点2:音频流的处理
与MP3不同,OGG文件通常需要通过流的方式来处理,因为它们可能是无损压缩的。
需要理解如何使用NAudio库中的Vorbis支持来读取和播放OGG文件的音频流。
难点3:异常处理
同样需要处理文件不存在、文件格式错误等异常情况。
NAudio库可能有其特定的异常类型,需要正确捕获和处理这些异常。
难点4:用户界面与兼容性
用户界面的设计和跨版本兼容性的考虑与要求1类似,但可能需要针对不同的播放引擎(WindowsMediaPlayer vs NAudio)进行适配。
三、小结
技术选型:WindowsMediaPlayer控件适合简单的MP3播放需求,而NAudio库提供了更灵活的音频处理能力,适合更复杂的场景。
异常处理:良好的异常处理机制是保证程序稳定运行的关键。
用户界面:清晰直观的用户界面可以提升用户体验。
兼容性:跨版本兼容性是确保软件广泛适用的重要因素。
测试:充分的测试是确保软件质量的必要条件,特别是在不同的环境和配置下。