代码实现:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using DotNetSimple.MusicPlayer.Plus;
using System.IO;
using System.Xml;
//BASS解码器引用
using Un4seen.Bass;
using System.Diagnostics;
using System.Threading;
using System.Net;
namespace DotNetSimple.MusicPlayer
{
public partial class mainFrm : TempleteFrm
{
//垃圾回收声明
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(int hProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
#region Enum 枚举类型
/// <summary>
/// 播放器状态
/// </summary>
private enum PlayerState
{
/// <summary>
/// 停止模式
/// </summary>
Stop,
/// <summary>
/// 播放模式
/// </summary>
Play,
/// <summary>
/// 暂停模式
/// </summary>
Pause
}
/// <summary>
/// 播放模式选择
/// </summary>
private enum PlayMode
{
/// <summary>
/// 单曲播放
/// </summary>
SinglePlay,
/// <summary>
/// 单曲循环
/// </summary>
SingleCycle,
/// <summary>
/// 列表循环
/// </summary>
CyclePlay,
/// <summary>
/// 顺序播放
/// </summary>
OrderPlay,
/// <summary>
/// 随机播放
/// </summary>
RandomPlay
}
#endregion
#region 当前曲目参数
/// <summary>
/// 当前播放曲目索引
/// </summary>
private int changeValue = 0;
//记录当前播放器的状态。
private PlayerState playerState = PlayerState.Stop;
/// <summary>
/// 播放模式
/// </summary>
private PlayMode playModel = PlayMode.SinglePlay;
/// <summary>
/// 播放器实例
/// </summary>
public BassEngine bassPlayer = null;
/// <summary>
/// Lrc文件时间组
/// </summary>
private string[] Ltime = new string[200];
private string[] Ltext = new string[200];
private string bigTime;
private string smallTime;
private bool nextLrc = false;
#endregion
#region 其他
protected internal AnchorStyles StopAanhor = AnchorStyles.None;
/// <summary>
/// 音乐窗实例
/// </summary>
protected internal musicMiniFrm musicMiniFrm;
/// <summary>
/// 桌面歌词窗
/// </summary>
protected internal DiskLrcFrm diskLrcFrm;
/// <summary>
/// 歌词秀窗体实例
/// </summary>
protected internal LyricsFrm lyricsFrm;
/// <summary>
/// 歌词搜索下载类
/// </summary>
protected internal LyricsHelper lyricsHelper;
/// <summary>
/// 歌词匹配类
/// </summary>
protected internal LrcRegex lrcRegex = new LrcRegex();
/// <summary>
/// 当前音乐列表类型
/// </summary>
protected internal string tabMusicType = "默认列表";
/// <summary>
/// 搜索歌词线程
/// </summary>
protected internal Thread threadSearchLrc;
#endregion
public mainFrm()
{
InitializeComponent();
#region 初始化配置信息
LoadDiskLrcPanel();
this.lyricsHelper = new LyricsHelper(false);
this.lyricsHelper.InitializeProxy += new EventHandler(InitializeProxy);
this.lyricsHelper.WebException += new EventHandler(WebException);
this.lyricsHelper.SelectSong += new EventHandler(SelectSong);
try
{
this.bassPlayer = BassEngine.Instance;
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
return;
}
this.lvMusicListView.SmallImageList = new ImageList();
this.lvMusicListView.SmallImageList.ImageSize = new Size(1, 22);
IniFiles ini = new IniFiles(Application.StartupPath + "\\Ini\\config.ini");
int valume = int.Parse(ini.ReadValue("Player", "Valume"));
//初始化音量默认参数
this.bassPlayer.Volume = this.tbValume.Value = valume;
//获取配置文件 - 播放模式
int playModel = int.Parse(ini.ReadValue("Player", "PlayModel"));
switch (playModel)
{
case (int)PlayMode.CyclePlay:
this.tsmiCyclePlay.Checked = true;
this.playModel = PlayMode.CyclePlay;
this.tipTitle.SetToolTip(this.pbPlayerModel, this.tsmiCyclePlay.Text);
this.pbPlayerModel.Image = Image.FromFile(Application.StartupPath + "\\images\\cycle.png");
break;
case (int)PlayMode.OrderPlay:
this.tsmiOrderPlay.Checked = true;
this.playModel = PlayMode.OrderPlay;
this.tipTitle.SetToolTip(this.pbPlayerModel, this.tsmiOrderPlay.Text);
this.pbPlayerModel.Image = Image.FromFile(Application.StartupPath + "\\images\\order.png");
break;
case (int)PlayMode.RandomPlay:
this.tsmiRandomPlay.Checked = true;
this.playModel = PlayMode.RandomPlay;
this.tipTitle.SetToolTip(this.pbPlayerModel, this.tsmiRandomPlay.Text);
this.pbPlayerModel.Image = Image.FromFile(Application.StartupPath + "\\images\\random.png");
break;
case (int)PlayMode.SingleCycle:
this.tsmiSingleCycle.Checked = true;
this.playModel = PlayMode.SingleCycle;
this.tipTitle.SetToolTip(this.pbPlayerModel, this.tsmiSingleCycle.Text);
this.pbPlayerModel.Image = Image.FromFile(Application.StartupPath + "\\images\\singlecycle.png");
break;
case (int)PlayMode.SinglePlay:
this.tsmiSinglePlay.Checked = true;
this.playModel = PlayMode.SinglePlay;
this.tipTitle.SetToolTip(this.pbPlayerModel, this.tsmiSinglePlay.Text);
this.pbPlayerModel.Image = Image.FromFile(Application.StartupPath + "\\images\\single.png");
break;
default:
break;
}
int mainHeight = int.Parse(ini.ReadValue("Player", "MainHeight"));
this.Height = mainHeight;
//加载XML文件歌曲列表
OpenPlayList();
#endregion
}
#region 窗体按钮事件
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (MessageBox.Show(null, "要关闭窗口吗?", "自定义窗口按钮", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
{
e.Cancel = true;
}
base.OnFormClosing(e);
}
private void pbClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void pbContextMenu_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.contextMenuStrip1.Show(MousePosition);
}
private void pbMinimized_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
private void pnlHearts_MouseDown(object sender, MouseEventArgs e)
{
if (this.pnlHearts.Tag.ToString() == "0")
{
this.pnlHearts.Tag = "1";
this.pnlHearts.BackgroundImage = Image.FromFile(Application.StartupPath + "\\images\\hearts_m.png");
}
else
{
this.pnlHearts.Tag = "0";
this.pnlHearts.BackgroundImage = Image.FromFile(Application.StartupPath + "\\images\\hearts.png");
}
}
#endregion
/// <summary>
/// 关闭歌词面板
/// </summary>
protected void CloseLrcPanel()
{
this.diskLrcFrm.manualReset.Set();
this.diskLrcFrm.thread.Abort();
this.diskLrcFrm.Close();
this.diskLrcFrm = null;
}
/// <summary>
/// 加载歌词面板
/// </summary>
protected void LoadDiskLrcPanel()
{
this.diskLrcFrm = new DiskLrcFrm();
//关闭歌词面板回调函数
this.diskLrcFrm.CloseLrcPanel += new DiskLrcFrm.CloseLrcPanelHandler(CloseLrcPanel);
//上一曲回调函数
this.diskLrcFrm.PreMusicLrcPanel += new DiskLrcFrm.PreMusicLrcPanelHandler(PreMusicLrcPanel);
//播放暂停回调函数
this.diskLrcFrm.PlayOrPauseMusicLrcPanel += new DiskLrcFrm.PlayOrPauseMusicLrcPanelHandler(PlayOrPauseMusicLrcPanel);
//下一曲回调函数
this.diskLrcFrm.NextMusicLrcPanel += new DiskLrcFrm.NextMusicLrcPanelHandler(NextMusicLrcPanel);
//搜索歌词回调函数
this.diskLrcFrm.SearchLrcPanel += new DiskLrcFrm.SearchLrcPanelHandler(SearchLrcPanel);
this.diskLrcFrm.Init("===草莓音乐===", 0);
this.diskLrcFrm.Show();
}
#region 媒体列表管理
/// <summary>
/// 打开曲目列表
/// </summary>
private void OpenPlayList()
{
XmlDocument xmlDoc = new XmlDocument();
//加载Xml文件
xmlDoc.Load(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
//匹配曲目列表
XmlNode root = xmlDoc.SelectSingleNode("musiclist");//查找<musiclist>
//清空歌曲列表
this.lvMusicListView.Items.Clear();
//获取所有曲目列表
XmlNodeList xnl = root.ChildNodes;
bool flag = false; //设置当前列表是否有正在播放的曲目
this.lvMusicListView.BeginUpdate();
for (int i = 0; i < xnl.Count; i++)
{
ListViewItem item = new ListViewItem(root.ChildNodes[i].Attributes["genre"].Value);
//依次顺序为:曲目名称|曲目长度
item.SubItems.AddRange(new string[] { root.ChildNodes[i].Attributes["lenght"].Value });
//设置背景色
if (i % 2 == 0)
item.BackColor = Color.FromArgb(232, 243, 250);
//设置曲目绝对路径
item.Tag = root.ChildNodes[i].Attributes["filename"].Value;
//判断当前加载曲目是否是当前播放曲目,如果是则高亮显示并保存播放信息
if (this.bassPlayer.OpenningFile == root.ChildNodes[i].Attributes["filename"].Value)
{
//设置当前选中项背景颜色
item.BackColor = Color.FromArgb(142, 185, 209);
item.ForeColor = Color.FromArgb(255, 255, 255);
//更新当前下标,以免造成可能的列表下标越界
this.changeValue = i;
flag = true;
}
this.lvMusicListView.Items.Add(item);
//处理消息队列
Application.DoEvents();
}
this.lvMusicListView.EndUpdate();
//如果当前列表没有正在播放的曲目,则将序列号初始化为-1,以免造成可能的列表下标越界
if (!flag)
{
//由于在进行计时器运行时,播放下一曲会进行+1,因此设置成-1后,计时器加1变成0,刚好从0下标开始重新播放
this.changeValue = -1;
}
}
/// <summary>
/// 添加本地歌曲
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiAddLocalMusic_Click(object sender, EventArgs e)
{
try
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
//允许多选
ofd.Multiselect = true;
//文件格式
ofd.Filter = "音乐文件|*.mp3;*.wma;*.flac;*.ogg*.wav;*.aiff;*.mp2;*.mp1";
//对话框标题
ofd.Title = "打开媒体文件";
if (ofd.ShowDialog() == DialogResult.OK)
{
XmlDocument xmlDoc = new XmlDocument();
//加载Xml文件
xmlDoc.Load(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
XmlNode root = xmlDoc.SelectSingleNode("musiclist");//查找<musiclist>
//列表更新准备
this.lvMusicListView.BeginUpdate();
//遍历加载当前选中文件
for (int i = 0; i < ofd.FileNames.Length; i++)
{
//打开音乐设备
this.bassPlayer.OpenFile(ofd.FileNames[i]);
//返回没有后缀的文件名
string musicName = Path.GetFileNameWithoutExtension(ofd.FileNames[i]);
//添加ListView项
ListViewItem item = new ListViewItem(musicName);
item.SubItems.AddRange(new string[] { GetStardandTimeString(this.bassPlayer.ChannelLength) });
//设置背景色
if (i % 2 == 0)
item.BackColor = Color.FromArgb(232, 243, 250);
item.Tag = ofd.FileNames[i];
this.lvMusicListView.Items.Add(item);
XmlElement xe1 = xmlDoc.CreateElement("name");//创建一个音乐节点
xe1.SetAttribute("genre", musicName);//设置该节点文件路径属性
xe1.SetAttribute("filename", ofd.FileNames[i]);//设置该节点文件名属性
xe1.SetAttribute("lenght", GetStardandTimeString(this.bassPlayer.ChannelLength));//设置该节点音乐时间属性
root.AppendChild(xe1);//添加到<musiclist>节点中
//处理消息队列
//Application.DoEvents();
}
//更新列表结束
this.lvMusicListView.EndUpdate();
xmlDoc.Save(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
//释放资源,减少内存占用
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle.ToInt32(), -1, -1);
}
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 添加文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiAddLocalFolder_Click(object sender, EventArgs e)
{
try
{
//打开文件夹选择对话框
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
if (fbd.ShowDialog() == DialogResult.OK)
{
DirectoryInfo dInfo = new DirectoryInfo(fbd.SelectedPath);
//遍历该文件夹
FileInfo[] files = dInfo.GetFiles("*.*", SearchOption.AllDirectories);
try
{
XmlDocument xmlDoc = new XmlDocument();
//加载Xml文件
xmlDoc.Load(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
XmlNode root = xmlDoc.SelectSingleNode("musiclist");//查找<musiclist>
this.lvMusicListView.BeginUpdate();
foreach (FileInfo fileName in files)
{
//获取文件扩展名
string extension = Path.GetExtension(fileName.FullName);
//判断是否为音乐文件
//if (extension.ToLower() == ".mp3" || extension.ToLower() == ".wma" || extension.ToLower() == ".wav")
//{
//打开音乐设备
this.bassPlayer.OpenFile(fileName.FullName);
XmlElement xe1 = xmlDoc.CreateElement("name");//创建一个音乐节点
xe1.SetAttribute("genre", Path.GetFileNameWithoutExtension(fileName.FullName));//设置该节点文件路径属性
xe1.SetAttribute("filename", fileName.FullName);//设置该节点文件名属性
xe1.SetAttribute("lenght", GetStardandTimeString(this.bassPlayer.ChannelLength));//设置该节点音乐时间属性
root.AppendChild(xe1);//添加到<musiclist>节点中
ListViewItem item = new ListViewItem(Path.GetFileNameWithoutExtension(fileName.FullName));
//添加到播放列表
item.SubItems.AddRange(new string[] { xe1.GetAttribute("length") });
item.Tag = fileName.FullName;
this.lvMusicListView.Items.Add(item);
//}
//Application.DoEvents();
}
this.lvMusicListView.EndUpdate();
xmlDoc.Save(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
}
catch (Exception exp)
{
throw exp;
}
//垃圾回收,释放资源,减少内存占用
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle.ToInt32(), -1, -1);
}
//this.Mainfrm.btnPlayOrPause.Enabled = true;
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 删除选中歌曲
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiDeleteChangeMusic_Click(object sender, EventArgs e)
{
try
{
//判断是否至少选中一项
if (this.lvMusicListView.SelectedItems.Count == 0)
{
MessageBox.Show("请选择您要删除的歌曲!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
//获取选中歌曲数目
ListView.SelectedListViewItemCollection collection = this.lvMusicListView.SelectedItems;
//循环删除选中歌曲
foreach (ListViewItem item in collection)
{
this.lvMusicListView.Items.Remove(item);
}
SaveXmlFile();
this.lvMusicListView.BeginUpdate();
//重置列表背景颜色
for (int i = 0; i < this.lvMusicListView.Items.Count; i++)
{
if (i % 2 == 0)
this.lvMusicListView.Items[i].BackColor = Color.FromArgb(230, 243, 250);
else
this.lvMusicListView.Items[i].BackColor = Color.FromArgb(250, 250, 250);
}
this.lvMusicListView.EndUpdate();
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 清空当前列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmiClearList_Click(object sender, EventArgs e)
{
try
{
XmlDocument xmlDoc = new XmlDocument();
//加载Xml文件
xmlDoc.Load(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
XmlNode root = xmlDoc.SelectSingleNode("musiclist");//查找<musiclist>
//删除所有歌曲列表
root.RemoveAll();
//保存歌曲列表
xmlDoc.Save(string.Format("{0}\\PlayList\\{1}.xml", Application.StartupPath, this.tabMusicType));
//清空列表
this.lvMusicListView.Items.Clear();
//this.number = 1;
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 触发删除键,删除选中歌曲
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void lvMusicListView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete) //如果触发Delete删除键则删除当前选中歌曲
tsmiDeleteChangeMusic_Click(null, null);
}
/// <summary>
/// 删除重复歌曲
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tsmDeleteRepeat_Click(object sender, EventArgs e)
{
//冒泡排序法——删除重复歌曲
for (int i = 0; i < this.lvMusicListView.Items.Count; i++) //控制比较多少轮
{
//将重复元素删除
for (int j = 0; j < this.lvMusicListView.Items.Count; j++)
{
//如果两个比较的元素相同并且不是同一元素,执行删除操作
if (this.lvMusicListView.Items[i].Tag.ToString() == this.lvMusicListView.Items[j].Tag.ToString() && i != j)
{
this.lvMusicListView.Items[j].Remove();
//判断当前播放歌曲是否存在于删除之列,如果存在设置当前播放曲目为第一首
if (this.changeValue == j)
this.changeValue = 0;
}
}
}
this.lvMusicListView.BeginUpdate();
//重置列表背景颜色
for (int i = 0; i < this.lvMusicListView.Items.Count; i++)
{
if (i % 2 == 0)
this.lvMusicListView.Items[i].BackColor = Color.FromArgb(230, 243, 250);
else
this.lvMusicListView.Items[i].BackColor = Color.FromArgb(250, 250, 250);
}
this