lifewahaha

前言:去年就已经把开发WindowsPhone应用的所有软硬件环境都置备齐全了(脑子一热把原来的MOTO安卓机换成了520,装Windows8 装vs2012...费了好大的力气啊吐舌头),但是由于种种原因,一直没有时间学习WindowsPhone开发的相关内容。正好凑清明节学校放假,同学们都组团出去欢乐谷游玩了,我没有出去,所以就留下来正好可以安稳的学习一下wp了。

     废话不多说,进入正题。大笑

     年前做过一个播放音频的小demo,但是不可以后台播放,所以这次我就想弄明白到底怎样可以后台播放。去百度了好久都没有找到相关的内容(ps:可能是我数据挖掘学的不咋地)所以就去MSDN搜索相关问题,没想到还真有后台播放音频的讲解。所以就依葫芦画瓢的做了下来,没想到还真成了。下面我把实现步骤写到下面供大家参考学习。希望能帮到大家!

 

第一步:新建WindowsPhone项目,我这里命名为”音乐播放器“,然后在解决方案管管理器中右键解决方案名称->添加->新建项目->Windows Phone音频播放代理->给项目命名(这里我命名为MyPlaybackAgent)->确定。在项目名”音乐播放器“中右键->添加->新建文件夹->命名为Audio,然后右键Audio文件夹->添加->现有项->导入几首mp3格式的音乐。然后全选导入的音乐文件右键->属性->复制到输出目录选择”如果较新则复制“,保存项目。Ok ,到这一步大体框架已经完成。结构如下:

 

      

 

第二步:设计MainPage。

   具体步骤不在多说,看下图:

xaml代码:

  1. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,24,0">  
  2.             <Button Content="上一首" x:Name="btnPrev" HorizontalAlignment="Left" Margin="23,144,0,0" VerticalAlignment="Top" Click="btnPrev_Click"/>  
  3.             <Button Content="播放" x:Name="btnPlay" HorizontalAlignment="Left" Margin="173,144,0,0" VerticalAlignment="Top" Click="btnPlay_Click"/>  
  4.             <Button Content="下一首" x:Name="btnNext" HorizontalAlignment="Left" Margin="326,144,0,0" VerticalAlignment="Top" Click="btnNext_Click_1"/>  
  5.             <TextBlock HorizontalAlignment="Left" x:Name="txtCurrentTrack" Margin="46,257,0,0" TextWrapping="Wrap" Text="当前播放" VerticalAlignment="Top" Height="42" Width="322"/>  
  6.   
  7.         </Grid>  

第三步:编码

1.在解决方案管理器,右键选择MainPage.xaml->查看代码。

2.引入以下命名空间

  1. using Microsoft.Phone.BackgroundAudio;  


3.编辑三个按钮的Click事件,代码如下:

  1. #region 播放控制  
  2.        private void btnNext_Click_1(object sender, RoutedEventArgs e)  
  3.        {  
  4.            BackgroundAudioPlayer.Instance.SkipNext();  
  5.        }  
  6.   
  7.        private void btnPrev_Click(object sender, RoutedEventArgs e)  
  8.        {  
  9.            BackgroundAudioPlayer.Instance.SkipPrevious();  
  10.        }  
  11.   
  12.        private void btnPlay_Click(object sender, RoutedEventArgs e)  
  13.        {  
  14.            if (BackgroundAudioPlayer.Instance.PlayerState!=PlayState.Playing&&BackgroundAudioPlayer.Instance.Track!=null)  
  15.            {  
  16.                BackgroundAudioPlayer.Instance.Play();  
  17.            }  
  18.            else  
  19.            {  
  20.                BackgroundAudioPlayer.Instance.Stop();  
  21.            }  
  22.        }  
  23.        #endregion  


4.在MainPage的构造函数里面加入以下代码:

  1. BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);  

5.Instance_PlayStateChanged方法的代码如下:


 

  1. void Instance_PlayStateChanged(object sender, EventArgs e)  
  2.       {  
  3.           switch (BackgroundAudioPlayer.Instance.PlayerState)  
  4.           {  
  5.               case PlayState.Playing:  
  6.                   btnPlay.Content = "暂停";  
  7.                   break;  
  8.               case PlayState.Paused:  
  9.               case PlayState.Stopped:  
  10.                   btnPlay.Content = "播放";  
  11.                   break;  
  12.            }  
  13.           if (BackgroundAudioPlayer.Instance.Track!=null)  
  14.           {  
  15.               txtCurrentTract.Text = BackgroundAudioPlayer.Instance.Track.Title + "By" + BackgroundAudioPlayer.Instance.Track.Artist;  
  16.   
  17.           }  
  18.       }  

