Android多媒体开发:MusicPlayer篇
来源:互联网 发布:淘宝视频怎么发布 编辑:程序博客网 时间:2024/06/06 09:09
今天被问到视频播放,录音的问题,又想起了曾经开发音视频播放,遇到的那些坑。其实多媒体的知识比较多,客户端开发难度也大,毕竟android应用层用java开发,对于音频开发,最好是有强大的C/C++功底才好研究底层,任重道远。
一起学习吧,先从音乐播放器开始。
一,先贴后台播放音乐的service部分代码
不一定要这样写,仅供参考。
/** * 可播放音视频的 MediaPlayerService duqian * 既可以activity绑定该service,也可以直接start,实现后台播放音乐 * 2016/01/08 */public class AudioPlayerService extends Service { private static final String TAG = AudioPlayerService.class.getSimpleName(); private MyBinder myBinder; private String music_name; public AudioPlayerService() { super(); } private static VideoView mediaPlayer; /** * 初始化播放器控件 * @param videoView */ private void initPlayer(VideoView videoView) { mediaPlayer = videoView; } /** * 播放音乐 */ public void play(){ if(mediaPlayer != null){ mediaPlayer.start(); notifyChange(MediaStaticVar.ACTION_PREPARED, MediaStaticVar.DATA_PREPARED); //showNotification(); } } /** * 暂停音乐 */ public void pause(){ if(mediaPlayer != null){ mediaPlayer.pause(); } //stopNotification(); } /** * 跳到指定播放位置 * @param progress */ private void seekTo(int progress) { MediaStaticVar.progress = progress; if(mediaPlayer != null){ mediaPlayer.seekTo(progress); } } //是否正在播放 public boolean isPlaying(){ boolean playing =false; if(mediaPlayer != null){ playing= mediaPlayer.isPlaying(); } return playing; } //总时长 private long getDuration(){ long duration = 1000*60*6; if (mediaPlayer!=null){ duration = mediaPlayer.getDuration(); } return duration; } //当前时长 private long getCurrentPosition(){ long currentPosition = 0; if (mediaPlayer!=null){ currentPosition = mediaPlayer.getCurrentPosition(); } return currentPosition; } /** * 创建播放器 * @param path */ private void startPlay(String path,Context context) { if (path == null||TextUtils.isEmpty(path)) { return; } else { MediaStaticVar.path = path; if (mediaPlayer==null){ LogUtils.debug(TAG, "mediaPlayer==null"); mediaPlayer = new VideoView(context); } mediaPlayer.setVideoPath(path); mediaPlayer.seekTo(MediaStaticVar.progress);//上次播放的位置 mediaPlayer.requestFocus(); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.setPlaybackSpeed(1.0f); play(); //notifyChange(MediaStaticVar.ACTION_PREPARED, MediaStaticVar.DATA_PREPARED); } }); mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { notifyChange(MediaStaticVar.ACTION_PREPARED,MediaStaticVar.DATA_COMPLETED); } }); mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { notifyChange(MediaStaticVar.ACTION_PREPARED,MediaStaticVar.DATA_ERROR); LogUtils.debug(what + "" + extra + "error"); return true; } }); } } @Override public IBinder onBind(Intent intent) { LogUtils.debug(TAG,"onBind"); myBinder = new MyBinder(); return myBinder;//使用Binder对象,要返回 } /** * 定义一个类 继承 Binder,定义一个对象和调用者通信 */ private class MyBinder extends Binder implements IMusicPlayerService { @Override public void callInitPlayer(VideoView videoView) { initPlayer(videoView); } @Override public void callPlayer(String path, Context mContext) { startPlay(path,mContext); } @Override public void callPause() { pause(); } @Override public void callPlay() { play(); } @Override public boolean callIsPlaying() { return isPlaying(); } @Override public void callSeekTo(int progress) { seekTo(progress); } @Override public void callPrevious() { } @Override public void callNext() { } @Override public long callGetDuration() { return getDuration(); } @Override public long callGetCurrentPosition() { return getCurrentPosition(); } @Override public void callNotifyChange(String nofity, int action) { notifyChange(nofity,action); } @Override public void stopNotification() { stopNotification(); } } @Override public boolean onUnbind(Intent intent) { LogUtils.debug(TAG,"on unbind"); return super.onUnbind(intent); } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); if (mediaPlayer != null) { try { mediaPlayer.stopPlayback(); mediaPlayer = null; LogUtils.debug(TAG,"mediaPlayer stop"); } catch (Exception e) { e.printStackTrace(); } } stopNotification(); MediaStaticVar.progress = 0; MediaStaticVar.path = ""; } /** * 发消息 * @param nofity */ private void notifyChange(String nofity,int action){ Intent intent = new Intent(); if (nofity==null) { intent.setAction(MediaStaticVar.ACTION_PREPARED); }else{ intent.setAction(nofity); } intent.putExtra("data",action); sendBroadcast(intent);//发广播 }}
二,IMusicPlayerService接口
如果activity绑定了该service,控制后台音乐的播放,暂停,下一曲,上一曲。那么可以写一个类似的接口, 定义一个类继承 Binder,实现IMusicPlayerService接口,以便service和调用者通信。
public interface IMusicPlayerService { public void callInitPlayer(VideoView videoView); public void callPlayer(String path,Context mContext); public void callPause(); public void callPlay(); public boolean callIsPlaying(); public void callSeekTo(int progress); public void callPrevious(); public void callNext(); public long callGetDuration(); public long callGetCurrentPosition(); public void callNotifyChange(String nofity,int action); public void stopNotification();}
三,启动/绑定service
以下代码不全,仅供参考。
//开启服务 private IMusicPlayerService iservice; //服务 private MyConn conn; private void startService(Class clazz) { //1.开启服务,与本activity不绑定 Intent service = new Intent(context, clazz); service.setPackage(context.getPackageName());//这里你需要设置你应用的包名,5.0新要求 context.startService(service);//多次调用startService并不会启动多个service 而是会多次调用onStart //2.开启服务与本activity绑定 Intent intent = new Intent(this,clazz); conn = new MyConn(); bindService(intent,conn,Context.BIND_AUTO_CREATE); } private boolean isServiceConnected; //定义绑定服务的接口 private class MyConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { //当绑定服务成功后,会回调此方法 isServiceConnected = true; iservice = (IMusicPlayerService)service; iservice.callPlayer(MediaStaticVar.path,context);//高清音乐,开始播放 } @Override public void onServiceDisconnected(ComponentName name) { //当取消绑定服务成功后,会回调这个方法 iservice = null; } }
四,MediaPlayer相关介绍
对于背景音乐,将MediaPlayer封装在Service中即可实现。
MediaPlayer支持元数据、音频文件、音频流等形式的源数据的播放。
(1)播放元数据
所谓元数据即raw文件夹下的资源文件,调用方法如下:
mMediaPlayer=MediaPlayer.create(this, R.raw.test_cbr);mMediaPlayer.start();
(2)播放音频文件
对于本地文件,其数据源可以通过Uri来表示,在开始播放前需要设置播放类型并加载缓冲,示例如下:
Uri myUri="/path/to/localfile";MediaPlayer mediaPlayer=new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(getApplicationContext(), myUri);mediaPlayer.prepare(); //加载缓冲mediaPlayer.start();
(3)播放流
MediaPlayer支持基于网络的流播放,其支持的网络协议包括RSTP(RTP、SDP)、HTTP渐进流(HTTP Progressive Streaming)、HTTP生活流(HTTP Live Streaming Draft Protocol,仅Honeycomb版本中用到)等。Android4.0开始支持HTTPS协议,在网络播放和本地播放上略有不同,示例如下:
String url="http://duqian.net.cn/demo.mp3;MediaPlayer mediaPlayer=new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(url);mediaPlayer.prepare(); //加载缓冲mediaPlayer.start();
五,mediaPlayer设置监听
准备完成,播放完成,发生播放错误等,都可以监听。
不能在UI主线程中调用prepare方法。应通过prepareAsync方法将加载缓冲的工作放置在非UI主线程中进行,当准备工作完成时,MediaPlayer通过MediaPlayer.OnPreparedListener监听器可以监听到该事件。设置监听器的方法如下:
MediaPlayer.OnPreParedListener mPreparedListener=new MediaPlayer.OnPreparedListener(){ public void onPrepared(MediaPlayer mp){ mediaPlayer.start(); }}
当播放结束时,通过MediaPlayer.OnCompletionListener可以监听到播放结束的消息,示例如下:
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){public void onCompletion(MediaPlayer mediaPlayer){//stop or next}});
MediaPlayer还存在一个出错的状态,即MEDIA_PLAYER_STATE_ERROR。监听出错的监听器为MediaPlayer.OnErrorListener。
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { LogUtils.debug(what + "" + extra + "error"); return true; }});
六,个人的一点总结
其实android 系统API中的mediaPlayer使用起来还是挺方便的。当然也可以使用第三方多媒体框架,实现音视频的播放。
杜乾,Dusan,Q291902259;欢迎交流。
- Android多媒体开发:MusicPlayer篇
- Android MusicPlayer
- 自制最简Android MusicPlayer
- Android 多媒体开发-音频
- Android多媒体开发介绍
- Android多媒体开发介绍
- Android多媒体开发介绍
- Android开发&多媒体控件
- Android 多媒体开发 MediaPlayer
- android多媒体开发笔记
- Android多媒体开发
- Android多媒体开发
- Android多媒体开发:照相机
- Android多媒体开发:录音机
- Android多媒体开发框架
- Android多媒体开发介绍
- Android多媒体开发 android mediaplayer
- Android 多媒体开发相关技巧
- matlab基本操作和语法
- 禁止输入中文字符
- ibeacon 学习
- proftp权限设置
- Error while waiting for device: The emulator process for AVD Nexus_5X_API_22 was killed.
- Android多媒体开发:MusicPlayer篇
- iOS中Xcode使用UIScrollView+AutoLayout轻松实现滚动布局
- Python练习 - 廖雪峰教程
- 状态机
- mybatis自动创建代码
- dns
- css 复习 - 文档流
- Map扩展一对多的使用
- 移动web学习--淘宝 flexible.js