目录
一、作业内容
请编写一个C#程序,实现音乐文件的播放功能。
要求1:
1. 程序应能够读取MP3文件,并播放其中的音频。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用WindowsMediaPlayer控件
要求2:
1. 程序应能够播放ogg文件。
2. 程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能可以使用Nuget程序包中的Naudi.Vorbis控件
二、解题
题目中有两个主要的方面
1.能够读取mp3文件,播放(使用WindowsMediaPlayer控件)
2.能够读取ogg文件,播放(Nuget程序包中的Naudi.Vorbis控件)
还有一些提高代码健壮性,用户体验性的要求
程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
程序应具有良好的用户界面,方便用户进行操作。
程序应具有良好的兼容性,能在不同版本的C#中正常运行。
明确要求之后,我们就来解决问题就行啦~
(一)、读取mp3(包含MP3.Flac格式等)文件
首先我们想要音乐播放器能正确播放音乐,肯定得有文件来播放吧,所以我们的第一步就是把怎么读文件。话不多说,上代码,边看代码边分析。
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "音频文件|*.mp3;*.wav;*.flac";
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);
}
}
}
在音乐播放器中,肯定要有选择文件按钮,不然文件怎么进去呢?在此处,就使用了一个button1控件,读入文件(由于ogg文件需要单独解码),所以我们只需要负责将.mp3;.wav;.flac等几种基础文件读入就行。
此处用了openFileDialog控件来读入文件,并将读入的文件名,以列表的形式展现在listbox1上面。
(二)播放mp3文件
读了文件,将歌名展示在listbox上,不得开始播放歌曲了?上代码!!!
private void musicplay(string filename)
{
try
{
string extension = Path.GetExtension(filename).ToLower();
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
catch (Exception ex)
{
MessageBox.Show($"播放音频文件时发生错误: {ex.Message}", "播放错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
在日常播放歌曲中,要打开音乐播放APP,在这里我们同样希望,有个控件,能为我们解码,为我们担任播放音乐这个任务。这里,就要介绍windowsMediaPlayer控件了。这里就只用到了这个控件播放音乐的作用,具体操作和玩花活,可以看下面的博客。
C#winform小型本地自定义播放器 插入视频播放控件与简单运用(Windows Media Player)_winform windowsmediaplayer-CSDN博客https://blog.csdn.net/ou2914671339/article/details/134996388?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171532346316800188539711%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171532346316800188539711&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-134996388-null-null.142^v100^pc_search_result_base5&utm_term=windowsMediaPlayer&spm=1018.2226.3001.4187这里所运用到的,就是将文件的URL地址,送到控件里面播放就行。至此播放的基础任务就已经完成了。我们接着,想让这个音乐播放器更好用一点,我们先来借鉴一下,网易云的做法。
有播放和上一曲,下一曲,暂停,调节音量的作用,我们现在就让这个音乐播放器更好用一点。
1.暂停
private void button2_Click(object sender, EventArgs e)
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
让控件停止,没什么好说的
2.下一曲
private void button3_Click(object sender, EventArgs e)
{
int nextIndex = listBox1.SelectedIndex + 1;
if (nextIndex >= localmusiclist.Count)
{
nextIndex = 0;
}
listBox1.SelectedIndex = nextIndex; // 更新列表框选择
}
在这个里面,我们就不断让歌单里面指的歌曲加1就行;但是,我们会遇到一个小问题,当列表歌曲已经是最后一曲时,我们需要跳到第一首,实现列表循环,在这,如果下一个角标大于总歌数的时候,直接把下标设为0,实现跳到第一曲。
3.音量大小调节
// 音量调节事件
private void trackBar1_Scroll(object sender, EventArgs e)
{
axWindowsMediaPlayer1.settings.volume = trackBar1.Value;
label2.Text = trackBar1.Value + "%";
}
此处,我们利用了一个trackBar来实现音量的滑动,同时在label上显示音量大小。
当然,我们可以把所有功能集成到一起为 axWindowsPlayer来实现
(三)播放ogg文件
完成了基础文件的读取与播放,我们也需要对于一些特殊文件ogg来进行播放。
这里要介绍一些特殊控件:Nuget程序包中的Naudi.Vorbis控件
C# Winform编程 NAudio 音频库_naudio音频库-CSDN博客https://blog.csdn.net/songyulong8888/article/details/134442675?ops_request_misc=&request_id=&biz_id=102&utm_term=Nuget%E7%A8%8B%E5%BA%8F%E5%8C%85%E4%B8%AD%E7%9A%84Naudi.Vorbis%E6%8E%A7%E4%BB%B6&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-134442675.142^v100^pc_search_result_base9&spm=1018.2226.3001.4187这个音频库的使用和安装就在上面了。但是Vorbis控件,是Naudi中一个比较冷门的控件,这是问文心一言才找到的这个库。
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "选择音频|*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
string oggFilePath = openFileDialog.FileName;
localmusiclist.Add(oggFilePath); // 添加到音乐列表
listBox1.Items.Add(Path.GetFileName(oggFilePath)); // 添加到 ListBox 显示
// 自动选择新添加的文件并播放
listBox1.SelectedIndex = listBox1.Items.Count - 1;
musicplay(oggFilePath);
// 更新正在播放的文件名显示
label1.Text = Path.GetFileName(oggFilePath);
}
catch (Exception ex)
{
MessageBox.Show($"加载或播放 OGG 文件时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
这段代码只是读取ogg文件,要想成功播放它,我们还需要写一个方法。
在这我们可以想到,既然都是播放音乐,是不是可以调用一个公共的方法,来实现音乐播放?
说干就干
// 播放音乐文件,支持 OGG 特殊处理
private void musicplay(string filename)
{
try
{
string extension = Path.GetExtension(filename).ToLower();
if (extension == ".ogg")
{
axWindowsMediaPlayer1.Ctlcontrols.stop(); // 停止当前播放
using (var vorbisWaveReader = new VorbisWaveReader(filename))
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisWaveReader);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
else
{
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
catch (Exception ex)
{
MessageBox.Show($"播放音频文件时发生错误: {ex.Message}", "播放错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
这里就实现了ogg和普通文件的播放啦。
但是这里播放OGG文件有些bug(仍未解决),其中播放OGG文件中,form1主进程会无响应,导致崩溃,这里涉及到线程工作相关学习,(抱歉还没学到这,问AI没什么意义),就让这个bug留下来吧,等我会了再来解决。
三、学习心得
通过本次作业,我学会了C#运用文件操作管理的方法,对于音乐播放器的实现,有了一个完整的学习。
当然,感谢AI在我编写解释时的检查,和最后代码的核查,让我同时也掌握了AI的用法。
四、完整代码
using NAudio.Wave.SampleProviders;
using NAudio.Wave;
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;
using NAudio.Vorbis;
namespace MusicPlay
{
public partial class Form1 : Form
{
string[] files;
List<string> localmusiclist = new List<string>();
public Form1()
{
InitializeComponent();
}
// 播放音乐文件,支持 OGG 特殊处理
private void musicplay(string filename)
{
try
{
string extension = Path.GetExtension(filename).ToLower();
if (extension == ".ogg")
{
axWindowsMediaPlayer1.Ctlcontrols.stop(); // 停止当前播放
using (var vorbisWaveReader = new VorbisWaveReader(filename))
using (var outputDevice = new WaveOutEvent())
{
outputDevice.Init(vorbisWaveReader);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
System.Threading.Thread.Sleep(1000);
}
}
}
else
{
axWindowsMediaPlayer1.URL = filename;
axWindowsMediaPlayer1.Ctlcontrols.play();
}
}
catch (Exception ex)
{
MessageBox.Show($"播放音频文件时发生错误: {ex.Message}", "播放错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 打开文件对话框,选择音频文件
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "音频文件|*.mp3;*.wav;*.flac";
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 && listBox1.SelectedIndex >= 0)
{
string selectedFile = localmusiclist[listBox1.SelectedIndex];
musicplay(selectedFile);
label1.Text = Path.GetFileName(selectedFile);
}
}
// 音量调节事件
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)
{
int nextIndex = listBox1.SelectedIndex + 1;
if (nextIndex >= localmusiclist.Count)
{
nextIndex = 0;
}
listBox1.SelectedIndex = nextIndex; // 更新列表框选择
}
// 播放 OGG 文件的专用按钮
private void button4_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "选择音频|*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
string oggFilePath = openFileDialog.FileName;
localmusiclist.Add(oggFilePath); // 添加到音乐列表
listBox1.Items.Add(Path.GetFileName(oggFilePath)); // 添加到 ListBox 显示
// 自动选择新添加的文件并播放
listBox1.SelectedIndex = listBox1.Items.Count - 1;
musicplay(oggFilePath);
// 更新正在播放的文件名显示
label1.Text = Path.GetFileName(oggFilePath);
}
catch (Exception ex)
{
MessageBox.Show($"加载或播放 OGG 文件时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}