Media Playback媒体播放

由于安卓多媒体框架支持多种常见类型的多媒体文件的播放,所以开发者可以很容易的集成视频、音频和图像到自己的应用中。我们可以使用Mediaplayer应用程序编程接口播放存储在本地的视频或者音频文件,也可以播放通过网络连接下载的数据流。

1:基础

安卓框架中使用以下两个类播放音频和视频:

MediaPlayer:这个类是播放声音和视频的主要API

AudioMannager:这个类管理音频来源,并且将音频输出到设备上。

2:显示声明

在开始使用MediaPlayer开发你的应用程序之前,确保具备如下条件:

网络许可和后锁许可

3:使用MediaPlayer

多媒体框架的最重要的一个组件之一就是MediaPlayer类,这个类的实例可以以最少的步骤获取、解码和播放音视频文件。它支持多种多媒体数据来源:

本地资源、URIs和URLs

4:异步准备

MediaPlayer的使用原则简单,但是也有一些地方需要注意。例如:prepare()这个函数需要执行很长的时间,因为它需要抓取和解码多媒体数据。所以作为一个执行需花费长时间的方法,我们不应该在应用的UI线程去调用。否则将使UI挂起很长时间直到这个方法返回,这是一个很糟糕的用户体验,而且可能造成ANR错误。在UI线程中任何一个超过十分之一秒的响应,将造成明显的卡顿,会给用户一种你的程序很慢的印象。为了避免挂起你的UI线程,可以产生另一个线程准备MediaPlayer,在准备完成后通知主线程。你可以自己写这个线程的逻辑,但是更常用的方法是使用框架提供的prepareAsync()方法。这个方法在后台准备Media,并且完成后立即返回。

5:状态管理

当你编写代码的时候需要留意MediaPlayer的内部状态,因为只有在特定的状态下相应的操作才会有效 。如果在错误状态下操作,系统将抛出异常或者造成其他非预期行为。

 6:释放MediaPlayer

一个MediaPlayer可能会消耗大量的系统资源。所以,我们应该采取额外的预防措施来保证我们并没有在超出所需时间不释放一个MediaPlayer实例。 应该通过调用release()以确保所分配的系统资源被正确释放。

7:使用MediaPlayer服务器

当你的应用不在屏幕上时,如果想要后台播放媒体文件,需要开启一个Service去控制MediaPlayer实例。

8:异步运行

首先,在一个活动中,所有的工作都是在一个单独的线程中完成的,事实上,如果你在同一个应用程序中运行某个活动和服务,他们会使用相同的线程(“主线程”)。因此,服务需要快速地处理输入意图,而不是执行冗长的计算后回应他们。如果有任何繁重的工作或阻塞调用,你必须以异步方式来完成这些任务:或者从另一个线程中实现自己,或者使用该框架的许多设施进行异步处理。

9:处理异步错误

在异步操作时,错误通常由异常或错误代码通知出来,当使用异步资源时,应该确保你的程序可以被适当的通知错误信息。在使用MediaPlayer时,我们可以通过在MediaPlayer实例中实现 MediaPlayer.OnErrorListener并且设置好它来完成这一点。

10:使用唤醒锁

当应用程序在后台播放媒体文件时,虽然你的服务在运行但是设备可能会进入休眠。因为安卓系统通过设备休眠节省电量。系统试图关闭任何不必要的功能包括CPU和Wifi硬件。然而如果你的服务是播放音乐,你想要阻止系统打扰你的播放。

为了确保你的服务在这些条件下继续运行,您必须使用“唤醒锁”。唤醒锁是一种向系统发出信号的方法,告诉系统你的应用程序正在使用某些功能,这些功能应该保持可用。应该在需要时才使用唤醒锁,因为它很费电。

为了确保当运行你的MediaPlayer时持续运行CPU,可以在初始化你的MediaPlayer时调用setWakeMode()函数。这样的话,MediaPlayer会持有特定的锁直到暂停或者停止时才释放。

但是如果你需要传递媒体文件通过网站或者Wifi的话,你还需要持有WifiLock。所以当你开始使用远程URL初始化你的MediaPlayer时,你需要创建和获取WiFi-lock。

11:作为前台服务运行

相对于后台服务,前台服务对用户体验的影响很大,不能随意打断。当运行在前台,服务也必须提供一个状态栏通知。

为了运行一个前台服务,我们可以创建一个Notification作为状态条,可以调用startForeground()函数。不需要运行前台服务时调用stopForeground()。

12:Handling audio focus

安卓是一个多任务环境系统。只有一个音频输出设备但是可能会有多个服务在竞争着使用。在安卓2.2之前是没有一个内置机制去解决这个问题的,这可能会导致用户体验不好。在安卓2.2之后,平台提供了一种方式让应用程序可以协商着使用音频输出硬件设备。这个协商办法就是audio focus。

当应用程序需要输出音乐或者通知这种音频的时候,首先要请求audio focus。程序持有focus的话可以自由使用音频输出设备,但是它应该监听focus的变化,如果失去了focus那么它应该退出音频输出或者将声音降低为0.

可以通过调用 AudioManager的requestAudioFocus()函数请求audio focus。

13:执行清理

如前所述,一个媒体播放器对象可以消耗大量的系统资源,所以在不需要的时候应该记得销毁它,而不是依赖于垃圾收集器去回收,因为垃圾收集器只会对需要的内存和稀缺资源敏感,等待垃圾收集器回收可能要花费一些时间。我们需要重写onDestroy()函数来完成MediaPlayer的释放。

程序除了在关闭的时候释放MediaPlayer也应该寻找其他机会释放MediaPlayer。具体什么时候该释放,根据情况而定。

14:Handling the AUDIO_BECOMING_NOISY Intent

很多精心编写的应用程序当突发事件发生时会自动停止播放音频以避免音频变成噪声。(例如听音乐时耳机不小心断开了,这个时候音频就不应该通过扬声器播放出来)

可以通过Handling the AUDIO_BECOMING_NOISY Intent实现这个功能,可以注册一个接收器。

15:用内容解析器检索Media

另一个你可能会使用的MediaPlayer的特性是获取用户在设备上的音乐。可以通过查询ContentResolver.

http://wear.techbrood.com/guide/topics/media/mediaplayer.html#viacontentresolver



你可能感兴趣的:(android,mediaplayer)