前面有文章曾经地介绍过mediaplayer的基本用法,这里就更加深入地讲解mediaplayer的在线播放功能。本文主要实现mediaplayer在线播放音频的功能,由于在线视频播放比在线音频播放复杂,因此先介绍在线音频播放的实现,这样可以帮助大家逐步深入了解mediaplayer的在线播放功能。
先来看看本文程序运行的结果如下图所示:
main.xml的源码如下:
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
|
<?xml version= "1.0" encoding= "utf-8" ?>
<framelayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_height= "fill_parent" android:layout_width= "fill_parent" >
<linearlayout android:layout_height= "wrap_content"
android:layout_width= "fill_parent" android:orientation= "vertical"
android:layout_gravity= "top" >
<linearlayout android:orientation= "horizontal"
android:layout_gravity= "center_horizontal" android:layout_margintop= "4.0dip"
android:layout_height= "wrap_content" android:layout_width= "wrap_content" >
<button android:layout_width= "wrap_content"
android:layout_height= "wrap_content" android:id= "@+id/btnplayurl"
android:text= "播放网络音频" ></button>
<button android:layout_height= "wrap_content" android:id= "@+id/btnpause"
android:text= "暂停" android:layout_width= "80dip" ></button>
<button android:layout_height= "wrap_content"
android:layout_width= "80dip" android:text= "停止" android:id= "@+id/btnstop" ></button>
</linearlayout>
<linearlayout android:orientation= "horizontal"
android:layout_width= "fill_parent" android:layout_height= "wrap_content"
android:layout_marginbottom= "20dip" >
<seekbar android:paddingright= "10dip" android:layout_gravity= "center_vertical"
android:paddingleft= "10dip" android:layout_weight= "1.0"
android:layout_height= "wrap_content" android:layout_width= "wrap_content"
android:id= "@+id/skbprogress" android:max= "100" ></seekbar>
</linearlayout>
</linearlayout>
</framelayout>
|
player.java是本文的核心,player.java实现了“进度条更新”、“数据缓冲”等功能,虽然不是很复杂的功能,但却是非常有用的功能。
player.java源码如下:
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
|
package com.musicplayer;
import java.io.ioexception;
import java.util.timer;
import java.util.timertask;
import android.media.audiomanager;
import android.media.mediaplayer;
import android.media.mediaplayer.onbufferingupdatelistener;
import android.media.mediaplayer.oncompletionlistener;
import android.os.handler;
import android.os.message;
import android.util.log;
import android.widget.seekbar;
public class player implements onbufferingupdatelistener,
oncompletionlistener, mediaplayer.onpreparedlistener{
public mediaplayer mediaplayer;
private seekbar skbprogress;
private timer mtimer= new timer();
public player(seekbar skbprogress)
{
this .skbprogress=skbprogress;
try {
mediaplayer = new mediaplayer();
mediaplayer.setaudiostreamtype(audiomanager.stream_music);
mediaplayer.setonbufferingupdatelistener( this );
mediaplayer.setonpreparedlistener( this );
} catch (exception e) {
log.e( "mediaplayer" , "error" , e);
}
mtimer.schedule(mtimertask, 0 , 1000 );
}
/*******************************************************
* 通过定时器和handler来更新进度条
******************************************************/
timertask mtimertask = new timertask() {
@override
public void run() {
if (mediaplayer== null )
return ;
if (mediaplayer.isplaying() && skbprogress.ispressed() == false ) {
handleprogress.sendemptymessage( 0 );
}
}
};
handler handleprogress = new handler() {
public void handlemessage(message msg) {
int position = mediaplayer.getcurrentposition();
int duration = mediaplayer.getduration();
if (duration > 0 ) {
long pos = skbprogress.getmax() * position / duration;
skbprogress.setprogress(( int ) pos);
}
};
};
//*****************************************************
public void play()
{
mediaplayer.start();
}
public void playurl(string videourl)
{
try {
mediaplayer.reset();
mediaplayer.setdatasource(videourl);
mediaplayer.prepare(); //prepare之后自动播放
//mediaplayer.start();
} catch (illegalargumentexception e) {
// todo auto-generated catch block
e.printstacktrace();
} catch (illegalstateexception e) {
// todo auto-generated catch block
e.printstacktrace();
} catch (ioexception e) {
// todo auto-generated catch block
e.printstacktrace();
}
}
public void pause()
{
mediaplayer.pause();
}
public void stop()
{
if (mediaplayer != null ) {
mediaplayer.stop();
mediaplayer.release();
mediaplayer = null ;
}
}
@override
/**
* 通过onprepared播放
*/
public void onprepared(mediaplayer arg0) {
arg0.start();
log.e( "mediaplayer" , "onprepared" );
}
@override
public void oncompletion(mediaplayer arg0) {
log.e( "mediaplayer" , "oncompletion" );
}
@override
public void onbufferingupdate(mediaplayer arg0, int bufferingprogress) {
skbprogress.setsecondaryprogress(bufferingprogress);
int currentprogress=skbprogress.getmax()*mediaplayer.getcurrentposition()/mediaplayer.getduration();
log.e(currentprogress+ "% play" , bufferingprogress + "% buffer" );
}
}
|
test_musicplayer.java是主程序,负责调用player类,其中关键部分是seekbarchangeevent这个seekbar拖动的事件:seekbar的progress是0~seekbar.getmax()之内的数,而mediaplayer.seekto()的参数是0~mediaplayer.getduration()之内数,所以mediaplayer.seekto()的参数是(progress/seekbar.getmax())*player.mediaplayer.getduration()。
test_musicplayer.java源码如下:
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
|
package com.musicplayer;
import android.app.activity;
import android.os.bundle;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.seekbar;
public class test_musicplayer extends activity {
private button btnpause, btnplayurl, btnstop;
private seekbar skbprogress;
private player player;
/** called when the activity is first created. */
@override
public void oncreate(bundle savedinstancestate) {
super .oncreate(savedinstancestate);
setcontentview(r.layout.main);
this .settitle( "在线音乐播放---hellogv编写" );
btnplayurl = (button) this .findviewbyid(r.id.btnplayurl);
btnplayurl.setonclicklistener( new clickevent());
btnpause = (button) this .findviewbyid(r.id.btnpause);
btnpause.setonclicklistener( new clickevent());
btnstop = (button) this .findviewbyid(r.id.btnstop);
btnstop.setonclicklistener( new clickevent());
skbprogress = (seekbar) this .findviewbyid(r.id.skbprogress);
skbprogress.setonseekbarchangelistener( new seekbarchangeevent());
player = new player(skbprogress);
}
class clickevent implements onclicklistener {
@override
public void onclick(view arg0) {
if (arg0 == btnpause) {
player.pause();
} else if (arg0 == btnplayurl) {
//在百度mp3里随便搜索到的,大家可以试试别的链接
string url= "http://219.138.125.22/myweb/mp3/cmp3/jh19.mp3" ;
player.playurl(url);
} else if (arg0 == btnstop) {
player.stop();
}
}
}
class seekbarchangeevent implements seekbar.onseekbarchangelistener {
int progress;
@override
public void onprogresschanged(seekbar seekbar, int progress,
boolean fromuser) {
// 原本是(progress/seekbar.getmax())*player.mediaplayer.getduration()
this .progress = progress * player.mediaplayer.getduration()
/ seekbar.getmax();
}
@override
public void onstarttrackingtouch(seekbar seekbar) {
}
@override
public void onstoptrackingtouch(seekbar seekbar) {
// seekto()的参数是相对与影片时间的数字,而不是与seekbar.getmax()相对的数字
player.mediaplayer.seekto(progress);
}
}
}
|
感兴趣的读者可以亲自动手调试一下本文实例代码,相信会对大家理解android程序设计起到一定的促进作用。