C# 简单播放器,音乐播放器,视频播放器,歌词显示,播放列表
C# 简单播放器,音乐播放器,视频播放器,歌词显示,播放列表,添加列表,删除列表,列表循环,单曲循环,随机循环,音量调节。
使用C#制作播放器需要用到Windows Media Player空间。
添加Windows Media Player步骤如下:
1、工具箱——组件——(右键)选择项——COM 组件——Windows Media Player——确定。
设置步骤:
将Windows Media Player 组件拖拽到窗体上,右键属性。
常规选项:
控件布局:选择模式(None)。
音量:最大。
播放选项:按比例拉伸。
高级选项:
控件设置:
(取消勾选)启动控件。
其中控件布局——选择模式:4中选项。
Full(default)默认选项:除视频或可视化效果窗口之外,内嵌的播放机还具有状态窗口、定位栏、播放/暂停、停止、静音、下一个、上一个、快进、快退以及音量控件。
None:内嵌的播放机不带控件,仅显示视频或可视化效果窗口。
Mini:除视频或可视化效果窗口之外,内嵌的播放机还具有状态窗口、播放/暂停、停止、静音以及音量控件。
Invisible:内嵌的播放机不带控件,不显示视频或可视化效果窗口以及任何用户界面。
默认属性窗口:
简单播放器设计界面:
播放按钮,主要注意判断列表内是否有文件,如果没文件不能让播放按钮执行播放。不然会报错。
并且也要判断列表框内是否有选中项。没有选中项,则返回索引为-1.调取 文件路径会报错。
播放和停止按钮代码:
private void btnPlayOrNo_Click(object sender, EventArgs e)//播放按钮 单击事件
{
if (btnPlayOrNo.Text == "播放")//判断 按钮Text是否为 播放。
{
if (lbPlayerList.Items.Count == 0)//用于判断 播放列表内是否有播放文件。
{
return;//如果播放列表没有文件,则不执行下面语句。
}
//如果不判断是否有文件,点击播放,在下面获取播放文件地址会报错。
if (b == true)//判断用户之前是否点击过 暂停按钮,点击过暂停按钮则,b为false.
{
if (lbPlayerList.SelectedIndex == -1)//判断列表框中 使用有选择的项,如果没选中项,则为-1.
{
WMPlayer.URL = listPath[0];//如果用户没有选中列表框中的选项,则将 文件路径list 第一个赋值给播放器。
lbPlayerList.SelectedIndex = 0;//列表框选中项设置为第一个。
}
WMPlayer.URL = listPath[lbPlayerList.SelectedIndex];//如果列表框中用户选中的有项,则将选中项的 文件路径 赋值给播放器。
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedItem = Path.GetFileName(WMPlayer.URL);//设置选中项
}
WMPlayer.Ctlcontrols.play();//播放文件
btnPlayOrNo.Text = "暂停";//文字改为 暂停
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedItem = Path.GetFileName(WMPlayer.URL);//设置选中项
}
else if (btnPlayOrNo.Text == "暂停")//判断按钮Text 是否为 暂停.
{
WMPlayer.Ctlcontrols.pause();//暂停
btnPlayOrNo.Text = "播放";//文字改为 播放
b = false;//设置为 false 说明用户已经点击了暂停按钮。
}
}
private void btnStop_Click(object sender, EventArgs e)//停止按钮
{
WMPlayer.Ctlcontrols.stop();//播放器停止。
lblTime.Text = "00:00:00/00:00:00";//时间标签
btnPlayOrNo.Text = "播放";//播放按钮 文字
this.Text = "简单播放器——小道博客https://www.daobk.com";//标题
tkbMove.Value = 0;//播放滚动条为0
}下面主要注意隐藏列表框后要将 其他两个panel 宽度加上。
显示或隐藏列表框代码:
private void btnList_Click(object sender, EventArgs e)//列表框 点击事件
{
int panel1w = panel1.Size.Width;//获取panel1宽度
int panel1h = panel1.Size.Height;//获取panel1高度
int panel2w = panel2.Size.Width;//获取panel2宽度
int panel2h = panel2.Size.Height;//获取panel2高度
if (grpList.Visible == true)//判断grpList 显示状态
{
grpList.Visible = false;//隐藏
panel1.Size = new Size(panel1w + 158, panel1h);//隐藏列表框后,将panel1 宽度加上 158
panel2.Size = new Size(panel2w + 158, panel2h);//隐藏列表框后,将panel2 宽度加上 158
}
else if (grpList.Visible == false)//判断grpList 显示状态
{
grpList.Visible = true;//显示
panel1.Size = new Size(panel1w - 158, panel1h);//隐藏列表框后,将panel1 宽度减去 158
panel2.Size = new Size(panel2w - 158, panel2h);//隐藏列表框后,将panel2 宽度减去 158
}
}调用方法参数判断是打开还是添加,如果是打开按钮,则要先清空路径和列表框内容,再添加列表框,并且播放打开的文件,如果是添加按钮,则值添加到列表框中无须播放。
删除要注意要先删除文件路径list,在删除列表框中内容。
打开、添加、删除按钮和添加方法代码:
private void btnOpen_Click(object sender, EventArgs e)//打开 按钮 单击事件
{
addFile((Button)sender);//调用添加文件方法 参数为 是哪个按钮单击的
}
private void btnAdd_Click(object sender, EventArgs e)//添加 按钮 单击事件
{
addFile((Button)sender);//调用添加文件方法 参数为 是哪个按钮单击的
}
private void btnRemove_Click(object sender, EventArgs e)//删除 按钮 单击事件
{
int count = lbPlayerList.SelectedItems.Count;//获取选中列表框的项的数目。
if (count == 0)//判断是否为0,为0表示列表框没有文件。
{
return;//不继续执行下面语句。
}
if (MessageBox.Show("你确定要移除列表中的 " + count + " 个选中项吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)//提示
{
for (int i = 0; i < count; i++)//循环删除
{
listPath.RemoveAt(lbPlayerList.SelectedIndex);//移除 列表框选中对应的 文件路径数组中的元素。
lbPlayerList.Items.RemoveAt(lbPlayerList.SelectedIndex);//移除 列表框选中的项
}
}
}
void addFile(Button sender)//添加文件方法。
{
OpenFileDialog ofd = new OpenFileDialog();//提示用户打开文件夹
ofd.InitialDirectory = @".\";//初始目录
ofd.Multiselect = true;//可以多选
ofd.Title = "请选择要打开的文件.";//标题
ofd.Filter = "支持的全部文件|*.MP3;*.WMA;*.MP4;*.AVI;*.WMV;*.FLV;*.MKV;*.MOV;*.RM;*.RMVB|音乐文件|*.MP3;*.WMA|视频文件|*.MP4;*.AVI;*.WMV;*.FLV;*.MKV;*.MOV;*.RM;*.RMVB|所有文件(*.*)|*.*";
//扩展名,这里我没全部做测试,其中仅使用MP3、MP4播放。
ofd.FilterIndex = 1;//获取或设置文件对话框中当前选定筛选器的索引。
if (ofd.ShowDialog() != DialogResult.OK)//判断用户是否点击了 OK按钮
{
MessageBox.Show("请选择要打开的文件!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);//提示
return;
}
if (sender.Name == "btnOpen")//判断传过来的按钮 name
{
lbPlayerList.Items.Clear();//清空列表
listPath.Clear();//清空路径
}
string[] path = ofd.FileNames;//获取打开的文件
for (int i = 0; i < path.Length; i++)//循环
{
listPath.Add(path[i]);//将 文件添加到路径
lbPlayerList.Items.Add(Path.GetFileName(path[i]));//添加到列表
}
if (sender.Name == "btnOpen")//判断传过来的按钮 name
{
lbPlayerList.SelectedIndex = 0;//将列表选中项设置为第一项
WMPlayer.URL = listPath[0];//播放路径设置为 路径第一项
btnPlayOrNo.Text = "暂停";//按钮 文字
showLrc();//调用歌词
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
}以下代码主要注意:双击在空白处的判断。ListBox 设置:SelectionMode 为 MultiExtended 列表框可以多选.
双击列表框代码:
private void lbPlayerList_DoubleClick(object sender, EventArgs e)//列表框 双击事件
{
if (lbPlayerList.Items.Count == 0)//判断列表框 元素个数是否为0
{
MessageBox.Show("请先加载要播放的文件到列表中!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);//提示
return;
}
if (lbPlayerList.SelectedIndex == -1)//判断是否有选择项。主要防止 添加文件到列表,没有选中项,双击空白处,报错。
{
return;
}
WMPlayer.URL = listPath[lbPlayerList.SelectedIndex];//将选中项的路径赋值给播放器
btnPlayOrNo.Text = "暂停";//按钮 文字
showLrc();//调用歌词
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}以下代码主要注意:循环模式的判断。
上一个、下一个按钮代码:
private void btnDown_Click(object sender, EventArgs e)//下一个 按钮
{
int index = lbPlayerList.SelectedIndex;//获取选中项索引
if (btnLoop.Text == "列表循环" || btnLoop.Text == "单曲循环")//判断循环模式
{
index++;//索引+1
if (index >= lbPlayerList.Items.Count)//判断 索引 是否大于 列表元素最大数。
{
index = 0;//索引为0
}
WMPlayer.URL = listPath[index];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = index;//设置选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
else if (btnLoop.Text == "随机播放")//判断循环模式
{
int num = r.Next(0, lbPlayerList.Items.Count);//随机 0~列表元素总数值。
WMPlayer.URL = listPath[num];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = num;//设置选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
}
private void btnUp_Click(object sender, EventArgs e)//上一个
{
int index = lbPlayerList.SelectedIndex;//获取选中项索引
if (btnLoop.Text == "列表循环" || btnLoop.Text == "单曲循环")//判断循环模式
{
index--;//索引-1
if (index < 0)//判断 索引 是否小于0。
{
index = lbPlayerList.Items.Count - 1;//索引为 列表总数数-1
}
WMPlayer.URL = listPath[index];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = index;//设置选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
else if (btnLoop.Text == "随机播放")//判断循环模式
{
int num = r.Next(0, lbPlayerList.Items.Count);//随机 0~列表元素总数值。
WMPlayer.URL = listPath[num];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = num;//设置选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
}以下代码主要注意:要保存当前音量大小数据,用于 按下静音和恢复声音后的音量值。
音量标签和滚动条代码:
private void AMain_Load(object sender, EventArgs e)//窗体默认加载
{
volumeNum = WMPlayer.settings.volume;//获取音量的值
trbVolume.Maximum = 100;//音量滚动条 最大值
trbVolume.Minimum = 0;//音量滚动条 最小值
trbVolume.TickFrequency = 3;//获取或设置一个值,该值指定控件上绘制的刻度之间的增量。
trbVolume.Value = 100;//当前滚动条的位置
label1.Text = trbVolume.Value.ToString() + "%";//在音量 标签显示音量值
tkbMove.LargeChange = 10;//播放进度 滚动条 滚动距离
}
private void label1_Click(object sender, EventArgs e)//音量 标签 单击
{
if (label1.Tag.ToString() == "1")//判断Tag 值
{
WMPlayer.settings.mute = true;//音量关闭
label1.Tag = "2";//设置为2
label1.Image = Properties.Resources.音量关;//图标
trbVolume.Value = 0;//音量 滚动条为0
}
else if (label1.Tag.ToString() == "2")//判断Tag 值
{
WMPlayer.settings.mute = false;//音量打开
label1.Tag = "1";//设置为1
label1.Image = Properties.Resources.音量开;//图标
trbVolume.Value = volumeNum;//音量滚动条恢复
}
}
private void trbVolume_ValueChanged(object sender, EventArgs e)//音量 滚动条 值发生变化
{
WMPlayer.settings.volume = trbVolume.Value;//将滚动条 值赋值给音量
if (trbVolume.Value == 0)//判断滚动条值是否为0
{
label1.Image = Properties.Resources.音量关;//图标
label1.Tag = "2";//Tag设置为2
label1.Text = "";//为空
}
else
{
volumeNum = WMPlayer.settings.volume;//将音量值赋值给 volumeNum 用于记录 音量值
label1.Text = trbVolume.Value.ToString() + "%";//在音量 标签显示音量值
label1.Image = Properties.Resources.音量开;//图标
label1.Tag = "1";//Tag设置为1
}
}以下代码主要注意:当前播放进度与总时长,判断是否播放完毕,要总时长-1 == 当前播放进度。
播放时间时钟代码:
private void timerPlay_Tick(object sender, EventArgs e)//播放时间 时钟
{
tkbMove.Minimum = 0;//播放 滚动条最小值
if (WMPlayer.playState == WMPLib.WMPPlayState.wmppsPlaying)//判断当前 是否在播放文件
{
showLrc();//调用歌词
string playTime = WMPlayer.Ctlcontrols.currentPositionString;//获取当前播放的时间,格式 00:00
lblTime.Text = playTime + "/" + WMPlayer.currentMedia.durationString;//将当前播放时间/文件总时间 显示在标签上,格式: 00:50/03:20
tkbMove.Maximum = (int)WMPlayer.currentMedia.duration;//获取文件总长度,格式如: 229.334
tkbMove.Value = (int)WMPlayer.Ctlcontrols.currentPosition;//获取当前播放长度,格式如:158.2564589
if (tkbMove.Maximum - 1 == tkbMove.Value)//判断当总时间-1 是否等于 当前播放时间
{
int index = lbPlayerList.SelectedIndex;//获取当前选中项的索引
if (btnLoop.Text == "列表循环")//判断循环模式
{
index++;//索引+1
if (index >= lbPlayerList.Items.Count)//判断 索引 是否大于 列表元素最大数。
{
index = 0;//索引为0
}
WMPlayer.URL = listPath[index];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = index;//设置 选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
else if (btnLoop.Text == "单曲循环")//判断循环模式
{
if (index == -1)//判断索引是否为 -1 主要为了防止 选择单曲循环,并删除列表当前选中项,这时索引为-1.会报错
{
index = 0;//索引设置为0
lbPlayerList.SelectedIndex = index;//设置 选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
WMPlayer.URL = listPath[index];//赋值播放器
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
else if (btnLoop.Text == "随机播放")//判断循环模式
{
int num = r.Next(0, lbPlayerList.Items.Count);
WMPlayer.URL = listPath[num];//赋值播放器
lbPlayerList.SelectedIndices.Clear();//清除 选中项
lbPlayerList.SelectedIndex = num;//设置 选中项
this.Text = "简单播放器——" + Path.GetFileName(WMPlayer.URL);//窗体命名为,“简单播放器——歌名”
}
}
}
}以下代码主要注意: 要添加 鼠标松开 后事件,最好将当前线程挂起100毫秒,不然拖放滚动条,画面会卡顿。
播放进度滚动条代码:
private void tkbMove_MouseUp(object sender, MouseEventArgs e)//播放滚动条 移动
{
Thread.Sleep(100);//将当前线程挂起指定的时间。
if (tkbMove.Value >= (int)WMPlayer.currentMedia.duration)//判断当前播放进度 是否大于或等于 播放总长度
{
if ((int)WMPlayer.currentMedia.duration == 0)//判断播放总长度是否为0
{
return;
}
tkbMove.Value = (int)WMPlayer.currentMedia.duration - 1;//设置 滚动条值为 总长度-1
}
WMPlayer.Ctlcontrols.currentPosition = tkbMove.Value;//滚动条值赋值给 当前播放进度
}
private void tkbMove_Scroll(object sender, EventArgs e)// 播放 滚动条 滚动
{
if (Control.MouseButtons == MouseButtons.None)//判断是否是 鼠标拖动 滚动条
{
if (tkbMove.Value >= (int)WMPlayer.currentMedia.duration)//判断当前播放进度 是否大于或等于 播放总长度
{
if ((int)WMPlayer.currentMedia.duration - 1 == -1)//判断总长度-1 是否等于-1
{
return;
}
tkbMove.Value = (int)WMPlayer.currentMedia.duration - 1;//设置 滚动条值为 总长度-1
}
WMPlayer.Ctlcontrols.currentPosition = tkbMove.Value;//滚动条值赋值给 当前播放进度
}
}显示歌词本来想使用GDI+ 显示全部歌词,并高亮 当前歌词。想想还是后期 学习了美化播放器UI界面,在做把。歌词只测试了一个,下面代码可能会有Bug。
歌词显示或隐藏代码:
private void btnLrc_Click(object sender, EventArgs e)//歌词按钮 单击事件
{
if (btnLrc.Tag.ToString() == "1")//判断Tag 值
{
if (WMPlayer.URL == "")//判断 播放链接是否为空
{
return;
}
showLrc();//调用歌词
btnLrc.BackColor = SystemColors.ControlDark;//按钮背景颜色
btnLrc.Tag = "2";//Tag值为2
WMPlayer.Visible = false;//播放器 设置隐藏
lblLrc.Visible = true;//显示歌词 标签
}
else if (btnLrc.Tag.ToString() == "2")//判断Tag 值
{
btnLrc.BackColor = SystemColors.Control;//按钮背景颜色
btnLrc.Tag = "1";//Tag值为1
lblLrc.Visible = false;//隐藏 歌词标签
WMPlayer.Visible = true;//显示播放器
}
}
List<double> listTime = new List<double>();//存放 歌词事件
List<string> listLrcText = new List<string>();//存放歌词
void showLrc()//歌词方法
{
string lrcPath = WMPlayer.URL.Substring(0, WMPlayer.URL.LastIndexOf(".")) + ".lrc";//查找是否存在歌词,比如:歌曲名:ABC.mp3,那么歌词名为:ABC.lrc
if (File.Exists(lrcPath) == false)//判断歌词是否存在
{
timerLrc.Enabled = false;//歌词时钟 关闭
lblLrc.TextAlign = ContentAlignment.MiddleCenter;//对齐方式
lblLrc.Font = new Font("宋体", 20, FontStyle.Bold);//字体
lblLrc.ForeColor = Color.Blue;//颜色
lblLrc.Text = "---------未找到歌词---------";//显示
return;
}
timerLrc.Enabled = true;//歌词时钟 打开
string[] lrcText = File.ReadAllLines(lrcPath);//读取歌词文件内容
for (int i = 0; i < lrcText.Length; i++)//循环
{
string[] lrcTemp = lrcText[i].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
//分割 时间和歌词
if (lrcTemp.Length != 2)//判断lrcTemp数组 长度 不等于2
{
continue;//退出本次循环
}
string[] lrcNewTemp = lrcTemp[0].Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
//分割时间
double timeM;//分钟
double timeS;//秒数
if (double.TryParse(lrcNewTemp[0], out timeM) == false)//判断 转换失败
{
continue;//退出本次循环
}
if (double.TryParse(lrcNewTemp[1], out timeS) == false)//判断 转换失败
{
continue;//退出本次循环
}
double time = (timeM * 60) + timeS;//获取总秒数
listTime.Add(time);//添加 歌词时间list
listLrcText.Add(lrcTemp[1]);//添加 歌词list
}
}
private void timerLrc_Tick(object sender, EventArgs e)//歌词 时钟
{
lblLrc.TextAlign = ContentAlignment.MiddleCenter;//对齐方式
lblLrc.Font = new Font("宋体", 20, FontStyle.Bold);//字体 大小
lblLrc.ForeColor = Color.Blue;//颜色
for (int i = 0; i < listTime.Count; i++)//循环
{
if (i == listTime.Count - 1)//判断当前i的值是否为listTime 最后一个值,如果没这句判断,到最后一行货报错。
{
if (WMPlayer.Ctlcontrols.currentPosition >= listTime[i])//当前播放进度是否大于 歌词时间
{
lblLrc.Text = listLrcText[i];//显示歌词
}
return;
}
if (WMPlayer.Ctlcontrols.currentPosition >= listTime[i] && WMPlayer.Ctlcontrols.currentPosition < listTime[i + 1])//当前播放进度是否大于 歌词时间,并且当前播放进度小于 下一句歌词时间
{
lblLrc.Text = listLrcText[i];//显示歌词
}
}
}运行界面:
暂未添加功能:UI界面美化、网络播放(导入网上视频地址,在线播放。)、添加文件夹到列表、播放列表保存、视频倍速播放、视频全屏播放,视频打开原始尺寸播放等功能。
如需本软件完整源码请留言!仅限学习交流使用!
