Naive Media Player

自己做着玩的一个UWP播放器,不喜勿喷:)


项目地址:GitHub

先说说我的思路:

我是想这个简单的不能再简单的播放器起码得有一个播放历史的功能,所以,我参照了各种新闻类的App那种左右分两栏的布局方式。
这里写图片描述

本来的设想是左边的ListView是播放历史,可以点击直接播放,然而,发现我所能找到的所有的例子都是使用file picker的,没有一个是直接同过URI来打开媒体文件。查了很久才发现UWP的安全措施限制了应用对任意位置的访问权限。见File Access Permissions
但是还是有办法的,毕竟还是有很多的应用,比如Media Player S Pro,仍然可以读取任意位置的媒体文件。网上大概有两种方法,一种是野路子,包含一个win32程序,通过进程通信来用win32程序访问文件。另外一种是官方给出的,使用manifest文件来声明(App Capability Declarations。不过由于时间的原因我就没有进一步研究,这一点留到以后来解决。

于是就到了现在的这个样子。点击坐左上的+号按钮,调用FilePicker选取一个媒体文件(mp3或mp4),然后会在右边自动播放(当然全屏,快进,音量等等功能都有)。


下面是学习总结:

技术问题1:音频文件播放时没有图像

想到大部分播放器比如windows media player都会在播放音频时出现一个默认的音频图标,所以我抱着试试看的心态去找,一开始搜索Image属性无果,后来在看微软的MediaElement类的文档的时候看到了PosterSource属性(MediaElement),里面说

You can use the PosterSource property to provide your MediaElement with a
 visual representation before the media is loaded.

于是这就解决了我的问题。

技术问题2:后台无法播放

当应用点击最小化按钮后音频和视频的播放将会停止,于是我去搜索了一下UWP后台播放,发现过程实际上比较麻烦。正如官方文档(这里)所说,当应用从前台进入后台时,会释放内存资源,并触发应用程序状态的改变,所以,要让媒体文件可以后台播放,首先需要在manifest文件中声明后台播放媒体的功能,然后还要处理进入后台( EnteredBackground )和退出后台(LeavingBackground)的事件

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;

    this.EnteredBackground += App_EnteredBackground;
    this.LeavingBackground += App_LeavingBackground;
}

还由于后台能使用的内存资源非常有限,编程中还应该释放不必要的内存资源。
我按照文档中所说尝试了一下,但是却没有成功,主要是文档中对于事件的具体的处理逻辑没有说清楚,可能是因为我自己的知识水平还不够,有些东西还不知道,所以并没有成功。但是这个问题还是让我学到了挺多东西,比如说进一步理解了进程的各个状态,后台前台的区别以及内存分配的问题。
还是应该化更多的时间去学习,只是由于目前时间紧张所以还没能实现。

技术问题3:ListView无法滚动

非常奇怪的一个问题,但是其实我以前遇到过,但是一直还没有很好的解决办法。
当播放记录很多时,ListView会显示不全而需要滚动查看,按照文档所说ListView,是默认带有滚动的功能的,但是我的应用无论如何也无法滚动。查了很长很长很长时间,没有人有这个问题,所有人的关注点都是比如怎么横向滚动,怎么加滚动特效,怎么下拉刷新。但是就是没见过有人是无法纵向滚动的。

尝试设置了一下ListView的高度,发现问题竟然解决了。估计是如果我不设高度,item就会一直撑大ListView的高度,但是并不管是否已经超出了窗口的界限,所以ListView总是不能滚动。解决这个问题的一个办法是:监控窗口大小,实时地将ListView的高度设为对应窗口大小的高度。
只是我觉得,这一点从控件本身的设计上来说,明明可以避免的。

技术问题4:MediaElement无法打开文件

一开始,使用FilePicker已经获取了文件的实例,并拿到了媒体文件路径,但是,我无论用什么方法,都没有办法通过文件路径来播放。MediaElement控件确实有Source这个属性,但是只能设置应用内文件夹中的媒体文件,如果设置绝对路径就不起作用。
于是我去查官方文档,里面给出的例子是直接用FilePicker返回的对象打开文件流进行播放

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await SetLocalMedia();
}

async private System.Threading.Tasks.Task SetLocalMedia()
{
    var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

    openPicker.FileTypeFilter.Add(".wmv");
    openPicker.FileTypeFilter.Add(".mp4");
    openPicker.FileTypeFilter.Add(".wma");
    openPicker.FileTypeFilter.Add(".mp3");

    var file = await openPicker.PickSingleFileAsync();

    // mediaPlayer is a MediaElement defined in XAML
    if (file != null)
    {
        var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
        mediaPlayer.SetSource(stream, file.ContentType);

        mediaPlayer.Play();
    }
}

于是问题暂时解决了,但是后面我还是需要用绝对路径打开文件,(这一点在一开始我说过了)。尽管最终的解决方案并不完美,但是我加深了对App Container的理解,更深入地了解了UWP应用程序在Windows中的地位和权限,所以还是收获良多。
这里写图片描述


其实还有很多问题,比如我在外层套NavigationView的时候导航栏被遮挡了的问题,比如说数据绑定时如何对控件模板进行绑定,等等,但这些其实都和这次作业的主题(MediaElement)不太相关,所以我就不详述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值