一、项目背景与准备
在开始编码之前,我们需要了解一些背景知识和准备工作。首先,为了播放MP3文件,我们将使用Windows Media Player(WMP)组件。而对于OGG格式,我们将借助NAudio库,它是一个开源的音频处理库,支持多种音频格式的解码和播放。
在开始之前,请确保你的开发环境中已经安装了必要的库和组件。对于NAudio,你可以通过NuGet包管理器来安装。
然后在工具箱里添加对应的工具
Label:显示当前播放。
Listbox:显示选择播放的音乐列表。
Trackbar:调节音量。
WindowsMediaPlayer:播放常规音乐格式(ogg格式无法用此播放)。
openFileDialog:用于选择音乐文件。
button1:用于添加歌曲”
button2:用于“停止播放”
button3:用于“播放下一首”
button4:用于“播放歌曲”
二、项目结构与初始化
我们的音乐播放器将基于Windows Forms来构建。在Visual Studio中创建一个新的Windows Forms应用程序项目,并添加必要的UI元素,如按钮、列表框和标签。
在项目的初始化部分,我们需要实例化Windows Media Player对象和NAudio的WaveOutEvent对象。这些对象将在后续的音乐播放过程中起到关键作用。
以下是我的代码和ui界面
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using NAudio.Vorbis;
using NAudio.Wave;
using WMPLib;
namespace 音乐播放器
{
public partial class Form1 : Form
{
private WindowsMediaPlayer wmp; // Windows Media Player 实例
private WaveOutEvent waveOut; // NAudio 播放实例
private List<string> fileList;// 音乐文件列表
private int currentIndex = -1; // 当前播放文件的索引
public Form1()
{
InitializeComponent();
InitializeMediaPlayer();
fileList = new List<string>();
}
private void InitializeMediaPlayer()
{
wmp = new WindowsMediaPlayer();
waveOut = new WaveOutEvent();
}
private void PlayCurrentSong()
{
if (currentIndex >= 0 && currentIndex < fileList.Count)
{
string filePath = fileList[currentIndex];
string fileExt = Path.GetExtension(filePath).ToLower();
if (fileExt == ".mp3")
{
wmp.URL = filePath;
wmp.controls.play();
}
else if (fileExt == ".ogg")
{
Task.Run(() => PlayOggFile(filePath));
}
label1.Text = "当前播放: " + Path.GetFileName(filePath);
}
}
private void PlayOggFile(string filePath)
{
using (var vorbisReader = new VorbisWaveReader(filePath))
{
waveOut.Init(vorbisReader);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(1000); // 在后台线程中等待,不会阻塞UI线程
}
}
}
// 添加歌曲按钮事件
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "音频文件 (*.mp3, *.ogg)|*.mp3;*.ogg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// 假设我们每次只添加一个文件,而不是多选
string filePath = openFileDialog.FileName;
// 将文件路径添加到歌曲列表
AddSongToListBox(filePath);
// 更新当前播放索引(如果当前列表为空,则设置为0)
if (fileList == null || fileList.Count == 0)
{
currentIndex = 0;
}
}
}
}
private void AddSongToListBox(string filePath)
{
fileList.Add(filePath); // 直接添加到List中
listBoxSongs.Items.Add(filePath); // 更新ListBox
listBoxSongs.SelectedIndex = listBoxSongs.Items.Count - 1; // 选中新添加的歌曲
}
private void button2_Click_1(object sender, EventArgs e)
{
if (wmp != null && wmp.playState == WMPPlayState.wmppsPlaying)
{
wmp.controls.pause(); // 暂停MP3文件的播放
}
if (waveOut != null && waveOut.PlaybackState == PlaybackState.Playing)
{
waveOut.Stop(); // 对于OGG文件,我们只能停止播放
// 如果您想要之后从停止的位置恢复播放,您需要自己记录停止的位置
// 并在之后恢复播放时使用这个位置
}
label1.Text = "当前播放: 已暂停/停止";
}
//播放歌曲事件
private void button4_Click_1(object sender, EventArgs e)
{
PlayCurrentSong();
}
//播放下一首事件
private void button3_Click_1(object sender, EventArgs e)
{
currentIndex++;
if (currentIndex >= fileList.Count)
{
currentIndex = 0; // 如果已经是最后一首,则循环到第一首
}
PlayCurrentSong();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
三、代码的重难点
重难点一:媒体播放的兼容性
难点:
- 支持多种音频格式,如MP3和OGG,需要处理不同格式的解码和播放。
实现:
- 使用
WindowsMediaPlayer
来播放MP3文件,因为它内置了对MP3格式的支持。 - 对于OGG格式,采用了NAudio库中的
VorbisWaveReader
来进行解码,并使用WaveOutEvent
来进行播放。
重难点二:多线程处理
难点:
- OGG文件的播放需要在一个单独的线程中进行,以避免阻塞UI线程。
实现:
- 使用
Task.Run
来启动一个新的后台任务,专门用于播放OGG文件。 - 在播放OGG的后台任务中,使用一个循环来检查播放状态,并适当地暂停线程,以避免占用过多CPU资源。
重难点三:UI与后台任务的交互
难点:
- 确保UI线程能够安全地更新,同时后台播放任务能够正常运行。
实现:
- 使用
Invoke
或BeginInvoke
来在UI线程上执行更新操作,如更新标签文本或列表框的选中项。 - 避免在后台线程中直接操作UI元素,以防止线程冲突。
重难点四:资源管理
难点:
- 确保音频文件播放完毕后,相关资源得到正确释放,避免内存泄漏。
实现:
- 使用
using
语句来确保VorbisWaveReader
对象在使用完毕后被正确释放。 - 对于
WaveOutEvent
对象,在播放完毕后调用Stop
和Dispose
方法来释放资源。
四、用户交互与界面更新
除了播放功能外,我们的播放器还需要响应用户的操作,如添加歌曲、暂停/播放、切换到下一首歌曲等。这些操作都需要更新UI界面,并可能涉及到播放状态的改变。
例如,当用户点击“添加歌曲”按钮时,我们会弹出一个文件选择对话框,让用户选择要添加的歌曲。选中的歌曲路径将被添加到歌曲列表中,并显示在ListBox控件中。
五、总结与展望
通过这个项目,我们不仅学习了如何使用Windows Media Player和NAudio库来播放不同格式的音频文件,还实践了如何在Windows Forms应用程序中实现用户交互和界面更新。这个简单的音乐播放器可以作为一个起点,你可以根据自己的需求添加更多的功能,如歌词显示、均衡器调整等。