WPF開發較為完整的音樂播放器(一) ---音樂播放類的構建


 

    近來閑來有事,便想到用自己這段時間學習的知識寫一個音樂播放器。提前聲明,我不擅長界面,因此做出來的界面的卻有些次,但不是本系列文章的重點。

    先講下我們開發此音樂播放器所用到的技術:數據綁定、Xml、MediaPlayer類、數據模板等,將在之后陸續講解。

   來闡述下播放器開發的整體思路:構建音樂播放類用於播放音樂,用兩個控件分別作為播放列表和播放控制,並且利用控件模板改變它們的界面,利用Xml數據讀取類XmlListsReader來讀取位於存放列表的xml,將歌曲名稱、文件路徑、持續時間歌手等信息讀取到Product類中,並設置ListBox的ItemSouse為此類,采用數據模板顯示數據。

    好了,開始我們第一部分的教程--音樂播放類的構建。

  

  話說利用WPF播放音樂有多種方法:MediaPlayer類,SoundPlayer類,以及使用DirectX Sound等。若要選擇一種功能較多,方便易用的方法,定要屬MediaPlayer類了,唯一的限制就是需要依賴Windows Media Player(WMP)。不過在Windows環境下,這一限制可以忽略不計,都是系統自帶的,不是嗎?

    當然,我們可以直接在窗口中防置MediaPlayer的操作代碼,但是為了更正規化和可維護性,我們將它封裝進MusicPlayer類中。  

  在類的開頭,先來定義幾個私有變量和公有的枚舉(表示播放器的狀態):

       public enum PlayState : int
       {
           stoped = 0,
           playing = 1,
           paused = 2
       }
       private MediaPlayer player = null;
       private Uri musicfile;
       private PlayState state;

       public Uri MusicFile
       {
           set
           {
               musicfile = value;
           }
           get
           {
               return musicfile;
           }
       }

接下來寫構造函數,一個帶參數(音樂文件路徑),一個不帶參數的:

       public MusicPlay()
       {
           player = new MediaPlayer();
       }
       public MusicPlay(Uri file)
       {
           Load(file);          
       }

構造函數將傳入的文件路徑傳到Load方法中處理,以下是Load方法的代碼:

       public void Load(Uri file)
       {
           player = new MediaPlayer();
           MusicFile = file;
           player.Open(musicfile);

       }


Load方法中設置了MusicFile(公有變量,指示文件路徑),用MediaPlayer的Open方法加載了音樂文件。

接下來是播放、暫停、停止的代碼:

       public void Play()
       {
           player.Play();
           state = PlayState.playing;
       }
       public void Pause()
       {
           player.Pause();
           state = PlayState.paused;
       }
       public void Stop()
       {
           player.Stop();
           state = PlayState.stoped;
       }


以上三個方法的第一句代碼分別是設置播放、暫停、停止,第二句代碼是設置播放器當前的狀態。

然后是獲取音樂文件的自然持續時間:

       public TimeSpan GetMusicDurationTime()
       {
           while (!player.NaturalDuration.HasTimeSpan)
           {
               if (player.NaturalDuration.HasTimeSpan)
               {
                   return player.NaturalDuration.TimeSpan;
               }
           }
           return new TimeSpan();
       }

這里用了MediaPlayer的NaturalDuration.HasTimeSpan檢查是否可以讀取音樂的自然持續時間,還用了While循環避免了讀取到空值或讀取不到的情況。

這是設置和獲取當前進度的方法:

       public void SetPosition(TimeSpan tp)
       {
           player.Position = tp;
       }
       public TimeSpan GetPosition()
       {
           return player.Position;
       }

設置音量和讀取音量,傳入參數為0即是靜音:

       public void SetVolume(double volume)
       {
           player.Volume = volume;
       }
       public double GetVolume(double volume)
       {
          return player.Volume;
       }


獲取和設置當前播放器的狀態,這里只是三種狀態,但實際可能會更多:

       public PlayState GetPlayState()
       {
           return state;
       }
       public void SetPlayState(PlayState state)
       {
           if (state == PlayState.playing)
           {
               this.Play();
           }
           else if (state == PlayState.paused)
           {
               this.Pause();
           }
           else if (state == PlayState.stoped)
           {
               this.Stop();
           }
       }


再加個根據文件路徑獲取音樂名字的方法:

       public string GetMusicTitle()
       {
           string title=player.Source.ToString();
           return title.Substring(title.LastIndexOf("/")+1, title.Length - title.LastIndexOf("/")-1);
       }

這個方法的第二句代碼就是截取字符串最后一個"/"后邊的部分。

還有我在這里還定義了個  DispatcherTimer,用來更新音樂的位置,完全可以用更改通知來完成相同的任務,但我沒有用到,大家可以嘗試下。

以下是完整代碼,沒寫注釋,湊合看吧,應該不難:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
namespace WpfApplication10
{
   public  class MusicPlay
    {
       public enum PlayState : int
       {
           stoped = 0,
           playing = 1,
           paused = 2
       }
       private MediaPlayer player = null;
       private Uri musicfile;
       private PlayState state;

       public Uri MusicFile
       {
           set
           {
               musicfile = value;
           }
           get
           {
               return musicfile;
           }
       }

      public DispatcherTimer dt = null;
       public MusicPlay()
       {
           player = new MediaPlayer();
       }
       public MusicPlay(Uri file)
       {
           Load(file);
           
           
       }

       public void Load(Uri file)
       {
           player = new MediaPlayer();
           MusicFile = file;
           player.Open(musicfile);

       }

       public void Play()
       {
           player.Play();
           dt.Start();
           state = PlayState.playing;
       }
       public void Pause()
       {
           player.Pause();
           state = PlayState.paused;
       }
       public void Stop()
       {
           player.Stop();
           state = PlayState.stoped;
       }
       public string GetMusicTitle()
       {
           string title=player.Source.ToString();
           return title.Substring(title.LastIndexOf("/")+1, title.Length - title.LastIndexOf("/")-1);
           //return "";
       }
       public TimeSpan GetMusicDuringTime()
       {
           while (!player.NaturalDuration.HasTimeSpan)
           {
               if (player.NaturalDuration.HasTimeSpan)
               {
                   return player.NaturalDuration.TimeSpan;
               }
           }
           return new TimeSpan();
          
       }
       public void SetPosition(TimeSpan tp)
       {
           player.Position = tp;
       }
       public TimeSpan GetPosition()
       {
           return player.Position;
       }
       public void SetVolume(double volume)
       {
           player.Volume = volume;
       }
       public double GetVolume(double volume)
       {
          return player.Volume;
       }
       public PlayState GetPlayState()
       {
           return state;
       }
       public void SetPlayState(PlayState state)
       {
           if (state == PlayState.playing)
           {
               this.Play();
           }
           else if (state == PlayState.paused)
           {
               this.Pause();
           }
           else if (state == PlayState.stoped)
           {
               this.Stop();
           }
       }
    }
}


可別急着構建界面。。。在下篇文章中我們將構建Xml讀取類,敬請期待,同時期待拍磚者的到來。。。。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM