目录
作品展示
特别鸣谢爆炎战神fzq(CSDN用户小菜一颗葱 )在开发设计过程中进行的UI构建和框架教学。
在线下载
添加音乐
暂停/播放
文件下载功能(带多线程和网络连接)
实现一个简单的多线程文件下载类 DownLoadFile
使用多线程技术,我们可以同时下载多个文件拆成多个部分并行下载,从而提升下载速度和效率。
类和成员变量
在 Form1
类中,我们定义了一些成员变量,包括文件列表、音频播放器设备、播放状态等:
public partial class Form1 : Form
{
string[] files;
private IWavePlayer waveOutDevice;
private VorbisWaveReader vorbisWaveReader;
private bool isPlaying = false; // 播放状态
private bool isPaused = false; // 暂停状态
private long pausePosition = 0; // 暂停位置
private string currentFile = string.Empty; // 当前文件
private DownLoadFile dlf = new DownLoadFile(); // 创建下载文件对象
public download d1;
public Form f1;
List<string> localmusiclist = new List<string> { };
}
类的定义与初始化
首先,我们定义了 DownLoadFile
类。该类主要包含以下成员:
ThreadNum
: 表示默认的下载线程数,默认为3。list
: 用于存储线程的列表。doSendMsg
: 用于发送下载状态消息的委托事件。
在类的构造函数中,我们将 doSendMsg
事件与 Change
方法绑定,以便在下载过程中处理各种状态变化。
namespace Gac
{
public class DownLoadFile
{
public int ThreadNum = 3;
List<Thread> list = new List<Thread>();
public DownLoadFile()
{
doSendMsg += Change;
}
private void Change(DownMsg msg)
{
if (msg.Tag == DownStatus.Error || msg.Tag == DownStatus.End)
{
StartDown(1);
}
}
}
}
添加下载任务
AddDown
方法用于向下载任务列表中添加新的下载任务。每个任务启动一个新的线程,并调用 download
方法执行具体的下载操作。
启动下载任务
StartDown
方法用于启动指定数量的下载任务。它会遍历任务列表,启动未开始或已暂停的线程。
下载实现
download
方法是下载操作的核心实现。它首先发送一个开始下载的消息,然后创建一个 FileDownloader
对象来执行实际的下载操作。下载进度通过 DownloadProgressListener
来监听和发送。
首先要把每一个链接用“|”分成两部分,前面的应该是文件名字,后面的是真正的URL。如果处理过后的数组的长度是二,那么就是正确的格式,就可以接着对这个链接进行处理。再利用前面创键好的DownLoadFile类dlf进行下载。
DownMsg
类用于表示下载过程中的各种状态消息,包括开始、进度更新和错误信息。通过 doSendMsg
事件,我们可以将这些消息发送给注册的监听器,以便实时更新UI或处理其他逻辑。
for (int i = 0; i < lines.Length; i++)
{
//按“|”分割每一行,去除空条目
string[] line = lines[i].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
//如果分割后的数组长度为2,表示行格式正确
if (line.Length == 2)
{
// 获取URL路径并进行编码
string path = Uri.EscapeUriString(line[1]);
// 获取文件名
string filename = line[0];
// 定义下载目录
string dir = @"C:\Users\Administrator\Desktop\新建文件夹 (2)";
// 创建一个新的ListViewItem并添加到listView1中
ListViewItem item = listView1.Items.Add(new ListViewItem(new string[] {
(listView1.Items.Count + 1).ToString(), // 序号
filename, // 文件名
"0", // 已下载大小
"0", // 文件总大小
"0%", // 下载进度
"0", // 下载速度
"0", // 剩余时间
DateTime.Now.ToString(), // 开始时间
"等待中", // 状态
line[1] // 下载链接
}));
// 获取新添加项的索引
int id = item.Index;
// 添加下载任务
dlf.AddDown(path, dir, id, filename);
}
}
// 开始下载
dlf.StartDown();
}
初始化和文件选择
在 Form1
的构造函数中,我们初始化下载对象和窗体,并定义了一个方法来选择本地音乐文件:
public Form1()
{
InitializeComponent();
d1 = new download();
f1 = new Form();
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "选择音频|*mp3;*.wav;*.flac;*.ogg;*.m4a;";
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)
{
string y = Path.GetFileName(x);
listBox1.Items.Add(y);
localmusiclist.Add(x);
}
}
}
音乐播放功能
musicplay
方法用于播放选择的音乐文件。它根据文件扩展名决定使用 NAudio.Vorbis
还是 Windows Media Player
来播放音频:
private void musicplay(string filename)
{
string extension = Path.GetExtension(filename).ToLowerInvariant();
if (extension == ".ogg")
{
//ogg文件处理
}
else
{
//非ogg文件处理
}
}
播放和暂停功能(处理方式和fzq完全不同)
在我们的音乐播放器应用程序中,播放和暂停是两个核心功能。通过一个按钮(button6
)来控制这两个功能,我们可以实现用户友好的播放体验。以下是详细的代码解析和说明。button6_Click
方法处理了播放和暂停的逻辑。根据当前的播放状态(isPlaying
)和暂停状态(isPaused
),它决定是继续播放、暂停播放还是开始新播放。
-
检查当前播放状态:
if (isPlaying)
: 首先检查当前是否正在播放音频文件。如果isPlaying
为true
,表示当前有音频文件正在播放。
-
处理暂停状态:
-
if (isPaused)
: 如果isPlaying
为true
且isPaused
为true
,表示当前音频处于暂停状态,需要继续播放。waveOutDevice != null
: 如果当前使用的是NAudio
处理的 OGG 文件,调用waveOutDevice.Play()
继续播放。else
: 如果使用的是Windows Media Player
,调用axWindowsMediaPlayer1.Ctlcontrols.play()
继续播放。- 将
isPaused
设置为false
,并更新按钮文本为“暂停”。
-
else
: 如果isPlaying
为true
且isPaused
为false
,表示当前音频正在播放,需要暂停。waveOutDevice != null
: 如果当前使用的是NAudio
处理的 OGG 文件,记录当前播放位置pausePosition = vorbisWaveReader.Position
,然后调用waveOutDevice.Pause()
暂停播放。else
: 如果使用的是Windows Media Player
,调用axWindowsMediaPlayer1.Ctlcontrols.pause()
暂停播放。- 将
isPaused
设置为true
,并更新按钮文本为“播放”。
-
-
处理播放状态:
else
: 如果isPlaying
为false
,表示当前没有音频文件在播放,需要开始新播放。if (!string.IsNullOrEmpty(currentFile))
: 如果currentFile
不为空,表示有一个当前文件已经加载,只需要调用musicplay(currentFile)
开始播放。else if (localmusiclist.Count > 0)
: 如果currentFile
为空,但localmusiclist
有内容,表示用户已经选择了一些文件。调用musicplay(localmusiclist[0])
播放列表中的第一个文件,并更新界面显示。- 将
isPlaying
设置为true
,并更新按钮文本为“暂停”。
private void button6_Click(object sender, EventArgs e)
{
if (isPlaying)
{
if (isPaused)
{
// 继续播放
if (waveOutDevice != null)
{
waveOutDevice.Play();
}
else
{
axWindowsMediaPlayer1.Ctlcontrols.play();
}
isPaused = false;
button6.Text = "暂停";
}
else
{
// 暂停播放
if (waveOutDevice != null)
{
pausePosition = vorbisWaveReader.Position; // 记录暂停位置
waveOutDevice.Pause();
}
else
{
axWindowsMediaPlayer1.Ctlcontrols.pause();
}
isPaused = true;
button6.Text = "播放";
}
}
else
{
if (!string.IsNullOrEmpty(currentFile))
{
musicplay(currentFile);
isPlaying = true;
button6.Text = "暂停";
}
else if (localmusiclist.Count > 0)
{
musicplay(localmusiclist[0]);
label1.Text = "正在播放:" + Path.GetFileNameWithoutExtension(localmusiclist[0]);
listBox1.SelectedIndex = 0;
isPlaying = true;
button6.Text = "暂停";
}
}
}
文末,再次鸣谢fzq的帮助,他帮我踩了好多坑(doge)以及完成模型搭建和UI设计,fzq文章可见Windows程序设计作业——带有在线下载功能的MusicPlayer-CSDN博客
总结
本项目完成音乐播放器实现网络连接,并且在线并发下载文件,且在进行在线下载,对比其他同学的新点在于,我可以只使用一个button,可以通过这个按钮进行控制播放和暂停。这样用户可以方便地控制音频的播放和暂停。该播放器支持多种音频格式,并且通过简单的逻辑实现了播放、暂停、停止和音量控制等基本功能。希望本文对你实现类似的功能有所帮助。