【跟Z学开发】1.3 (续)做一个更简陋的播放器

zcxsythenew UID.911687
2017-07-14 发表

本帖最后由 zcxsythenew 于 2017-7-24 13:50 编辑

专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

语言:C#
如果想学习XAML,可以关注后续课程。

本节包含:
后台任务
后台媒体播放(双进程)

首先,我们要给自己点赞,因为我们已经坚持到了第三节课。我们可以回去看一看预告帖和第一、二节课的投票人数,明显呈下降趋势。
如果你感到疲惫,请鼓励自己。都坚持到第三节课了,就不要怀疑自己的能力。

首先,我们比对一下我们写过的代码和一些其它的注意事项。

1. App.xaml.cs

***附件停止解析***
(上节课内容更正:在第二个if中,条件应该补充加上:“ && status != BackgroundAccessStatus.Unspecified”)

2. 后台任务

***附件停止解析***

3. Package.appxmanifest(声明)

***附件停止解析***

4. 引用

***附件停止解析***

如果比对结果无误,那么我们就继续这节课的学习。

[backcolor=red]请通过电脑网页版来浏览此教程。[/backcolor][page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

上一节课,我在教程里面埋了两个任务。你完成了吗?
现在,对每一个任务,我给出两种解决方案,请君自选其一或者用你自己认为更好的方法。
(有时候,代码看起来是否舒服也是评判解决方案好不好的因素之一。)

任务1 仅在“启动”的时候重新注册后台任务。

方案1.1 全局变量

***附件停止解析***
(图中“if(firstAction)”的大括号一直括到原代码的末尾。)

方案1.2 代码下移

***附件停止解析***

任务2 将if改写为switch。

方案2.1

***附件停止解析***

方案2.2

***附件停止解析***[page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

经过上节课的学习和这节课开始的比对,我们的后台任务应该都已经“万事俱备,只欠东风”了。这节课,我们来学一学这个“东风”。

“东风”就是这个:[mw_shl_code=csharp,true]builder.SetTrigger(new ToastNotificationActionTrigger());[/mw_shl_code]Trigger有很多种。首先,我们来看一看几种常见的Trigger。

1. SystemTrigger
此“东风”表示当系统发生某事时启动这个后台任务。
注意:需要在“声明”中勾选“系统事件”。“系统事件”不能和“音频”一同使用。

用法:

***附件停止解析***
图中,false表示每次发生此事件都执行后台任务,true表示只执行一次。

2. TimeTrigger和MaintenanceTrigger
此“东风”表示定时启动这个后台任务。MaintenanceTrigger与TimeTrigger的不同之处是MaintenanceTrigger主要用于维护任务,因此系统对其限制可能比较严格。
注意:需要在“声明”中勾选“计时器”。“计时器”不能和“音频”一同使用。

用法:

***附件停止解析***

***附件停止解析***

图中,true表示在指定分钟数后执行一次,false表示以此为时间间隔执行后台任务。

3. ApplicationTrigger
使用了ApplicationTrigger之后,可以在前台进程有需要的时候立即执行后台任务。
注意:需要在“声明”中勾选“常规”。“常规”不能和“音频”一同使用。

用法1:

***附件停止解析***
(执行RequestAsync之后,后台任务将立即启动。)

用法2(跟踪后台任务启动情况):

***附件停止解析***

ApplicationTrigger 还可以向后台传递参数。此处省略。

4. ToastNotificationActionTrigger
通过交互式通知启动后台任务。
注意:一般来讲,需要在“声明”中勾选“常规”,但在现有版本中,没有“常规”也能启动后台任务。那么,我们就可以勾选“音频”,可以通过交互式通知来打开音频。这其实是一个不标准的用法,但是判断一个程序“对不对”,唯一的标准是能否运行,而我们足够幸运遇到了这个Bug。
用法大家都很清楚了,我们上节课就是以ToastNotificationActionTrigger做的例子。

以上四种就是比较常见的Trigger。不过,对于双进程的后台媒体播放而言,还有一种方法来启动后台任务:[mw_shl_code=csharp,true]MediaPlayer player = BackgroundMediaPlayer.Current;[/mw_shl_code]有了这一行代码,就可以立即启动声明为“音频”的后台任务,而无须注册(但仍然需要声明和引用)。

当然,我们学了那么久的注册,不会白费。我们在后面会讲到注册和不注册后台任务的适用范围。[page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

我们要首先了解一下电脑和手机上后台媒体播放的不同。在电脑上,后台任务和前台“共享生命周期”,即:前台任务关闭,后台任务将一同关闭。上节课讲到,我们希望把多余的空白窗口“干掉”,但是“干掉”前台窗口的时候,后台播放器也关掉了,不符合要求。但是,这里我们可以抖一个机灵,使用交互式通知单独启动后台任务。那么我们就会用到ToastNotificationActionTrigger。这部分内容在下节课会讲到。

在手机上,后台任务和前台相对独立。关闭前台窗口并不会关闭后台任务,但前提是后台音频正在播放。在手机上,BackgroundMediaPlayer.Current再合适不过了。不过,我们需要知道前台窗口在什么时候关闭比较合适,应该在媒体开始播放的时候。

下面先以手机为例。

第1步 把“注册后台任务”的相关代码全部注释掉。下节课,我们再用到它。

***附件停止解析***
(心碎的声音)

第2步 在原来的代码的下一行输入[mw_shl_code=csharp,true]MediaPlayer player = BackgroundMediaPlayer.Current;[/mw_shl_code]第3步 输入[mw_shl_code=csharp,true]BackgroundMediaPlayer.MessageReceivedFromBackground+=[/mw_shl_code]按Tab。

***附件停止解析***

我们滚动到下方找到上图显示的代码。这里是我们第2次遇到事件处理。

这一段代码会在前台任务收到后台任务的消息时执行。我们的这个播放器非常简陋,也不打算传递更多的信息。我们计划后台任务加载完音频之后向前台传递一个消息,前台收到信息之后,不用管这个信息是什么,直接关闭就可以了。这样,我们的“更简陋的播放器”(手机版)就完工了。

我们把上面的代码改为[mw_shl_code=csharp,true]App.Current.Exit();
//throw new NotImplementedException();[/mw_shl_code]我们的前台代码基本完成。当然,你可以在“BackgroundMediaPlayer.MessageReceivedFromBackground”的下一行插入[mw_shl_code=csharp,true]return;[/mw_shl_code]因为我们暂时不需要用到MainPage,自然也不需要导航到那里去,下方的代码我们暂时不需要。

最后我们再处理一下后台代码。

在[mw_shl_code=csharp,true]MediaPlayer player = BackgroundMediaPlayer.Current;[/mw_shl_code]下一行,插入[mw_shl_code=csharp,true]player.PlaybackSession.PlaybackStateChanged+=[/mw_shl_code]然后按Tab。

这里是我们第3次遇到事件处理。我们仍然把throw...注释掉,然后插入:[mw_shl_code=csharp,true]if (sender.PlaybackState == MediaPlaybackState.Playing)//表示媒体正在播放中。MediaPlaybackState的其它情况(枚举值)可以在Visual Studio查看。
{
BackgroundMediaPlayer.SendMessageToForeground(new ValueSet());//ValueSet可包含实际内容,但在这里我们传递的是空信息。
}[/mw_shl_code]我们可以在手机上调试这个应用,测试一下效果。[page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

如果你真的一步一步做到这里,那么恭喜你,你已经把UWP的流氓应用做出来了。快到智机网发帖吧,标题【震惊!WP竟然有退不出的流氓应用!】

为什么?我们做的这个应用,已经把前台关闭了,只剩下后台音频任务,所以没有后台卡片。而BackgroundMediaPlayer并不会自动在音量控制里面放控制按钮,所以就无法控制了。

***附件停止解析***

流氓和不流氓,其实和开发者自己的责任心有关,而与用什么平台无关。当然,我相信上这个课的都是良好公民,那么我们一起来修复这个Bug吧。我们打开后台代码。下一页,我会给出两种解决方案。[page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

方案1 自动控制

在[mw_shl_code=csharp,true]player.Play();[/mw_shl_code]下一行,插入:[mw_shl_code=csharp,true]player.CommandManager.IsEnabled = true;[/mw_shl_code]CommandManager可以自动连接SystemMediaTransportControls,并且自动提供暂停、播放、下一首等功能。

提问:我们现在做的这个应用是播放央广音乐之声直播电台的应用,那么“暂停”的意义不大(暂停时间过长,将导致播放中断)。如果要将“暂停”改写为“停止”,应该怎么办呢?

提示:
1. 事件处理:player.CommandManager.PauseReceived
2. “停止”的代码:[mw_shl_code=csharp,true]BackgroundMediaPlayer.Shutdown();
def.Complete();
args.Handled = true;
//Handled表示事件已经处理完成,在本例中,表示“暂停”按钮已经处理好了,我们不需要CommandManager自动提供的“暂停”功能。
//这就是我上节课提及的“IsHandled”,我上节课笔误了。
//args还包含GetDeferral函数,但在这里,我们没有用到await,不需要请求延时。(请求了延时也可以。)[/mw_shl_code]方案2 手动控制

在[mw_shl_code=csharp,true]player.Play();[/mw_shl_code]的下一行,插入:[mw_shl_code=csharp,true]SystemMediaTransportControls controls = SystemMediaTransportControls.GetForCurrentView();
//也可以用SystemMediaTransportControls controls = player.SystemMediaTransportControls;代替。
controls.IsEnabled = true;[/mw_shl_code]这几行代码将允许音量控制显示音频播放状态,但是必须手动允许暂停、播放等按钮开启。我们要打开“暂停”按钮的功能。插入以下代码:[mw_shl_code=csharp,true]controls.IsPauseEnabled = true;[/mw_shl_code]然后我们要指定音量控制的状态,让它显示“暂停”而不是“播放”。[mw_shl_code=csharp,true]controls.PlaybackStatus = MediaPlaybackStatus.Playing;[/mw_shl_code]“手动控制”的方案中,我们必须手动指定按下按钮时要进行的操作。

提问:要在按下“暂停”按钮时“停止”播放,应该怎么办呢?

提示:
1. 事件处理:controls.ButtonPressed
2. 判断点击的是不是“暂停”按钮:
if (args.Button == SystemMediaTransportControlsButton.[...])
请补充[...]代表的部分。
3. “停止”的代码:[mw_shl_code=csharp,true]BackgroundMediaPlayer.Shutdown();
def.Complete();[/mw_shl_code][page]专题一 开发一个媒体播放应用
课题3 (续)做一个更简陋的播放器

非常感谢依然在这里的各位。非常认真的讲,我们做的这个应用,只要把Logo改一改,就可以厚着脸皮拿到商店去发布了,卖点是“简单”“节省流量”等等。

当然,它还非常简单,不能做一些复杂的事情。下节课,我们将学习交互式通知,并接触到我们的课程里还未接触到的语言XML。顺便,我们再将这节课没有讲的电脑版简陋播放器补完。

我们将要完成一项“壮举”:做到网易云音乐都不敢做不能做的事情。(误)(当然我们肯定没有它厉害)

***附件停止解析***
(图:右下角有点难,仅保留音量控制还是可以做到的)

下节课:2017年7月17日19:00

苍天啊!为什么论坛给我增加了第三项投票!

[backcolor=red]请投票选择第一个“打卡签到”,谢谢。[/backcolor]

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
597****372 UID.2861473
2017-07-14 回复

表示支持lz,好人一生平安。顺便问一下,1.1-1.3需要C#和XML基础就可以了?

zcxsythenew UID.911687
2017-07-14 回复

Quote597928372 发表于 2017-7-14 19:18
表示支持lz,好人一生平安。顺便问一下,1.1-1.3需要C#和XML基础就可以了?


是的。

小张qq UID.1257492
2017-07-14 使用 Lumia 640 XL 回复

支持下

vbfool UID.352791
2017-07-15 回复

我记得单独的后台播音频的话,不需要背景媒体播放权限了。

zcxsythenew UID.911687
2017-07-15 回复

Quotevbfool 发表于 2017-7-15 01:09
我记得单独的后台播音频的话,不需要背景媒体播放权限了。


我也发现了。后来一想,这个1.1遗留下来的问题,留到1.4解决好了。1.3遗留的问题是OnLaunched里面有一个多余的async标签,也留到1.4解决。放一个小标题“注意细节”。

wa****hu UID.224919
2017-07-15 使用 Lumia 950 XL 回复

看不懂,纯支持

斌****啊 UID.866382
2017-07-16 回复

我想问一下开发uwp应用需要什么配置的电脑最好是笔记本的。

vbfool UID.352791
2017-07-16 回复

Quote***链接停止解析***
我想问一下开发uwp应用需要什么配置的电脑最好是笔记本的。


内存大一点(8G就差不多了)
CPU台式机的话无所谓了,G3都行,笔记本稍微考虑好点的CPU吧。
然后就是屏幕尽量还是大一些最好。

这个价位的台式机,便宜配的话估计4000不到就行,笔记本的话5000多块的基本也够了。

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报