6.因为这个应用要实现后台播放,也就是当用户按了手机的Back或者Home/Search按键退出程序后再次回到页面后要恢复页面状态,所以有必要重写页面的OnNavigatedTo事件,实现方法如下(此段代码添加到MainPage的类中):


 

  1. /// <summary>  
  2.        /// 重写页面返回  
  3.        /// </summary>  
  4.        /// <param name="e"></param>  
  5.        protected override void OnNavigatedTo(NavigationEventArgs e)  
  6.        {  
  7.            //如果重新回到页面后播放状态为正在播放,则把播放按钮的Content属性改为“暂停”  
  8.            if (BackgroundAudioPlayer.Instance.PlayerState==PlayState.Playing)  
  9.            {  
  10.                btnPlay.Content = "暂停";  
  11.                txtCurrentTract.Text = BackgroundAudioPlayer.Instance.Track.Title + "by" + BackgroundAudioPlayer.Instance.Track.Artist;  
  12.            }  
  13.            else  
  14.            {  
  15.                btnPlay.Content = "播放";  
  16.                txtCurrentTract.Text = "当前无播放歌曲";  
  17.            }  
  18.                base.OnNavigatedTo(e);  
  19.        }  


7.在解决方案管理器中找到App.xaml并右键查看代码,引用以下命名空间:

  1. using System.IO.IsolatedStorage;  
  2. using System.Windows.Resources;  

8.由于BackgrounAudioPlayer只能播放应用独立存储区(isolated storage)或者网络上的音乐资源(Remote URL),所以有必要用下面的方法来把audio文件夹内的文件拷贝到独立存储区来满足播放要求。(一定要确保下面方法中数组中文件的名字和Audio文件夹内的完全一致,不然会出现空引用的异常):

  1. private void CopyToIsolatedStorage()  
  2.        {  
  3.            using (IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForApplication())  
  4.            {  
  5.                string[] files = new string[] {"Celine Dion - My Heart Will Go On.mp3",  
  6.                "Conway Twitty - Don\'t Cry Joni.mp3",  
  7.                "Gala - Young For You.mp3",  
  8.                "god is a girl.mp3"  
  9.                };  
  10.                foreach (var _fileName in files)  
  11.                {  
  12.                    if (!storage.FileExists(_fileName))  
  13.                    {  
  14.                        string _filePath = "Audio/" + _fileName;  
  15.                        StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));  
  16.   
  17.                        using (IsolatedStorageFileStream file=storage.CreateFile(_fileName))  
  18.                        {  
  19.                            int chunkSize = 4096;//4M  
  20.                            byte[] bytes = new byte[chunkSize];  
  21.                            int byteCount;  
  22.                            //每次读4M  
  23.                            while ((byteCount=resource.Stream.Read(bytes,0,chunkSize))>0)  
  24.                            {  
  25.                                file.Write(bytes, 0, byteCount);  
  26.                            }  
  27.   
  28.                        }  
  29.                    }  
  30.                }  
  31.            }  
  32.        }  


9.在App.xaml页的构造函数中调用CopyToIsolatedStorage方法:

  1. CopyToIsolatedStorage();  


10.因为音频代理是应用的一部分,当应用处于后台时也会继续运行。所以接下来要为项目”音乐播放器“引入代理,方法如下:

在解决方案资源管理器中右键”音乐播放器“项目中的”引用“->添加引用->解决方案->MyAudioPlaybackAgent->确定。如下图:

 


-----------------------------------------------------------以下是对AudioPlayer.cs文件进行的操作----------------------------------------

 11.打开解决方案资源管理器中音频代理项目中的AudioPlayer.cs文件,在代码中添加以下命名空间的引用:

  1. using System.Collections.Generic;  


12.在AudioPlayer.cs文件中声明一个静态的int型的变量用来代表当前播放曲目的个数:

  1. static int currentTrackNumber = 0;//初始为零  

