以下 music player 均为windows media player控件的名字。
1.属性
1)musicPlayer.settings.autoStart:打开播放器时是否自动播放 。true:自动播放,false:不自动播放,默认自动播放。
2)musicPlayer.URL:要播放歌曲的路径。
3)musicPlayer.settings.mute:是否静音。true:静音,false:不静音。
4)musicPlayer.settings.volume:音量值大小,范围是1~100。
5)musicPlayer.Ctlcontrols.currentPositionString:当前播放时间。返回值是字符串类型,例如:02:23。
6)musicPlayer.Ctlcontrols.currentPosition:也是返回当前播放的时间。返回值是 double 类型,例如:133.8。
7)musicPlayer.currentMedia.name:返回当前播放歌曲的名字。
8)musicPlayer.playState:播放器当前的状态。
有一个枚举 WMPLib.WMPPlayState 说明了它的取值:
0——wmppsUndefined:未知状态
1——wmppsStopped:播放停止
2——wmppsPaused:播放暂停
3——wmppsPlaying:正在播放
4——wmppsScanForward:向前搜索
5——wmppsScanReverse:向后搜索
6——wmppsBuffering :正在缓冲
7——wmppsWaiting:正在等待流开始
8——wmppsMediaEnded:播放流已结束
9——wmppsTransitioning :准备新的媒体文件
10——wmppsReady:播放准备就绪
11——wmppsReconnecting:尝试重新连接流媒体数据
12——wmppsLast:上一次状态,状态没有改变
2.方法
1)musicPlayer.Ctlcontrols.play():播放
2)musicPlayer.Ctlcontrols.pause():暂停
3)musicPlayer.Ctlcontrols.stop():停止
1.第一步:先拖一个windows media player控件,再拖一个 listbox 用来存放歌曲名字。一个按钮,点击按钮的时候显示文件对话框。选择音乐文件后,将音乐的名字添加到 listbox 中。
//设置文件对话框
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "请选择音乐";
ofd.InitialDirectory = @"E:\计算机资料\项目\03 CS学习\03 C#例子\【04】\04\4-4\歌曲";
ofd.Filter = "(*.mp3)|*.mp3";
ofd.Multiselect = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
//存放歌曲路径,需定义一个string[]数组或list泛型集合
path = ofd.FileNames;
for (int i = 0; i < path.Length; i++)
{
//截取歌曲名字
string musicName = path[i].Substring(path[i].LastIndexOf('\\') + 1);
//向listbox中添加歌曲名字
listBox1.Items.Add(musicName);
}
//默认选择为第1项
listBox1.SelectedIndex = 0;
musicPlayer.URL = path[listBox1.SelectedIndex];
}
2.第二步:设置播放暂停按钮。
if (btnPlay.Text == "播放")
{
musicPlayer.Ctlcontrols.play();
btnPlay.Text = "暂停";
}
else
{
musicPlayer.Ctlcontrols.pause();
btnPlay.Text = "播放";
}
3.第三步:添加播放上一曲、下一曲按钮。
//播放下一曲
int index = listBox1.SelectedIndex;
index++;
if (index == path.Length)
{
index = 0;
}
listBox1.SelectedIndex = index;
musicPlayer.URL = path[index];
musicPlayer.Ctlcontrols.play();
//播放上一曲
int index = listBox1.SelectedIndex;
index--;
if (index < 0)
{
index = path.Length-1;
}
listBox1.SelectedIndex = index;
musicPlayer.URL = path[index];
musicPlayer.Ctlcontrols.play();
4.第四步:音量加减、是否静音。拖两个按钮,来控制上一首、下一首。拖一个 picturebox 控件,点击它来控制是否静音。
//音量+
musicPlayer.settings.volume += 5;
//音量-
musicPlayer.settings.volume -= 5;
//静音
if (picVolume.Tag.ToString() == "1")
{
musicPlayer.settings.mute = true;
picVolume.Image = Image.FromFile("路径");
picVolume.Tag = "2";
}
else
{
musicPlayer.settings.mute = false;
picVolume.Image = Image.FromFile("路径");
picVolume.Tag = "1";
}
5.显示当前播放时间和歌词。拖一个 timer 控件,在 timer 控件里让当前播放时间和歌词显示在 label 控件上。
显示当前播放时间很容易,用 musicPlayer.Ctlcontrols.currentPositionString 属性就可以了,但是歌词略微有点儿麻烦。首先得有歌词,其次将歌词文件中的内容读取出来后,还要将歌词分割,将歌词补充完整,最后再进行排序。
什么意思呢?比如上图中的歌词有一些重复的歌词内容,需要按时间分割整行歌词,然后再在每个时间后面都加上个歌词内容,保存到一个list泛型集合中,最后再对他们排序,这才是完整的歌词。
//切割歌词的方法
private List<string> FormatLrc()
{
List<string> list = new List<string>();
//遍历歌词
for (int i = 0; i < listSongLrc.Count; i++)
{
//切割歌词
string[] strSongLrc = listSongLrc[i].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
//如果数组长度大于1,则表明时间后有歌词
if (strSongLrc.Length>1)
{
for (int j = 0; j < strSongLrc.Length-1; j++)
{
list.Add(strSongLrc[j] + "|" + strSongLrc[strSongLrc.Length - 1]);
}
}
}
//歌词排序,冒泡排序法
for (int i = 0; i < list.Count-1; i++)
{
for (int j = 0; j < list.Count-1-i; j++)
{
if (string.Compare(list[j],list[j+1])>0)
{
string temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
return list;
}
//timer事件,显示当前播放时间和歌词
private void timer1_Tick(object sender, EventArgs e)
{
//显示播放时间和歌曲名字
if (musicPlayer.currentMedia != null)
{
labTime.Text = musicPlayer.Ctlcontrols.currentPositionString;
labMusicName.Text = musicPlayer.currentMedia.name;
}
//显示歌词
if (listLrcPath.Count > 0 && musicPlayer.currentMedia != null)
{
for (int i = 0; i < listSongLrc.Count; i++)
{
//如果当前播放时间超过了歌词中的某个时间,就显示该时间后的歌词
if (string.Compare(musicPlayer.Ctlcontrols.currentPositionString, listSongLrc[i]) > 0)
{
lblLrc.Text = listSongLrc[i].Split('|')[1];
}
}
}
}
6.自动播放下一曲
实现自动播放下一曲的原理:当播放完一首歌的时候,播放器的播放状态变为 Ended,按照正常的状态变换,是这样的的:Ended –> Transtioning –> stopped。而在变成 Ended 状态之后,将下一曲的歌曲路径传给播放器,状态就变为了:Transtioning –> Ready,然后调用 play 方法,就实现了自动播放下一曲。
//状态改变事件
private void musicPlayer_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
//歌曲播放完,变换索引
if (musicPlayer.playState == WMPLib.WMPPlayState.wmppsMediaEnded)
{
int index = listBox1.SelectedIndex;
if (index == path.Length - 1)
{
index = 0;
}
else
{
index++;
}
listBox1.SelectedIndex = index;
}
if (musicPlayer.playState == WMPLib.WMPPlayState.wmppsReady)
{
try
{
musicPlayer.Ctlcontrols.play();
btnPlay.Text = "暂停";
}
catch
{
}
}
}
★解释一下为什么是在 ready 状态之后,调用播放方法?
因为在播放之前必须得给 musicplayer 一个歌曲路径,否则无法播放,而当路径改变的时候会经历两个状态:Transitioning –> Ready,也就是说只有在 Ready 状态时,才会把路径传给 musicplayer ,所以播放方法得在 Ready 状态中。