您的位置:首页 > 移动开发 > Android开发

Android多媒体编程——MediaPlayer播放音乐

2015-10-29 16:02 330 查看

Android多媒体——使用MediaPlayer播放声音

API

在我们的项目中经常会遇到播放声音的功能,在Android中系统的framework已经提供了调用播放声音的API——MediaPlayer 

在Android Developers中已经给出了相关的文档:

One of the most important components of the media framework is the 
MediaPlayer
 class.
An object of this class can fetch, decode, and play both audio and video with minimal setup. It supports several different media sources such as:

Local resources
Internal URIs, such as one you might obtain from a Content Resolver
External URLs (streaming)

android中的MediaPlayer可以播放多种路径的声音文件 包括 本地资源声音文件,网络声音文件,内部的系统声音

播放本地文件:

使用时首先需要创建Mediaplayer 

创建方式一:

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
mediaPlayer.start(); // no need to call prepare(); create() does that for you


创建方式二:

MediaPlayer player= new MediaPlayer();
//重置播放器
player.reset();
//设置资源文件
player.setDataSource("sdcard/zxmzf.mp3");
//准备就绪
player.prepare();
//播放
player.start();


这里采用create创建,文档中说明这样创建是不需要调用prepare等api方法了,create()方法中已经完成了这些
播放内部URI文件:

Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();


播放网络文件:

String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();


在这里官方的文档给出了播放网络文件的条件:

如果需要播放网络上的文件,必须保证该资源可以下载

线程安全问题:
官方api指出,在调用prepare()方法的时候,会进行抓取和解码等操作,所以属于耗时任务,这样有可能带来系统的ANR(应用程序未响应) 所以我们不应该执行耗时的任务在UI线程。给出了需要播放时可以使用媒体播放器框架,这个框架提供了一个方便的方法——使用prepareAsync()异步方法。这个方法被调用后媒体开始在后台准备播放所需要的解码等任务,并且会立即返回。当准备完毕后会回调MediaPlayer.OnPreparedListener方法,所以我们可以为媒体播放器设置监听来监听准备的状态
setOnpreparedListener()
管理播放器的状态:
MediaPlayer是有特定的状态的,如果错误的执行某状态下的操作,可能会抛出异常,应当是创建新的媒体播放器时,这个媒体播放器是处于闲置状态的,需要设置setDataSource()来进行初始化,初始化完成后使用prepare()/prepareAsync()方法来使MediaPlayer进入准备状态,当准备已经完成后,Media会进入就绪状态,这时可以调用start()方法来播放。可以使用pause()来暂停播放,也可以使用stop()停止播放。当你调用stop()方法时会停止播放。但是这时候停止后不能直接重新开始,你需要再次进行reset()
重新准备 才能重新播放
资源的释放:
媒体播放器资源是占用系统内存的,由于是底层硬件操作,不会主动地释放资源,所以我们需要收懂的释放资源,当不需要使用的时候,我们应该调用relase()方法释放资源,当使用MediaPlayer在一个系统的Service中时,我们需要释放播放器和服务

mediaPlayer.release();
mediaPlayer = null;


服务中使用Media

,就像一个Service,所有工作在一个Service是在一个线程中完成由违约事实,如果你正在运行一个activity从相同的应用程序和service,他们使用相同的线程(主线程)默认情况下。因此,服务需要迅速处理传入的意图,从不执行冗长的计算当回应他们。如果预计任何繁重的工作或阻塞调用,你必须做这些任务异步:从另一个线程实现你自己,或者使用框架的许多设施异步处理。

文档中给出了使用播放器在服务中的用法,强调就绪应当调用prepareAsync()而不是prepare(),实现MediaPlayer.OnPreparedListener接口

public class MyService extends Service implements MediaPlayer.OnPreparedListener {
private static final String ACTION_PLAY = "com.example.action.PLAY";
MediaPlayer mMediaPlayer = null;
 
public int onStartCommand(Intent intent, int flags, int startId) {
...
if (intent.getAction().equals(ACTION_PLAY)) {
mMediaPlayer = ... // initialize it here
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync(); // prepare async to not block main thread
}
}
 
/** Called when MediaPlayer is ready */
public void onPrepared(MediaPlayer player) {
player.start();
}
}


API中还介绍了使用唤醒锁保证媒体播放不受到系统睡眠的影响,作为前台服务运行。详情请查阅Develop文档

附上MediaPlayer的状态图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android知识点