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界面美化、网络播放(导入网上视频地址,在线播放。)、添加文件夹到列表、播放列表保存、视频倍速播放、视频全屏播放,视频打开原始尺寸播放等功能。
如需本软件完整源码请留言!仅限学习交流使用!