13.定义一个Track类型的数组,用来保存播放列表(这里定义成静态的是非常有必要的,这样就不用每次调用音频代理时都重新初始化它,节省资源):

  1.  private static List<AudioTrack> _playList = new List<AudioTrack>  
  2. {  
  3.     new AudioTrack(new Uri("Celine Dion - My Heart Will Go On.mp3", UriKind.Relative),   
  4.                     "Celine Dion",   
  5.                     "",   
  6.                     "",   
  7.                     null),  
  8.   
  9.     new AudioTrack(new Uri("Conway Twitty - Don\'t Cry Joni.mp3", UriKind.Relative),   
  10.                     "Conway Twitty",   
  11.                     "",   
  12.                     "",   
  13.                     null),  
  14.   
  15.     new AudioTrack(new Uri("Gala - Young For You.mp3", UriKind.Relative),   
  16.                     "Gala",   
  17.                     "",   
  18.                     "",   
  19.                     null),  
  20.     new AudioTrack(new Uri("god is a girl.mp3", UriKind.Relative),   
  21.                     "Star",   
  22.                     "",   
  23.                     "",   
  24.                     null),  
  25.   
  26.     // 一首网络歌曲(设备需联网)  
  27.     new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute),   
  28.                     "Episode 29",   
  29.                     "Windows Phone Radio",   
  30.                     "Windows Phone Radio Podcast",   
  31.                     null)  
  32. };  


14.添加一下代码用来响应用户的操作(播放,上一首,下一首):


 

  1. private void PlayNextTrack(BackgroundAudioPlayer player)  
  2.      {  
  3.          if (++currentTrackNumber >= _playList.Count)  
  4.          {  
  5.              currentTrackNumber = 0;  
  6.          }  
  7.   
  8.          PlayTrack(player);  
  9.      }  
  10.   
  11.      private void PlayPreviousTrack(BackgroundAudioPlayer player)  
  12.      {  
  13.          if (--currentTrackNumber < 0)  
  14.          {  
  15.              currentTrackNumber = _playList.Count - 1;  
  16.          }  
  17.   
  18.          PlayTrack(player);  
  19.      }  
  20.   
  21.      private void PlayTrack(BackgroundAudioPlayer player)  
  22.      {  
  23.          if ((player.Track == null) || (player.Track.Title != _playList[currentTrackNumber].Title))  
  24.          {  
  25.                 
  26.              player.Track = _playList[currentTrackNumber];  
  27.          }  
  28.   
  29.           
  30.          if ((player.Track != null) && (player.PlayerState != PlayState.Playing))  
  31.          {  
  32.              player.Play();  
  33.          }  
  34.      }  

15.在OnPlayStateChanged事件中添加以下代码(添加在NotifyComplete之前):

  1. switch (playState)  
  2. {  
  3.     case PlayState.TrackEnded:  
  4.         PlayNextTrack(player);  
  5.         break;  
  6.   
  7.     // Handle other PlayState changes here  
  8. }  

16.在OnUserAction 方法中添加以下代码(添加在NotifyComplete之前):

 

  1. switch (playState)  
  2. {  
  3.     case PlayState.TrackEnded:  
  4.         PlayNextTrack(player);  
  5.         break;  
  6.   
  7.     // Handle other PlayState changes here  
  8. }  

17.在OnUserAction 方法中添加以下代码(添加在NotifyComplete之前):

 

  1. switch (action)  
  2. {  
  3.   case UserAction.Play:  
  4.     PlayTrack(player);  
  5.     break;  
  6.   
  7.   case UserAction.Pause:  
  8.     player.Pause();  
  9.     break;  
  10.   
  11.   case UserAction.SkipPrevious:  
  12.     PlayPreviousTrack(player);  
  13.     break;  
  14.   
  15.   case UserAction.SkipNext:  
  16.     PlayNextTrack(player);  
  17.     break;  
  18. }  


18.Ok,到此为止所有的工作都已经完成,剩下的就是测试你的应用了,以下是我的测试截图:


好啦,到此及本上就完成了一个最简单的音乐播放器.自己可以发挥想象,加入自己的灵感,让应用更灵活,做一个自己的音乐播放器.

 

引用原文地址:http://star.phblog.tk/forum.php?mod=viewthread&tid=10&extra=page%3D1

分类:

技术点:

相关文章: