一、题目要求
要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控件
二、答题思路
想要编写一个C#程序来实现音乐文件的播放功能,我们首先需要在VS里新建一个窗体应用
新建成功后点开,我们会看到如下界面
想要实现播放音乐的功能,我们需要一个listBox控件窗口来显示我们的音乐播放列表;还需要一个音乐播放的暂停键和进度条,这个可以通过WindowsMediaPlayer组件实现,但该组件可能需要我们自己手动添加至工具箱中,我们可以通过‘工具箱’—‘常规’—‘指针’—‘选择项’—‘COM组件’下拉找到该组件;然后,我们还需要几个常见的操作按钮Button,例如‘选择歌曲’、‘下一首’、‘停止播放’等。为了能够在listBox1控件中显示播放的歌单列表,我们还需要插入一个label控件来为listBox1控件提供运行时的信息或说明性文字。
三、播放MP3文件的代码实现
在创建完窗口后,我们就要开始依次用代码实现各窗口和按钮的功能了。
1.listBox1
listBox1
控件需要拥有的功能是允许用户通过 listBox1
选择要播放的音乐,并在选择发生变化时自动更新 axWindowsMediaPlayer1
控件以播放所选音乐,并在 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]);
}
}
代码的具体功能解释如下:
- 首先,检查
localmusiclist中
是否有元素,即是否有本地音乐文件路径被添加到该播放列表中; - 如果
localmusiclist
中有元素,代码将获取listBox1
当前选中项(即用户选择的音乐)对应的索引,并使用该索引从localmusiclist
中获取相应的音乐文件路径。然后将这个路径设置为axWindowsMediaPlayer1
的URL
属性,从而告诉播放器要播放哪首音乐; musicplay(axWindowsMediaPlayer1.URL);
这行代码尝试调用一个名为musicplay
的函数,并传递axWindowsMediaPlayer1
的URL
属性(即当前选定的音乐文件路径)作为参数。然后执行一些与音乐播放相关的额外操作,例如‘选择歌曲’、‘下一首’、‘停止播放’等;- 最后,从当前选定的音乐文件路径中提取文件名,并将该文件名设置为
label1
的文本。这样,用户就可以在界面上看到当前正在播放的音乐的名称。
2.‘选择歌曲’按钮
private void button1_Click(object sender, EventArgs e)
{
//设置 openFileDialog1的过滤器,
//以便用户只能选择 .mp3、.flac 或 .wav 类型的音频文件
openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav";
openFileDialog1.Multiselect = true;
//显示文件对话框,并检查用户是否选择了文件
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//清空,以便添加新选择的文件
localmusiclist.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(x);
localmusiclist.Add(x);
}
}
}
3.‘下一首’按钮
实现代码即解释如下:
private void button3_Click(object sender, EventArgs e)
{
if (localmusiclist.Count > 0)
{
int index = listBox1.SelectedIndex + 1;
// 如果当前没有选中的项,或者已经是最后一首歌曲,则从第一首开始
if (index>=localmusiclist.Count())
{
index = 0;
}
// 设置Windows Media Player的URL为下一首歌曲的路径
axWindowsMediaPlayer1.URL = localmusiclist[index];
// 假设musicplay是一个自定义方法来处理播放逻辑,可以调用它
musicplay(axWindowsMediaPlayer1.URL);
// 更新标签以显示当前播放的歌曲名
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
// 更新ListBox的选中项,以反映当前播放的歌曲
listBox1.SelectedIndex = index;
}
}
4.‘停止播放’按钮
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
写完以上代码后,我们就可以实现将本地MP3音乐导入系统并进行播放的功能。为了丰富我们的播放功能,我们还可以额外添加一个trackBar控件用来调节播放音乐的音量,实现代码如下:
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume= trackBar1.Value;
}
他的最大最小音量以及音量间隔值、外观可以通过属性界面调整
5.运行结果:
播放MP3文件的功能实现成功后,接下来我们就要开始尝试播放ogg文件了。
四、播放ogg文件的代码实现
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
//设置了文件对话框的过滤器,只能选择.ogg 类型的文件。
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
// 替换为OGG文件路径
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);
}
}
// 等待播放完成,或者根据需要添加其他逻辑
using (var vorbisStream = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisStream);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
}
五、整体代码
using NAudio;
using NAudio.Wave.SampleProviders;
using NAudio.Wave;
using NAudio.Vorbis;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsMusic
{
public partial class Form1 : Form
{
// 定义 OpenFileDialog 对象
private OpenFileDialog openFileDialog1 = new OpenFileDialog();
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
{ axWindowsMediaPlayer1.Ctlcontrols.play(); }
}
private void button1_Click(object sender, EventArgs e)
{
//设置 openFileDialog1的过滤器,
//以便用户只能选择 .mp3、.flac 或 .wav 类型的音频文件
openFileDialog1.Filter = "选择音频|*.mp3;*.flac;*.wav";
openFileDialog1.Multiselect = true;
//显示文件对话框,并检查用户是否选择了文件
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//清空,以便添加新选择的文件
localmusiclist.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(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 axWindowsMediaPlayer1_Enter(object sender, EventArgs e)
{
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume= trackBar1.Value;
}
private void label1_Click(object sender, EventArgs e)
{
}
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;
}
// 设置Windows Media Player的URL为下一首歌曲的路径
axWindowsMediaPlayer1.URL = localmusiclist[index];
// 假设musicplay是一个自定义方法来处理播放逻辑,可以调用它
musicplay(axWindowsMediaPlayer1.URL);
// 更新标签以显示当前播放的歌曲名
label1.Text = Path.GetFileNameWithoutExtension(localmusiclist[index]);
// 更新ListBox的选中项,以反映当前播放的歌曲
listBox1.SelectedIndex = index;
}
}
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
//设置了文件对话框的过滤器,只能选择.ogg 类型的文件。
openFileDialog.Filter = "打开音频|*.ogg";
string oggFilePath = "";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
oggFilePath = openFileDialog.FileName;
}
// 替换为OGG文件路径
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);
}
}
// 等待播放完成,或者根据需要添加其他逻辑
using (var vorbisStream = new VorbisWaveReader(oggFilePath))
{
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisStream);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
}
}
}