我是靠谱客的博主 无聊白昼,这篇文章主要介绍Android多媒体开发:MusicPlayer篇,现在分享给大家,希望可以做个参考。

今天被问到视频播放,录音的问题,又想起了曾经开发音视频播放,遇到的那些坑。其实多媒体的知识比较多,客户端开发难度也大,毕竟android应用层用java开发,对于音频开发,最好是有强大的C/C++功底才好研究底层,任重道远。
一起学习吧,先从音乐播放器开始。

一,先贴后台播放音乐的service部分代码

不一定要这样写,仅供参考。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/** * 可播放音视频的 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和调用者通信。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

以下代码不全,仅供参考。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//开启服务 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文件夹下的资源文件,调用方法如下:

复制代码
1
2
mMediaPlayer=MediaPlayer.create(this, R.raw.test_cbr); mMediaPlayer.start();

(2)播放音频文件
对于本地文件,其数据源可以通过Uri来表示,在开始播放前需要设置播放类型并加载缓冲,示例如下:

复制代码
1
2
3
4
5
6
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协议,在网络播放和本地播放上略有不同,示例如下:

复制代码
1
2
3
4
5
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监听器可以监听到该事件。设置监听器的方法如下:

复制代码
1
2
3
4
5
MediaPlayer.OnPreParedListener mPreparedListener=new MediaPlayer.OnPreparedListener(){ public void onPrepared(MediaPlayer mp){ mediaPlayer.start(); } }

当播放结束时,通过MediaPlayer.OnCompletionListener可以监听到播放结束的消息,示例如下:

复制代码
1
2
3
4
5
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){ public void onCompletion(MediaPlayer mediaPlayer){ //stop or next } });

MediaPlayer还存在一个出错的状态,即MEDIA_PLAYER_STATE_ERROR。监听出错的监听器为MediaPlayer.OnErrorListener。

复制代码
1
2
3
4
5
6
7
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多媒体开发内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部