本次的做业是制做一个简单的播放器,功能仅限于播放视频和音频,虽然说是简单的播放器,但其中仍是有不少细节须要注意的。git
代码发布在:https://github.com/cui-jia-hua/mediaplayergithub
问题一:布局windows
原本这个问题不该该是一个问题了,以前老师讲过的Stackpanel和Grid等对于布局一个播放器来讲绰绰有余,但上次上课老师提到的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是另外一种打开多媒体文件的方式,不过文档把它们混着使用确实使人难以理解。
个人代码:
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后就和正常播放器同样了。
程序截图:
但我还有一个不太明白的地方,编写完成后在测试时我发现个人界面有的时候会显示不全,当我拉伸界面时会出现这种状况:
右半部超出原有边界的会看不到,但右上角关闭等按钮依然能够按,很奇怪,不清楚是个人什么配制出了问题。
已解决:重启大法好。。。
总结:
在编写这个简单的播放器的过程当中,我学到了不少东西,认识到了什么都没有官方文档好用,文档帮助了我不少。个人下一步计划是加入图片功能,而且将音乐和视频分隔开,作一个全能多媒体浏览器。