可視化程序設計基礎(三)——一個簡單的播放器(並不)

本次的做業是製做一個簡單的播放器,功能僅限於播放視頻和音頻,雖然說是簡單的播放器,但其中仍是有不少細節須要注意的。git

代碼發佈在:https://github.com/cui-jia-hua/mediaplayergithub


問題一:佈局windows

  原本這個問題不該該是一個問題了,以前老師講過的StackpanelGrid等對於佈局一個播放器來講綽綽有餘,但上次上課老師提到的NavigationView令我十分感興趣,這是一個uwp應用程序中隨處可見的一種佈局,節省了開發者不少的時間。api

  因此我就着手於創建這個NavigationView了,首先我看了一下XAML Controls Gallery,然而其中關於NavigationView的內容少的可憐,我在複製代碼進工程時還報出了不少錯誤,其中一項就是版本問題,這個NavigationView太新了,以致於老版本不支持,因此我又新建了一個項目將最低版本控制在秋季創意者,而且刪除了例子中不少有關樣式的內容,最後總算是在程序中看到了它。瀏覽器

參考:XAML Controls Gallery —— NavigationView網絡

  僅僅實現界面並不能幹任何事情,這個界面的核心就在於他能夠在不一樣頁面間來回切換,那麼切換這個功能如何實現呢?我在網絡上搜索的時候發現相關的內容較少,只在CSDN上找到了兩個講NavigationView切換頁面的博客。異步

參考:https://blog.csdn.net/xiahn1a/article/details/78935260async

參考:https://blog.csdn.net/LoHiauFung/article/details/61414592ide

  其中一篇博客的代碼中寫道佈局

private void nvAll_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
    //先判斷是否選中了setting
    if (args.IsSettingsInvoked)
    {
        contentFrame.Navigate(typeof(SettingsPage));
    }
    else
    {
        //選中項的內容
        switch (args.InvokedItem)
        {
            case "Home":
                ContentFrame.Navigate(typeof(HomePage));
                break;
        }
    }
}

   我在實驗的過程當中我發現我並不知道args.InvokedItem這個屬性的具體值是什麼,目前看來是字符串但我不清楚是哪一個,最後我在程序中輸出結果纔看到這個屬性其實就是界面上左邊不一樣標籤的文本,這也提醒了我不少時候網絡上的代碼不能拿過來直接使用,須要本身看懂弄懂後纔不會出錯誤。最終我寫出的代碼是這樣的:

private void NV_OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
        {
            //title.Text = args.InvokedItem.ToString();
            switch (args.InvokedItem)
            {
                case "picture":
                    contentFrame.Navigate(typeof(pic));
                    break;
                case "music":
                    contentFrame.Navigate(typeof(music));
                    break;
                case "video":
                    contentFrame.Navigate(typeof(video));
                    break;
            }
        }

 


問題二:打開文件

  以前的學習中我沒有用到文件的相關操做,因此我首先去看了一下官方文檔。發現了這樣一個類:FileOpenPicker,看到這個類名我就知道我找到了想要的。將代碼複製到工程中時還遇到了一點小小的問題,例子中的方法是異步的,因此須要進行一些細微的調整。

參考:https://docs.microsoft.com/en-us/uwp/api/Windows.Storage.Pickers.FileOpenPicker#code-snippet-1

  在選取文件後,須要對文件進行一些操做來使其變爲媒體源,這一步是經過調用 MediaSource.CreateFromStorageFile 初始化新的 MediaObject。而後經過調用 SetPlaybackSource 方法將媒體源設置爲 MediaElement 的播放源。例子中的代碼是這樣的:

if (file != null)
{
    mediaSource = MediaSource.CreateFromStorageFile(file);
    mediaElement.SetPlaybackSource(mediaSource);
}

  這裏我就不得不要吐槽一下微軟的這個參考樣例了,以前口口聲聲說結果在代碼端用了個mediaElement,迷惑性賊強,致使我實踐的過程當中不得不又從新看了其餘文檔。以下是一個專門講mediaplayer的文檔,感受寫的比以前的要清晰不少。折騰來折騰去,我總算是明白了,在使用MediaSource打開文件後就能夠經過已經初始化的MediaPlayer來播放了,不須要MediaElement,我猜想MediaElement是另外一種打開多媒體文件的方式,不過文檔把它們混着使用確實使人難以理解。

參考:https://docs.microsoft.com/zh-cn/windows/uwp/audio-video-camera/play-audio-and-video-with-mediaplayer

個人代碼:

 private async void ButtonBase_OnClickAsync(object sender, RoutedEventArgs e)
        {
            FileOpenPicker openPicker = new FileOpenPicker
            {
                ViewMode = PickerViewMode.Thumbnail,
                SuggestedStartLocation = PickerLocationId.PicturesLibrary
            };
            openPicker.FileTypeFilter.Add(".mp3");
            openPicker.FileTypeFilter.Add(".mp4");

            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                path.Text = file.Path.ToString();
                _mediaSource = MediaSource.CreateFromStorageFile(file);

                
                //簡單訪問
                _mediaPlayer = new MediaPlayer();
                _mediaPlayer.Source = _mediaSource;
                _mediaPlayer.Play();
                MediaPlayerElement.SetMediaPlayer(_mediaPlayer);

                //高級訪問
                /*var mediaPlaybackItem = new MediaPlaybackItem(_mediaSource);

                _mediaPlayer.Source = mediaPlaybackItem;*/
            }
            else
            {
                path.Text = "no file";
            }
        }

問題三:播放

  在界面中放置好MediaPlayerElement後,須要把它和MediaPlayer鏈接起來,參照上述文檔咱們能夠看到能夠經過調用 SetMediaPlayer,設置綁定元素的 MediaPlayer 實例。代碼很簡單,這裏就不放了,另外,使用這種方式能夠直接播放音頻和視頻,不用擔憂音頻沒法播放的問題。最後我利用StorageFile類中的FileType方法將用戶選擇的文件類型顯示在界面上。

  另外還有一個小細節,MediaPlayerElement中有一個屬性叫AreTransportControlsEnabled,這個在我參考的博客中是被設置爲false的,然而我運行測試時發現視頻只能播放,沒有咱們播放器中那些暫停,控制音量等按鈕,我猜想是由於這個屬性,將其設置爲true後就和正常播放器同樣了。

程序截圖:

但我還有一個不太明白的地方,編寫完成後在測試時我發現個人界面有的時候會顯示不全,當我拉伸界面時會出現這種狀況:

右半部超出原有邊界的會看不到,但右上角關閉等按鈕依然能夠按,很奇怪,不清楚是個人什麼配製出了問題。

已解決:重啓大法好。。。


總結:

  在編寫這個簡單的播放器的過程當中,我學到了不少東西,認識到了什麼都沒有官方文檔好用,文檔幫助了我不少。個人下一步計劃是加入圖片功能,而且將音樂和視頻分隔開,作一個全能多媒體瀏覽器。

相關文章
相關標籤/搜索