一、题目内容:
编写一个C#程序,实现音乐文件的播放功能。(包括MP3文件格式和ogg文件格式)
这学期过了一大半了,我们专业的Windows课程也已经从学习基础语法的控制台应用代码编写进入到.NET Windows窗体(WinForms)应用的学习阶段。这是第二次的Windows课程设计作业,要求在.NET Windows窗体应用中实现代码功能。容我在这里多说两句哈,因为上大学这两年来接触的编程语言C、C++、python、汇编语言等课程的学习都是在控制台应用层面上的,并没有实际直接面向应用实际地去实现具体的功能,并能够在运行代码后立即看到渲染的结果,即想要实现的功能呈现。在学习了WinForms应用后,我才更直观地看到了C#语言在很多功能的实现上的强大之处。WinForms是一种基于Windows操作系统的图形用户界面(GUI)应用程序开发框架。它提供了一套完整的用户界面控件,用于快速创建Windows桌面应用程序。好,废话少说,接着往下写。
二、题目要求:
要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的NAudi.Vorbis控件
必要的控件如图所示安装:
步骤:直接右键程序,点击管理NuGet程序包,在浏览项下搜索NAudio,选择安装NAudio和NAudio.Vorbis即可。
三、代码实现思路:
①对于要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
分析如下:首先,因为Windows窗体应用平台中有内置的包可以直接引用WindowsMediaPlayer组件来播放MP3格式的音频文件。所以,对于播放MP3音频文件可以直接将选择的本地音频文件地址传给WindowsMediaPlayer组件,让该组件自动播放音乐。这个功能很方便,可以直接“拿来用”。其次,对于获取本地音频文件的地址,这里设计的是在框架中拉一个openFileDialog1组件来实现打开本地文件夹,来达到选择本地音频文件的目的。这里有一个细节,因为要打开MP3格式的音频文件,所以在写打开音频文件功能的代码里要注意限制选择音频文件的扩展名为".mp3"。另外,为了给用户呈现一个较好的用户界面来方便操作,我们在选择好要播放的音频文件时,利用label组件实时呈现出当前所选择的音频文件的名字(不包括扩展名),这样的渲染界面会有更好的效果和对于用户操作的友好性。最后,因为最可怕的程序错误就是出现异常,如果不为程序做必要的程序异常处理,等到程序最终运行出来出现没有提示信息的错误时就实在是让人头疼啊,所以,为了避免出现这个问题,我们要保证程序能够处理好可能出现的异常,如文件不存在、文件读取错误等,这里,我们可以在打开本地音频文件时设置try、catch语句进行异常处理。在这个要求1中,我们用到了几个组件:label组件(实时显示选中的MP3音频文件的名字)、listbox组件(用于即时显示MP3音频文件的地址)、button组件(用于对点击事件响应以打开选中MP3音频文件)、axWindowsMediaPlayer组件(用于实时播放选中的MP3音频文件)、openFileDialog组件(用于打开本地文件夹),另外为了给用户提供更友好的界面,我们又用了trackBar组件(用于调节音频音量大小)。
②对于要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的NAudi.Vorbis控件
分析如下:首先,和上述的MP3格式的文件不同,对于ogg格式的音频文件,我们需要用安装处理ogg格式的音频文件的包,安装步骤在题目要求里已经用图展示了,这里不再赘述哈。这里对于要求2的实现思路其实和要求1里实现播放MP3音频的思路相差无几,只是用德包和函数不同罢了,所以大家不需要有负担,还是一样的思路,主要就是把最重要的播放ogg音频文件的包的导入和使用其中的Play()函数进行ogg音频文件的播放。这里不再赘述和要求1一样的实现的细节了。使用的组件和要求1里的一样,只是button组件的名字不一样而已,要求1里我们定义为“播放MP3”,而要求2里我们定义为“播放ogg”即可。
好了,是不是感觉还挺详细易懂的。如此,代码思路讲完后,我们再一起来看一下具体各功能的实现吧。
四、具体各功能实现:
1、初始化所有组件:
public Form1()
{
InitializeComponent();
}
2、 实现按钮响应播放MP3的功能:
private void button1_Click(object sender, EventArgs e) //播放MP3音频文件
{
openFileDialog1.Filter = "选择音频|*.mp3"; //音频格式以‘;’相隔
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);
}
}
}
3、播放MP3音频文件的功能:
private void musicplay(string filename) //判断格式并播放MP3音频文件
{
string extension = Path.GetExtension(filename); //获取音频文件扩展名
if (extension==".ogg")
Console.WriteLine("this is an ogg file.");
else
{
Console.WriteLine("this is not an ogg file.");
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
4、实时显示选中的文件的地址:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e) //将音频地址显示到listbox1上
{
try
{
if (localmusiclist.Count>0)
{
axWindowsMediaPlayer1.URL=localmusiclist[listbox1.SelectedIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text=Path.GetFileNameWithoutExtension(localmusiclist[listbox1.SelectedIndex]);
}
}
catch(Exception ex)
{
MessageBox.Show("Error:"+ex.Message);
}
}
5、 实时显示音频文件名字(不包含扩展名):
private void button3_Click(object sender, EventArgs e) //将歌名显示在label1上
{
int nextIndex = listbox1.SelectedIndex+1;
if (nextIndex >=localmusiclist.Count)
{
nextIndex = 0;
}
axWindowsMediaPlayer1.URL=localmusiclist[nextIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text=Path.GetFileNameWithoutExtension(localmusiclist[listbox1.SelectedIndex]);
listbox1.SelectedIndex= nextIndex;
}
6、播放ogg格式音频文件:
private void button4_Click(object sender, EventArgs e) //播放ogg文件
{
string oggFilePath = "";
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter="播放音频|*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath=openFileDialog.FileName;
}
using (var vorbisReader = new VorbisWaveReader(oggFilePath))
{
// 创建WaveOutEvent用于播放音频
using (var waveOutEvent = new WaveOutEvent())
{
// 初始化WaveOutEvent,将vorbisReader作为音频源
waveOutEvent.Init(vorbisReader);
waveOutEvent.Play();
while (waveOutEvent.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error:"+ex.Message);
}
}
播放MP3格式的音频文件的界面如下:
五、Form1.cs代码:
using NAudio.Vorbis;
using NAudio.Wave;
namespace MusicPlayer
{
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 an ogg file.");
else
{
Console.WriteLine("this is not an ogg file.");
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
private void button1_Click(object sender, EventArgs e) //播放MP3文件
{
openFileDialog1.Filter = "选择音频|*.mp3"; //音频格式以‘;’相隔
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) //将音频地址显示到listbox1上
{
try
{
if (localmusiclist.Count>0)
{
axWindowsMediaPlayer1.URL=localmusiclist[listbox1.SelectedIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text=Path.GetFileNameWithoutExtension(localmusiclist[listbox1.SelectedIndex]);
}
}
catch(Exception ex)
{
MessageBox.Show("Error:"+ex.Message);
}
}
private void trackBar1_Scroll(object sender, EventArgs e) //音量调节
{
axWindowsMediaPlayer1.settings.volume=trackBar1.Value;
label2.Text=trackBar1.Value+"%";
}
private void button2_Click(object sender, EventArgs e) //停止音乐
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
private void button3_Click(object sender, EventArgs e) //将歌名显示在label1上
{
int nextIndex = listbox1.SelectedIndex+1;
if (nextIndex >=localmusiclist.Count)
{
nextIndex = 0;
}
axWindowsMediaPlayer1.URL=localmusiclist[nextIndex];
musicplay(axWindowsMediaPlayer1.URL);
label1.Text=Path.GetFileNameWithoutExtension(localmusiclist[listbox1.SelectedIndex]);
listbox1.SelectedIndex= nextIndex;
}
private void button4_Click(object sender, EventArgs e) //播放ogg文件
{
string oggFilePath = "";
try
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter="播放音频|*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath=openFileDialog.FileName;
}
using (var vorbisReader = new VorbisWaveReader(oggFilePath))
{
// 创建WaveOutEvent用于播放音频
using (var waveOutEvent = new WaveOutEvent())
{
// 初始化WaveOutEvent,将vorbisReader作为音频源
waveOutEvent.Init(vorbisReader);
waveOutEvent.Play();
while (waveOutEvent.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error:"+ex.Message);
}
}
}
}
六、Form1.Desiner.cs代码如下:
namespace MusicPlayer
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
listbox1 = new ListBox();
axWindowsMediaPlayer1 = new AxWMPLib.AxWindowsMediaPlayer();
button1 = new Button();
openFileDialog1 = new OpenFileDialog();
label1 = new Label();
trackBar1 = new TrackBar();
label2 = new Label();
button2 = new Button();
button3 = new Button();
button4 = new Button();
((System.ComponentModel.ISupportInitialize)axWindowsMediaPlayer1).BeginInit();
((System.ComponentModel.ISupportInitialize)trackBar1).BeginInit();
SuspendLayout();
//
// listbox1
//
listbox1.FormattingEnabled = true;
listbox1.Location = new Point(52, 122);
listbox1.Name = "listbox1";
listbox1.Size = new Size(696, 562);
listbox1.TabIndex = 0;
listbox1.SelectedIndexChanged += listBox1_SelectedIndexChanged;
//
// axWindowsMediaPlayer1
//
axWindowsMediaPlayer1.Enabled = true;
axWindowsMediaPlayer1.Location = new Point(129, 734);
axWindowsMediaPlayer1.Name = "axWindowsMediaPlayer1";
axWindowsMediaPlayer1.OcxState = (AxHost.State)resources.GetObject("axWindowsMediaPlayer1.OcxState");
axWindowsMediaPlayer1.Size = new Size(536, 45);
axWindowsMediaPlayer1.TabIndex = 1;
//
// button1
//
button1.Font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button1.Location = new Point(834, 213);
button1.Name = "button1";
button1.Size = new Size(150, 46);
button1.TabIndex = 2;
button1.Text = "播放MP3";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// openFileDialog1
//
openFileDialog1.FileName = "openFileDialog1";
//
// label1
//
label1.AutoSize = true;
label1.ForeColor = Color.FromArgb(128, 128, 255);
label1.Location = new Point(52, 72);
label1.Name = "label1";
label1.Size = new Size(110, 31);
label1.TabIndex = 3;
label1.Text = "音乐名称";
//
// trackBar1
//
trackBar1.Location = new Point(782, 476);
trackBar1.Maximum = 100;
trackBar1.Name = "trackBar1";
trackBar1.Orientation = Orientation.Vertical;
trackBar1.Size = new Size(90, 208);
trackBar1.TabIndex = 4;
trackBar1.TickStyle = TickStyle.TopLeft;
trackBar1.Value = 20;
trackBar1.Scroll += trackBar1_Scroll;
//
// label2
//
label2.AutoSize = true;
label2.ForeColor = Color.Black;
label2.Location = new Point(861, 567);
label2.Name = "label2";
label2.Size = new Size(82, 31);
label2.TabIndex = 5;
label2.Text = "label2";
//
// button2
//
button2.Font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button2.Location = new Point(1052, 213);
button2.Name = "button2";
button2.Size = new Size(150, 46);
button2.TabIndex = 6;
button2.Text = "停止音乐";
button2.UseVisualStyleBackColor = true;
button2.Click += button2_Click;
//
// button3
//
button3.Font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button3.Location = new Point(834, 302);
button3.Name = "button3";
button3.Size = new Size(150, 46);
button3.TabIndex = 7;
button3.Text = "下一曲";
button3.UseVisualStyleBackColor = true;
button3.Click += button3_Click;
//
// button4
//
button4.Font = new Font("微软雅黑", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button4.Location = new Point(834, 122);
button4.Name = "button4";
button4.Size = new Size(150, 46);
button4.TabIndex = 8;
button4.Text = "播放ogg";
button4.UseVisualStyleBackColor = true;
button4.Click += button4_Click;
//
// Form1
//
AutoScaleDimensions = new SizeF(14F, 31F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1375, 914);
Controls.Add(button4);
Controls.Add(button3);
Controls.Add(button2);
Controls.Add(label2);
Controls.Add(trackBar1);
Controls.Add(label1);
Controls.Add(button1);
Controls.Add(axWindowsMediaPlayer1);
Controls.Add(listbox1);
Name = "Form1";
Text = "Form1";
((System.ComponentModel.ISupportInitialize)axWindowsMediaPlayer1).EndInit();
((System.ComponentModel.ISupportInitialize)trackBar1).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private ListBox listbox1;
private AxWMPLib.AxWindowsMediaPlayer axWindowsMediaPlayer1;
private Button button1;
private OpenFileDialog openFileDialog1;
private Label label1;
private TrackBar trackBar1;
private Label label2;
private Button button2;
private Button button3;
private Button button4;
}
}
七、整体设计的应用界面如下:
八、总结:
这是第二次的Windows课程设计,是对于WinForms窗体应用的练习,这也是进阶的C#编程学习。在完成这个实验的过程中,也遇到了一些小问题,比如在播放ogg文件时,当时找了很多的函数,希望可以实现播放ogg音频文件的功能,但是都没有成功,后来老师讲解了一种通过安装第三方包NAudio.Vorbis和NAudio.Wave来实现,应用了之后果然可以将ogg文件播放出来,也是豁然开朗了。但是其实就是这样的问题耗了我很长时间,所以就想我们老师跟我们说的一样,当我们遇到这样的问题时就是可以直接访问AI,通过这些工具实现我们需要的功能,但最重要的是我们要学会自己去思考这些代码实现的逻辑,要能够领会这些实现思想。说白了,咱们还是要多动手敲代码练习,才能形成更有效的肌肉记忆。所以,同志们,从现在开始,加油码起来吧!
最后,此次C#程序MusicPlayer的完整代码和解决方案的GitHub地址在这里放给大家:GitHub - zzhhyyrr/awesome_set