與眾不同 windows phone (40) - 8.0 媒體: 音樂中心的新增功能, 圖片中心的新增功能, 后台音樂播放的新增功能
作者:webabcd
介紹
與眾不同 windows phone 8.0 之 媒體
- 添加音樂到音樂中心,從音樂中心刪除音樂
- 與圖片中心相關的新增功能
- BackgroundAudioPlayer 的新增功能
示例
1、演示如何添加音樂到音樂中心,以及如何從音樂中心刪除音樂
MusicMediaLibrary/MusicMediaLibrary.xaml
<phone:PhoneApplicationPage x:Class="Demo.Media.MusicMediaLibrary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <Button x:Name="btnAdd" Content="添加音樂到音樂中心" Click="btnAdd_Click" /> <Button x:Name="btnDelete" Content="從音樂中心刪除音樂" Click="btnDelete_Click" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
MusicMediaLibrary/MusicMediaLibrary.xaml.cs
/* * 演示如何添加音樂到音樂中心,以及如何從音樂中心刪除音樂 * * * 在 wp8 中新增了 Microsoft.Xna.Framework.Media.PhoneExtensions.MediaLibraryExtensions,其擴展了 MediaLibrary 類 * MediaLibrary.SaveSong(Uri filename, SongMetadata songMetadata, SaveSongOperation operation) - 保存音樂到音樂中心,返回 Song 對象 * Uri filename - 需要添加到音樂中心的音樂文件,必須在 IsolatedStorage 下 * SongMetadata songMetadata - 元數據 * SaveSongOperation operation - CopyToLibrary 拷貝音樂文件;MoveToLibrary 移動音樂文件 * MediaLibrary.Delete(Song song) - 根據 Song 對象從音樂中心刪除數據 * * * 注: * 1、需要在 manifest 中增加配置 <Capability Name="ID_CAP_MEDIALIB_AUDIO" /> * 2、音樂文件只支持mp3和wma,且必須在 IsolatedStorage 下 * 3、音樂的封面文件只支持jpg,且必須在 IsolatedStorage 下 * * * 另: * 1、播放音樂或視頻的話,需要在 manifest 中增加配置 <Capability Name="ID_CAP_MEDIALIB_PLAYBACK" /> * 2、除了用 MediaElement 播放音樂外,還可以用 MediaPlayer(xna) 播放,參見:http://www.cnblogs.com/webabcd/archive/2011/07/11/2102713.html */ using System; using System.Collections.Generic; using System.Windows; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Media.PhoneExtensions; using System.IO.IsolatedStorage; using System.IO; using Windows.Storage.Streams; using Windows.Storage; using System.Threading.Tasks; namespace Demo.Media { public partial class MusicMediaLibrary : PhoneApplicationPage { private Random _random = new Random(); public MusicMediaLibrary() { InitializeComponent(); } private async void btnAdd_Click(object sender, RoutedEventArgs e) { // 將相關文件復制到 ApplicationData 的 Local 目錄下 await CopyFileToApplicationData(new Uri("ms-appx:///Assets/Demo.mp3", UriKind.Absolute), "Demo.mp3"); await CopyFileToApplicationData(new Uri("ms-appx:///Assets/Son.jpg", UriKind.Absolute), "Son.jpg"); // 將相關文件復制到 IsolatedStorage 的根目錄下 // CopyFileToIsolatedStorage(new Uri("Assets/Demo.mp3", UriKind.Relative), "Demo.mp3"); // CopyFileToIsolatedStorage(new Uri("Assets/Son.jpg", UriKind.Relative), "Son.jpg"); // 需要添加到音樂中心的音樂文件僅支持mp3和wma,且必須在 ApplicationData 下,以下格式會先在 Local 目錄下找,找不到再到 Local/IsolatedStorage 目錄下找 Uri musicUri = new Uri("Demo.mp3", UriKind.Relative); // 需要添加到音樂中心的音樂封面文件僅支持jpg,且必須在 ApplicationData 下,以下格式會先在 Local 目錄下找,找不到再到 Local/IsolatedStorage 目錄下找 Uri picUri = new Uri("Son.jpg", UriKind.Relative); // 構造 SongMetadata 對象 // 如果按以下內容設置 SongMetadata 對象,則音樂文件在音樂中心的保存路徑為:webabcd/webabcd album/music xxxx.mp3 SongMetadata sm = new SongMetadata(); sm.AlbumName = "webabcd album"; sm.ArtistName = "webabcd"; sm.GenreName = "rock"; sm.Name = "music " + _random.Next(1000, 10000).ToString(); sm.ArtistBackgroundUri = picUri; sm.AlbumArtUri = picUri; sm.AlbumArtistBackgroundUri = picUri; MediaLibrary library = new MediaLibrary(); try { // 添加音樂文件到音樂中心 Song song = library.SaveSong(musicUri, sm, SaveSongOperation.CopyToLibrary); } catch (Exception ex) { // 如果文件已存在,則會拋出 System.InvalidOperationException 異常 MessageBox.Show(ex.Message); } } private void btnDelete_Click(object sender, RoutedEventArgs e) { /* * MediaLibrary - 媒體庫 * Songs - 返回音樂中心的 SongCollection * Albums - 返回音樂中心的 AlbumCollection * Artists - 返回音樂中心的 ArtistCollection * Genres - 返回音樂中心的 GenreCollection * Playlists - 返回音樂中心的 Playlists */ MediaLibrary library = new MediaLibrary(); // 通過 MediaLibrary 遍歷音樂中心中的音樂文件 foreach (Song song in library.Songs) { // 從音樂中心刪除音樂文件 if (song.Artist.Name == "webabcd") library.Delete(song); } } // 將文件從 Package 復制到 IsolatedStorage 的根目錄下 private void CopyFileToIsolatedStorage(Uri sourceUri, string targetFileName) { IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); using (Stream input = Application.GetResourceStream(sourceUri).Stream) { using (IsolatedStorageFileStream output = isf.CreateFile(targetFileName)) { byte[] readBuffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = input.Read(readBuffer, 0, readBuffer.Length)) > 0) { output.Write(readBuffer, 0, bytesRead); } } } } // 將文件從 Package 復制到 ApplicationData 的 Local 目錄下 private async Task CopyFileToApplicationData(Uri sourceUri, string targetFileName) { StorageFolder applicationFolder = ApplicationData.Current.LocalFolder; StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(sourceUri); await sourceFile.CopyAsync(applicationFolder, targetFileName, NameCollisionOption.ReplaceExisting); } } }
2、演示與圖片中心相關的新增功能
MusicMediaLibrary/PictureMediaLibrary.xaml
<phone:PhoneApplicationPage x:Class="Demo.Media.PictureMediaLibrary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <Image Name="img" Width="50" Height="50" /> <Image Name="img2" Width="50" Height="50" Margin="0 10 0 0" /> <Image Name="img3" Width="50" Height="50" Margin="0 10 0 0" /> <Button x:Name="btnGet" Content="獲取圖片中心的圖片的小縮略圖和預覽圖" Click="btnGet_Click" /> <Button x:Name="btnShare" Content="共享圖片中心的指定的圖片" Click="btnShare_Click" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
MusicMediaLibrary/PictureMediaLibrary.xaml.cs
/* * 演示與圖片中心相關的新增功能 * * * 在 wp8 中新增了 Microsoft.Xna.Framework.Media.PhoneExtensions.MediaLibraryExtensions,其擴展了 MediaLibrary 類和 Picture 類 * Picture.GetPreviewImage() - 獲取預覽圖(介於縮略圖與原圖之間) * Picture.GetPath() - 獲取文件路徑,可以用於“共享”之類的場景,本例會介紹 * MediaLibrary.GetPathFromToken(fileToken) - 根據 token 獲取媒體庫文件的路徑 * * * 注: * 1、需要在 manifest 中增加配置 <Capability Name="ID_CAP_MEDIALIB_PHOTO" /> * 2、在 wp8 中,保存在手機上的每個圖片,系統都將為其自動創建兩種縮略圖:小縮略圖和預覽圖 */ using System.Linq; using System.Windows; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework.Media; using Microsoft.Xna.Framework.Media.PhoneExtensions; using Microsoft.Phone; using Microsoft.Phone.Tasks; namespace Demo.Media { public partial class PictureMediaLibrary : PhoneApplicationPage { public PictureMediaLibrary() { InitializeComponent(); } private void btnGet_Click(object sender, RoutedEventArgs e) { /* * MediaLibrary - 媒體庫 * Pictures - 返回圖片中心的全部圖片 * SavedPictures - 返回圖片中心的已保存圖片 * RootPictureAlbum - 返回圖片中心的所有根相冊 */ MediaLibrary library = new MediaLibrary(); if (library.Pictures.Count > 0) { // 獲取圖片中心的第一張圖片 Picture picture = library.Pictures.First(); img.Source = PictureDecoder.DecodeJpeg(picture.GetImage()); // 獲取原圖 img2.Source = PictureDecoder.DecodeJpeg(picture.GetThumbnail()); // 獲取縮略圖 img3.Source = PictureDecoder.DecodeJpeg(picture.GetPreviewImage()); // 獲取預覽圖 } } private void btnShare_Click(object sender, RoutedEventArgs e) { MediaLibrary library = new MediaLibrary(); if (library.Pictures.Count > 0) { Picture picture = library.Pictures.First(); // 獲取媒體文件路徑 string picturePath = picture.GetPath(); // 由文件啟動 app 時會傳遞過來文件的 token 值,用此方法可以根據 token 獲取媒體庫文件的路徑 // string picturePath = library.GetPathFromToken(fileToken); // 根據媒體文件路徑共享之 ShareMediaTask shareMediaTask = new ShareMediaTask(); shareMediaTask.FilePath = picturePath; shareMediaTask.Show(); } } } }
3、演示后台音頻播放的新增功能
MusicMediaLibrary/BackgroundAudio.xaml
<phone:PhoneApplicationPage x:Class="Demo.Media.BackgroundAudio" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" shell:SystemTray.IsVisible="True"> <Grid Background="Transparent"> <StackPanel Orientation="Vertical"> <TextBlock x:Name="lblMsg" TextWrapping="Wrap" Text="BackgroundAudioPlayer 的 PlayStateChanged 事件有了事件參數 PlayStateChangedEventArgs" /> </StackPanel> </Grid> </phone:PhoneApplicationPage>
MusicMediaLibrary/BackgroundAudio.xaml.cs
/* * 演示后台音頻播放的新增功能 * * * 注: * 關於后台音頻播放參見:http://www.cnblogs.com/webabcd/archive/2012/07/23/2604457.html */ using System; using Microsoft.Phone.Controls; using Microsoft.Phone.BackgroundAudio; namespace Demo.Media { public partial class BackgroundAudio : PhoneApplicationPage { public BackgroundAudio() { InitializeComponent(); // 播放狀態發生改變時 BackgroundAudioPlayer.Instance.PlayStateChanged += Instance_PlayStateChanged; } void Instance_PlayStateChanged(object sender, EventArgs e) { /* * 以下是新增功能 */ // 將事件參數參數對象轉換為 PlayStateChangedEventArgs PlayStateChangedEventArgs newEventArgs = (PlayStateChangedEventArgs)e; // BackgroundAudioPlayer 的當前的 PlayerState PlayState currentPlayState = newEventArgs.CurrentPlayState; // BackgroundAudioPlayer 在進入當前 PlayerState 時的前一個 PlayerState(如果沒有此中間狀態則 IntermediatePlayState 等於 CurrentPlayState) PlayState intermediatePlayState = newEventArgs.IntermediatePlayState; } } }
OK
[源碼下載]
