Android媒体播放:MediaPlayer
来源:互联网 发布:大数据精准营销的案例 编辑:程序博客网 时间:2024/04/30 20:21
一、基本的类
MediaPlayer:负责播放音频和视频。
AudioManager:用来管理音频资源和音频输出。
二、使用MediaPlayer
播放一个从ContentResolver获得的系统Uri:
// 初始化uriUri myUri = ....; MediaPlayer mediaPlayer = new MediaPlayer();// 设置流媒体的类型,便于系统依类型控制音量(铃声音量、多媒体音量等)mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// 设置数据源mediaPlayer.setDataSource(getApplicationContext(), myUri);mediaPlayer.prepare();mediaPlayer.start();
播放网络流媒体:
// 注意:这个音频文件必须能够渐进式下载String url = "http://........"; MediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(url);// 可能需要较长时间,比如缓冲mediaPlayer.prepare();mediaPlayer.start();
播放应用的内置raw资源:
MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);// create()中已调用prepare(),不必再调用后者mediaPlayer.start();
三、异步准备资源 prepare()
可能会花较长时间去提取、解码,为了避免阻塞UI主线程,Android提供了prepareAsync()
来实现异步准备。此方法会在后台开始准备并立即返回,当准备完毕时,系统会调用onPrepared()
:
private class OnPreparedListener implements MediaPlayer.OnPreparedListener { @Override public void onPrepared(MediaPlayer mp) { // 异步准备完毕后,开始播放 mp.start(); }}// 如果是同步调用prepare(),发生错误时系统会直接抛出异常。// 而异步调用prepareAsync()则需要监听错误的发生并处理。private class OnErrorListener implements MediaPlayer.OnErrorListener { /** * 错误发生时的回调方法。 * * 返回true表示错误已处理; * 如果返回false,或者未设置OnErrorListener, * 将会调用OnCompletionListener。 */ @Override public boolean onError(MediaPlayer mp, int what, int extra) { // 处理错误代码略 ... // 此时MediaPlayer已处于Error状态,必须reset() mp.reset(); return true; }}Uri myUri = ....;MediaPlayer mediaPlayer = new MediaPlayer();// 设置异步准备监听器mediaPlayer.setOnPreparedListener(new OnPreparedListener());// 设置错误监听器mediaPlayer.setOnErrorListener(new OnErrorListener());mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(getApplicationContext(), myUri);// 异步准备mediaPlayer.prepareAsync();
四、管理MediaPlayer状态
MediaPlay是基于状态(state)的播放器。某些操作仅当播放器处在特定的状态才有效。如果操作时状态不对,系统会抛出异常或导致其他未期望的行为。具体请看下图:
五、释放MediaPlayer
MediaPlayer占用着大量宝贵的系统资源。当用不着时(比如在未播放的情况下Activity进入onStop()
),可调用release()
来释放系统给它分配的资源:
mediaPlayer.release();mediaPlayer = null;
六、处理音频焦点
可能会有若干个应用于某个时刻正在或者准备要播放音频,若都申请音频焦点则可有序竞争避免同时播放降低用户体验。
private class OnAudioFocusChangeListener implements AudioManager.OnAudioFocusChangeListener { @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { // 获得音频焦点: case AudioManager.AUDIOFOCUS_GAIN: if (mMediaPlayer == null) initMediaPlayer(); else if (!mMediaPlayer.isPlaying() && mIsPrepared) { mMediaPlayer.start(); } mMediaPlayer.setVolume(1.0f, 1.0f); break; // 较长时间地失去音频焦点: case AudioManager.AUDIOFOCUS_LOSS: if (mMediaPlayer.isPlaying()) mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; break; // 短暂地失去音频焦点: case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: if (mMediaPlayer.isPlaying()) mMediaPlayer.pause(); break; // 短暂地失去音频焦点,但可以低音量播放: case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f); break; } }}// 如果系统版本在Android 2.2(API 8)之上,// 则可通过AudioManager来处理音频焦点,// 以获得更好的用户体验。if (Build.VERSION.SDK_INT >= 8) { AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); OnAudioFocusChangeListener onAudioFocusChangeListener = new OnAudioFocusChangeListener(); // AUDIOFOCUS_GAIN:常驻型焦点。还有短暂、独占等。 int result = audioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // 没法获得音频焦点 } else { // 已获得音频焦点,可以开始播放 ... // 播放结束后,可以放弃音频焦点: audioManager.abandonAudioFocus( onAudioFocusChangeListener); }}
七、处理AUDIO_BECOMING_NOISY
当耳机被拔出或断开连接时,系统发出这个Intent,并转换至内置扬声器播放。通过接收它并通知播放服务暂停或者降低音量,可以避免扬声器过于嘈杂而降低用户体验。
在Activity中动态注册一个广播接收器:
private NoisyIntentReceiver mNoisyIntentReceiver = new MusicIntentReceiver();@Overrideprotected void onCreate(Bundle savedInstanceState) { ... IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY); registerReceiver(mNoisyIntentReceiver, intentFilter);}@Overrideprotected void onDestroy() { ... unregisterReceiver(mNoisyIntentReceiver);}
广播接收器的代码:
public class NoisyIntentReceiver extends BroadcastReceiver { private PlaybackService.PlaybackBinder mPlaybackBinder = null; public void setPlaybackBinder( PlaybackService.PlaybackBinder playbackBinder) { mPlaybackBinder = playbackBinder; } @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals( AudioManager.ACTION_AUDIO_BECOMING_NOISY)) { if (mPlaybackBinder != null && mPlaybackBinder.isPlaying()) { mPlaybackBinder.pause(); } } }}
八、使用硬件音量键来控制音量
默认情况下,音量键可控制当前播放的音频流。如果前台Activity此时未播放任何音频,那么按下音量键控制的是铃声音量。在Activity中可做如下设置:
@Overwriteprotected void onCreate(Bundle savedInstanceState) { ... setVolumeControlStream(AudioManager.STREAM_MUSIC); ...}
使得当Activity可见时,它可以按用户的预期来调整Activity的音量。
九、使用耳机播放控制键来控制音频播放
每当按下耳机播放控制键(包括播放、暂停、停止、下一曲、上一曲)时,系统都会广播ACTION_MEDIA_BUTTON。
在Activity中动态注册一个广播接收器:
private RemoteControlReceiver mRemoteControlReceiver = new RemoteControlReceiver();private void onGetAudioFocus() { IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); registerReceiver(mRemoteControlReceiver, intentFilter);}private void onLoseAudioFocus() { unregisterReceiver(mRemoteControlReceiver);}
广播接收器的代码:
public class RemoteControlReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) { KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); switch (keyEvent.getKeyCode()) { case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: // ... break; case KeyEvent.KEYCODE_MEDIA_PLAY: // ... break; case KeyEvent.KEYCODE_MEDIA_PAUSE: // ... break; case KeyEvent.KEYCODE_MEDIA_STOP: // ... break; case KeyEvent.KEYCODE_MEDIA_NEXT: // ... break; case KeyEvent.KEYCODE_MEDIA_PREVIOUS: // ... break; case KeyEvent.KEYCODE_MEDIA_REWIND: // ... break; case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: // ... break; } } }}
参考资料:
Android > Developer > API Guides > Media Playback
http://developer.android.com/intl/zh-cn/guide/topics/media/mediaplayer.html
Android > Developer > Training > Controlling Your App’s Volume and Playback
http://developer.android.com/intl/zh-cn/training/managing-audio/volume-playback.html
- Android媒体播放:MediaPlayer
- Android之多媒体--使用MediaPlayer播放音频
- 24、从头学Android之多媒体--使用MediaPlayer播放音频
- 从头学Android之多媒体--使用MediaPlayer播放音频
- Android之多媒体使用——MediaPlayer播放音频
- 01.Android之多媒体--使用MediaPlayer播放音频01
- 01.Android之多媒体--使用MediaPlayer播放音频02
- Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- 24、从头学Android之多媒体--使用MediaPlayer播放音频
- Android之多媒体MediaPlayer(一个简单的音乐播放器)
- 【Android】媒体——利用MediaPlayer实现对讲语音播放
- android开发笔记之多媒体—MediaPlayer + SurfaceView播放视频
- Android 媒体 I-媒体播放
- 28、从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- 28、从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- 从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- 4.10 从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- Android使用MediaPlayer开发播放器时,AudioManager实现对媒体焦点的控制
- 俄媒:俄军代表团访华 学习解放军管理经验
- 编译安装nutch2.3和hbase0.98.8集成
- 续上
- 用户权限spring security
- 打印1到最大的N位整数
- Android媒体播放:MediaPlayer
- SpringMVC中ajax返回json数据时 数据中包含hibernate对象时,出现转换错误,需加JsonIgnoreProperties来排除
- 普京巴黎峰会冷落土耳其 拉拢中国站队
- 关于oracle时间格式to_date函数
- MyBatis学习笔记(一)
- windows8.1+ArcGIS10.1+VisualStudio2013安装
- Android微信支付彻底扫坑
- Php字符串操作
- 俄罗斯曝大实话:美国西太军力被中国超越