這個Play to,我還是用它原名,因為不知道怎麼翻譯,儘管MSDN上譯為“播放至”,但總感覺有些彆扭。
要說這玩意兒,用來幹嗎,我還真有點……總之,它的大致用途就是同一個網路中,如家庭組,其中有N台windows 8電腦,A計算上現正播放多媒體,這個時候,可以把流媒體發送到B,C,D其他電腦上播放。
於是,我想到什麼場合會用得上它呢?放電影,比如我現在在A機器上播放一部恐怖片,咱們一群哥們兒但子絕對地大,於是,大家對A說:別那麼自私嘛,一個人享受恐怖片不好玩的,去辦公室把投影裝置開啟,在那裡我們坐下來一起看。
於是,B到辦公室,把串連投影裝置的Win8電腦啟動,並啟用一個可以接收PlayTo流的應用,然後A在它的電腦上選擇辦公室的電腦作為目標裝置,這樣,恐怖片就流到辦公室那台電腦播放,大家可以坐在一起,一邊喝酒一邊看恐怖片了。
這麼一來,顯然,完成一個PlayTo,就要具備兩個終端,一個發送,一個接收,需要兩台機器。有點悲哀,我目前只有一台筆記本上裝了Win8系統,PC機是10年前的神機,你就知道不可能裝Win8的,沒辦法,窮人家的孩子,能買得起筆記本,在我們這種農村地方,買一台電腦都需要成本,所以,我一台電腦會用上10多年。
於是,我很努力的嘗試在一台機器上測試,結果測了N多次都是一個結果——失敗!用虛擬機器測也失敗,不知道為什麼,正在研究中。
那麼,你可能會問,那同一台機器上能測嗎?當然,SDK文檔上也有說的,可以的,下文我會介紹如何在本機測試PlayTo。發送端是沒問題,只是寫一個接收端就失敗。
我這個人有一個缺點:不喜歡講理論。所以,還是看執行個體吧。
1、啟動你的VS,建立一個項目,命名為“我的牛B應用”。
2、參考下面XAML,把首頁MainPage.xaml裝修一下,你也可以直接Ctrl + C的,沒關係,我不會起訴你抄襲的。
<Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <Style x:Key="btn_style" TargetType="Button"> <Setter Property="Margin" Value="5,8,15,27"/> <Setter Property="FontFamily" Value="宋體"/> <Setter Property="FontSize" Value="24"/> </Style> <Style x:Key="txb_base" TargetType="TextBlock"> <Setter Property="FontFamily" Value="宋體"/> <Setter Property="FontSize" Value="20"/> <Setter Property="Margin" Value="3,4,3,3"/> <Setter Property="TextWrapping" Value="Wrap"/> </Style> <Style x:Key="txb_fd_name" TargetType="TextBlock" BasedOn="{StaticResource txb_base}"> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Margin" Value="4,4,13,3"/> </Style> </Page.Resources> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition/> </Grid.RowDefinitions> <Button Content="開啟音頻檔案" Click="onOpenFiles" Style="{StaticResource btn_style}"/> <Grid Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Image Grid.Column="0" Margin="8" Stretch="Uniform" x:Name="img" Width="200" Height="200" VerticalAlignment="Top"/> <Grid Grid.Column="1" Margin="5"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="歌曲名:" Style="{StaticResource txb_fd_name}"/> <TextBlock x:Name="tbName" Grid.Column="1" Grid.Row="0" Style="{StaticResource txb_base}"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="歌手:" Style="{StaticResource txb_fd_name}"/> <TextBlock x:Name="tbArtist" Grid.Column="1" Grid.Row="1" Style="{StaticResource txb_base}"/> <TextBlock Grid.Row="2" Grid.Column="0" Text="專輯:" Style="{StaticResource txb_fd_name}"/> <TextBlock x:Name="tbAlbum" Grid.Column="1" Grid.Row="2" Style="{StaticResource txb_base}"/> <TextBlock Grid.Row="3" Grid.Column="0" Text="年份:" Style="{StaticResource txb_fd_name}"/> <TextBlock x:Name="tbYear" Grid.Column="1" Grid.Row="3" Style="{StaticResource txb_base}"/> </Grid> </Grid> <MediaElement x:Name="ME" Opacity="0" Width="0" Height="0" AutoPlay="True"/> </Grid></Page>
看好了,有一個Button的事件要處理,我們在後台代碼中會引用到名叫ME的MediaElement。
3、CS代碼,首先,我們要引用以下命名空間:
using Windows.Media.PlayTo;using Windows.Storage;using Windows.Storage.Pickers;using Windows.Storage.FileProperties;using Windows.Storage.Streams;using Windows.UI.Xaml.Media.Imaging;
然後聲明一個PlayToManager,在頁面類建構函式中new起來。
PlayToManager mgr = null; //PlayTo管理對象 public MainPage() { this.InitializeComponent(); // 得到管理對象執行個體 mgr = PlayToManager.GetForCurrentView(); // 註冊SourceRequested事件,設定PlayTo源 mgr.SourceRequested += mgr_SourceRequested; }
好,重點過了,剩下的代碼我直接Ctrl + V.
async void mgr_SourceRequested(PlayToManager sender, PlayToSourceRequestedEventArgs args) { var df = args.SourceRequest.GetDeferral(); await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { args.SourceRequest.SetSource(this.ME.PlayToSource); }); df.Complete(); } private async void onOpenFiles(object sender, RoutedEventArgs e) { // 開啟一個音頻檔案試試 FileOpenPicker picker = new FileOpenPicker(); picker.FileTypeFilter.Add(".mp3"); picker.FileTypeFilter.Add(".wma"); picker.SuggestedStartLocation = PickerLocationId.MusicLibrary; StorageFile audioFile = await picker.PickSingleFileAsync(); if (audioFile != null) { // 讀出音頻檔案的屬性並顯示 MusicProperties mp = await audioFile.Properties.GetMusicPropertiesAsync(); this.tbName.Text = mp.Title; this.tbArtist.Text = mp.Artist; this.tbAlbum.Text = mp.Album; this.tbYear.Text = mp.Year.ToString() ; // 取得檔案圖示 var icon = await audioFile.GetThumbnailAsync(ThumbnailMode.MusicView, 200, ThumbnailOptions.ResizeThumbnail); BitmapImage bmp = new BitmapImage(); bmp.SetSource(icon); this.img.Source = bmp; // 開始播放 this.ME.SetSource(await audioFile.OpenAsync(FileAccessMode.Read), audioFile.ContentType); } }
注意,在處理SourceRequested事件時,要先擷取一個PlayToSourceDeferral,然後再寫代碼,在最後調用Complete方法。因為是非同步,如果你不這樣做,它一下子就過去了,你的代碼可能來不及執行。
好了,現在我們來準備測試,先要做一些手腳,不然不好測。
1、開啟Windows Media Player,知道在哪吧,不用我說了吧,如果找不到,就在應用搜尋欄裡面搜。
2、單擊“媒體流”的下拉式箭頭,選擇“允許遠端控制我的播放器”。
3、在彈出的視窗中點擊“允許在網路中運行遠端控制”。
4、開啟控制台,找到“裝置和印表機”,單擊“添加裝置”按鈕。
5、如果不出意外,會看到在搜尋的裝置中有原生Media Player,選中它,並單擊“下一步”。
6、正在安裝
成功後,會在多媒體裝置中看到它了。
注意,讓Media Player繼續開啟,不要關了,不然等一下就測試失敗,你一關閉,這個裝置就無效了。
現在,回到VS,果斷運行應用程式,選擇一個音頻檔案,開始播放。頁面上顯示歌曲資訊。
然後,把滑鼠移到右上方或右下角,從測側邊欄中選擇【裝置】。
在隨後開啟的窗格中,點擊我們剛才添加的多媒體裝置。
這時候,如果一切正常,你會發現,音頻已經跑到Windows Media Player中播放了。你可以在WMP裡面控制音頻暫停或停止。