这次目标是实现基本播放功能,包括:音乐播放、上一首下一首、切歌模式的切换、音量控制、播放进度显示与控制。
在我的项目中,歌曲列表是主窗口的子页面,当我双击歌曲列表中的某一行时,需要调用主函数中的函数,在这里我选择用委托的方式来实现此功能。
1 private void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e) 2 { 3 Song o = song_ListView.SelectedItem as Song; 4 if (o == null) 5 return; 6 getSongNum(o.Num-1); //将歌曲序号传给主页面 7 song_ListView.SelectedItem = null; //双击后取消选中。 8 } 9 10 public delegate void GetSongNum(int num); 11 public GetSongNum getSongNum;
能获取到顺序后面的事情就简单多了。
在主页面后台实例化一个MediaElement类 player 与DispatherTimer类 timer,player用于播放音乐,timer用于进度条控制。
1 MediaElement player = new MediaElement() 2 { 3 LoadedBehavior = MediaState.Manual, 4 Volume = 10 5 }; //播放音乐 6 DispatcherTimer timer = new DispatcherTimer() 7 { 8 Interval = TimeSpan.FromSeconds(0.1), 9 }; //控制进度条
Show_Song函数中,除了显示歌曲的封面、名字等功能外,还要根据子窗口传入的参数播放对应的音乐
1 private void Show_Song(int num) //根据序号把歌曲的封面,歌名,歌手显示到左下角 2 { 3 try 4 { 5 MemoryStream stream = new MemoryStream(Pages.Music_Local.songs[num].Cover); 6 BitmapImage bmp = new BitmapImage(); 7 8 bmp.BeginInit(); //初始化 9 bmp.StreamSource = stream; //设置源 10 bmp.EndInit(); //初始化结束 11 music_cover_img.Source = bmp; //设置封面 12 13 song_name_btn.Content = Pages.Music_Local.songs[num].Title; //设置歌曲名 14 singer_name_btn.Content = Pages.Music_Local.songs[num].Singer; //设置歌手名 15 16 player.Source = new Uri(Pages.Music_Local.songs[num].Url); //设置播放路径 17 song_Value.Value = 0; 18 song_Value.Maximum = Pages.Music_Local.songs[num].Time; //设置进度条的最大长度 19 time_Max.Text = Pages.Music_Local.songs[num].Duration; //设置最大时间 20 play_icon.Kind = MaterialDesignThemes.Wpf.PackIconKind.Pause; 21 player.Play(); //开始播放 22 timer.Start(); //开始计时 23 return; 24 } 25 catch(Exception ex) 26 { 27 MessageBox.Show(ex.Message); 28 return; 29 } 30 }
控制进度条进度就是在timer的Tick事件中修改进度条的value值即可。
1 private void timer_Tick(object sender, EventArgs e) 2 { 3 song_Value.Value = player.Position.TotalSeconds; //进度条进度 4 time_Now.Text = player.Position.Minutes.ToString().PadLeft(2, '0') + ":" + player.Position.Seconds.ToString().PadLeft(2, '0'); //当前时间显示 5 }
调整播放进度就是进度条的valueChanged事件,在这里设置player的进度等于进度条的进度即可。
1 private void song_Value_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 2 { 3 player.Position = TimeSpan.FromSeconds(song_Value.Value); //拖动进度 4 }
切歌功能我准备定义两个全局变量,保存上一首播放的歌的Num与现在播放的歌的Num,按下对应按钮就调用放歌的函数即可。保存上一首播放的歌的原因是如果播放模式是随机播放,按上一首就不能按顺序来,所以设置这个变量。
同时还需要设置一个变量来表示播放模式。
int Last_SongNum = 0; //上一首 int Now_SongNum = 0; //正在播放 int play_Mode = 0; //播放模式,0:顺序播放 1:随机播放 2:循环播放 #region 下一首按钮点击事件 private void next_btn_Click(object sender, RoutedEventArgs e) { Last_SongNum = Now_SongNum; switch (play_Mode) { case 0: //顺序播放 case 2: //循环播放 if (Now_SongNum >= Pages.Music_Local.songs.Count - 1) Show_Song(0); //播放第一首 else Show_Song(Now_SongNum + 1); break; case 1: //随机播放 Show_Song(new Random().Next(0, Pages.Music_Local.songs.Count)); break; } } #endregion #region 上一首按钮点击事件 private void previous_btn_Click(object sender, RoutedEventArgs e) { if (play_Mode == 0 || play_Mode == 2) { if (Now_SongNum <= 0) Show_Song(Pages.Music_Local.songs.Count-1); //播放最后一首 else Show_Song(Now_SongNum - 1); //播放上一首 } else //随机播放 { Show_Song(Last_SongNum); } } #endregion #region 播放模式点击事件 private void play_Mode_btn_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { switch (play_Mode) { case 0: play_Mode = 1; play_Mode_btn.Source = new BitmapImage(new Uri("F://C#//WPF//FatboyMusic//icon//随机.png")); break; case 1: play_Mode = 2; play_Mode_btn.Source = new BitmapImage(new Uri("F://C#//WPF//FatboyMusic//icon//单曲循环.png")); break; case 2: play_Mode = 0; play_Mode_btn.Source = new BitmapImage(new Uri("F://C#//WPF//FatboyMusic//icon//列表循环.png")); break; } } #endregion
最后把音量控制实现。
1 #region 音量控制条拖动事件 2 private void volume_Value_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 3 { 4 player.Volume = volume_Value.Value; 5 } 6 #endregion 7 8 private void volume_Btn_Click(object sender, RoutedEventArgs e) 9 { 10 if (volumen_Btn_logo.Kind == MaterialDesignThemes.Wpf.PackIconKind.VolumeSource) 11 { 12 volume_Value.Value = 0; 13 volumen_Btn_logo.Kind = MaterialDesignThemes.Wpf.PackIconKind.VolumeVariantOff; 14 } 15 else 16 { 17 volume_Value.Value = 0.5; 18 volumen_Btn_logo.Kind = MaterialDesignThemes.Wpf.PackIconKind.VolumeSource; 19 } 20 }
最后的效果图:
今天的目标也就实现了,明天的目标是把搜索本地音乐、添加音乐功能实现,还有歌词页也可以尝试一下,继续加油。