前言:去年就已經把開發WindowsPhone應用的所有軟硬件環境都置備齊全了(腦子一熱把原來的MOTO安卓機換成了520,裝Windows8 裝vs2012...費了好大的力氣啊),但是由於種種原因,一直沒有時間學習WindowsPhone開發的相關內容。正好湊清明節學校放假,同學們都組團出去歡樂谷遊玩了,我沒有出去,所以就留下來正好可以安穩的學習一下wp了。
廢話不多說,進入正題。
年前做過一個播放音頻的小demo,但是不可以後臺播放,所以這次我就想弄明白到底怎樣可以後臺播放。去百度了好久都沒有找到相關的內容(ps:可能是我數據挖掘學的不咋地)所以就去MSDN搜索相關問題,沒想到還真有後臺播放音頻的講解。所以就依葫蘆畫瓢的做了下來,沒想到還真成了。下面我把實現步驟寫到下面供大家參考學習。希望能幫到大家!
第一步:新建WindowsPhone項目,我這裏命名爲”音樂播放器“,然後在解決方案管管理器中右鍵解決方案名稱->添加->新建項目->Windows Phone音頻播放代理->給項目命名(這裏我命名爲MyPlaybackAgent)->確定。在項目名”音樂播放器“中右鍵->添加->新建文件夾->命名爲Audio,然後右鍵Audio文件夾->添加->現有項->導入幾首mp3格式的音樂。然後全選導入的音樂文件右鍵->屬性->複製到輸出目錄選擇”如果較新則複製“,保存項目。Ok ,到這一步大體框架已經完成。結構如下:
第二步:設計MainPage。
具體步驟不在多說,看下圖:
xaml代碼:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,24,0">
<Button Content="上一首" x:Name="btnPrev" HorizontalAlignment="Left" Margin="23,144,0,0" VerticalAlignment="Top" Click="btnPrev_Click"/>
<Button Content="播放" x:Name="btnPlay" HorizontalAlignment="Left" Margin="173,144,0,0" VerticalAlignment="Top" Click="btnPlay_Click"/>
<Button Content="下一首" x:Name="btnNext" HorizontalAlignment="Left" Margin="326,144,0,0" VerticalAlignment="Top" Click="btnNext_Click_1"/>
<TextBlock HorizontalAlignment="Left" x:Name="txtCurrentTrack" Margin="46,257,0,0" TextWrapping="Wrap" Text="當前播放" VerticalAlignment="Top" Height="42" Width="322"/>
</Grid>
第三步:編碼
1.在解決方案管理器,右鍵選擇MainPage.xaml->查看代碼。
2.引入以下命名空間
using Microsoft.Phone.BackgroundAudio;
3.編輯三個按鈕的Click事件,代碼如下:
#region 播放控制
private void btnNext_Click_1(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipNext();
}
private void btnPrev_Click(object sender, RoutedEventArgs e)
{
BackgroundAudioPlayer.Instance.SkipPrevious();
}
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
if (BackgroundAudioPlayer.Instance.PlayerState!=PlayState.Playing&&BackgroundAudioPlayer.Instance.Track!=null)
{
BackgroundAudioPlayer.Instance.Play();
}
else
{
BackgroundAudioPlayer.Instance.Stop();
}
}
#endregion
4.在MainPage的構造函數裏面加入以下代碼:
BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
5.Instance_PlayStateChanged方法的代碼如下:
void Instance_PlayStateChanged(object sender, EventArgs e)
{
switch (BackgroundAudioPlayer.Instance.PlayerState)
{
case PlayState.Playing:
btnPlay.Content = "暫停";
break;
case PlayState.Paused:
case PlayState.Stopped:
btnPlay.Content = "播放";
break;
}
if (BackgroundAudioPlayer.Instance.Track!=null)
{
txtCurrentTract.Text = BackgroundAudioPlayer.Instance.Track.Title + "By" + BackgroundAudioPlayer.Instance.Track.Artist;
}
}
6.因爲這個應用要實現後臺播放,也就是當用戶按了手機的Back或者Home/Search按鍵退出程序後再次回到頁面後要恢復頁面狀態,所以有必要重寫頁面的OnNavigatedTo事件,實現方法如下(此段代碼添加到MainPage的類中):
/// <summary>
/// 重寫頁面返回
/// </summary>
/// <param name="e"></param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//如果重新回到頁面後播放狀態爲正在播放,則把播放按鈕的Content屬性改爲“暫停”
if (BackgroundAudioPlayer.Instance.PlayerState==PlayState.Playing)
{
btnPlay.Content = "暫停";
txtCurrentTract.Text = BackgroundAudioPlayer.Instance.Track.Title + "by" + BackgroundAudioPlayer.Instance.Track.Artist;
}
else
{
btnPlay.Content = "播放";
txtCurrentTract.Text = "當前無播放歌曲";
}
base.OnNavigatedTo(e);
}
7.在解決方案管理器中找到App.xaml並右鍵查看代碼,引用以下命名空間:
using System.IO.IsolatedStorage;
using System.Windows.Resources;
8.由於BackgrounAudioPlayer只能播放應用獨立存儲區(isolated storage)或者網絡上的音樂資源(Remote URL),所以有必要用下面的方法來把audio文件夾內的文件拷貝到獨立存儲區來滿足播放要求。(一定要確保下面方法中數組中文件的名字和Audio文件夾內的完全一致,不然會出現空引用的異常):
private void CopyToIsolatedStorage()
{
using (IsolatedStorageFile storage=IsolatedStorageFile.GetUserStoreForApplication())
{
string[] files = new string[] {"Celine Dion - My Heart Will Go On.mp3",
"Conway Twitty - Don't Cry Joni.mp3",
"Gala - Young For You.mp3",
"god is a girl.mp3"
};
foreach (var _fileName in files)
{
if (!storage.FileExists(_fileName))
{
string _filePath = "Audio/" + _fileName;
StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));
using (IsolatedStorageFileStream file=storage.CreateFile(_fileName))
{
int chunkSize = 4096;//4M
byte[] bytes = new byte[chunkSize];
int byteCount;
//每次讀4M
while ((byteCount=resource.Stream.Read(bytes,0,chunkSize))>0)
{
file.Write(bytes, 0, byteCount);
}
}
}
}
}
}
9.在App.xaml頁的構造函數中調用CopyToIsolatedStorage方法:
CopyToIsolatedStorage();
10.因爲音頻代理是應用的一部分,當應用處於後臺時也會繼續運行。所以接下來要爲項目”音樂播放器“引入代理,方法如下:
在解決方案資源管理器中右鍵”音樂播放器“項目中的”引用“->添加引用->解決方案->MyAudioPlaybackAgent->確定。如下圖:
-----------------------------------------------------------以下是對AudioPlayer.cs文件進行的操作----------------------------------------
11.打開解決方案資源管理器中音頻代理項目中的AudioPlayer.cs文件,在代碼中添加以下命名空間的引用:
using System.Collections.Generic;
12.在AudioPlayer.cs文件中聲明一個靜態的int型的變量用來代表當前播放曲目的個數:
static int currentTrackNumber = 0;//初始爲零
13.定義一個Track類型的數組,用來保存播放列表(這裏定義成靜態的是非常有必要的,這樣就不用每次調用音頻代理時都重新初始化它,節省資源):
private static List<AudioTrack> _playList = new List<AudioTrack>
{
new AudioTrack(new Uri("Celine Dion - My Heart Will Go On.mp3", UriKind.Relative),
"Celine Dion",
"",
"",
null),
new AudioTrack(new Uri("Conway Twitty - Don't Cry Joni.mp3", UriKind.Relative),
"Conway Twitty",
"",
"",
null),
new AudioTrack(new Uri("Gala - Young For You.mp3", UriKind.Relative),
"Gala",
"",
"",
null),
new AudioTrack(new Uri("god is a girl.mp3", UriKind.Relative),
"Star",
"",
"",
null),
// 一首網絡歌曲(設備需聯網)
new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute),
"Episode 29",
"Windows Phone Radio",
"Windows Phone Radio Podcast",
null)
};
14.添加一下代碼用來響應用戶的操作(播放,上一首,下一首):
private void PlayNextTrack(BackgroundAudioPlayer player)
{
if (++currentTrackNumber >= _playList.Count)
{
currentTrackNumber = 0;
}
PlayTrack(player);
}
private void PlayPreviousTrack(BackgroundAudioPlayer player)
{
if (--currentTrackNumber < 0)
{
currentTrackNumber = _playList.Count - 1;
}
PlayTrack(player);
}
private void PlayTrack(BackgroundAudioPlayer player)
{
if ((player.Track == null) || (player.Track.Title != _playList[currentTrackNumber].Title))
{
player.Track = _playList[currentTrackNumber];
}
if ((player.Track != null) && (player.PlayerState != PlayState.Playing))
{
player.Play();
}
}
15.在OnPlayStateChanged事件中添加以下代碼(添加在NotifyComplete之前):
switch (playState)
{
case PlayState.TrackEnded:
PlayNextTrack(player);
break;
// Handle other PlayState changes here
}
16.在OnUserAction 方法中添加以下代碼(添加在NotifyComplete之前):
switch (playState)
{
case PlayState.TrackEnded:
PlayNextTrack(player);
break;
// Handle other PlayState changes here
}
17.在OnUserAction 方法中添加以下代碼(添加在NotifyComplete之前):
switch (action)
{
case UserAction.Play:
PlayTrack(player);
break;
case UserAction.Pause:
player.Pause();
break;
case UserAction.SkipPrevious:
PlayPreviousTrack(player);
break;
case UserAction.SkipNext:
PlayNextTrack(player);
break;
}
18.Ok,到此爲止所有的工作都已經完成,剩下的就是測試你的應用了,以下是我的測試截圖:
好啦,到此及本上就完成了一個最簡單的音樂播放器.自己可以發揮想象,加入自己的靈感,讓應用更靈活,做一個自己的音樂播放器.