gyn
应用JMF编写mp3播放器
通过网上搜索,可以找到很多利用JMF播放单个文件的代码,写一个简单的播放器书是轻而易举的事情。而事实上JMF中的start似乎就可以让我们搞定一切。但是这样的东西,或者说仅仅一段代码,实在不能说是播放器。我希望让这个播放器尽量地可以使用,我的意思是对于一个提供的播放列表,它至少可以连续播放以及暂停、前进和后退。如果能做到这些,对于我自己,也许还有使用并且修改它的热情。
首先要解决的一个问题是如何实现连续播放。网上就接近这个问题是一个在百度为什么里的已注明自己解决的问题,当然是没有答案的。那么自己来解决吧,这个应该不难。一个while可以了吧。如果这样的话,你会听到一大推杂乱无章的声音,这是将播放列表中的音频叠加起来的效果(无意中做了一个混音,哈哈)。这是因为player.start()是非阻塞的,之后会迅速进入下一个循环。那么就让程序在播放当前这首歌的时长里不要试图去打开下一首歌就行了。对于以上这个循环,应该单独开一个线程,不然它会阻塞主线程,也就意味着无法对播放进行诸如暂停之类的控制。
之后一个问题是暂停。这似乎不应该是一个问题,因为我们用过了太多的播放器,而暂停是一个司空见惯的按钮。于是理所当然的,认为JMF中对于Player这个接口,应该有pause的实现。很遗憾,没有,真的没有。对此google上的搜索,几乎没有直接针对的。只能仔细看JMF的API,还好有一个叫setMediaTim的函数,用来设定播放开始时间。那么我们可以用停止,并且再从被停止的时间点播放来模拟暂停和继续的功能。通过这个问题,让我怀疑也许没有真正意义上的暂停(哈哈哈哈)。
至于,前进和后退,就简单很多了,记住当前播放文件在播放列表上的位置即可。补充一点的是,对于最后一首歌,在start之后,列表的位置是会超界的。这样做是用来退出循环,但这么做似乎早了一点,如果打算暂停或者停止后在播放的话,这是已经退出循环了。所以对此,循环的界限需要做大一些。
好了,下面贴代码。纯属个人解决,办法可能有点土,希望指正。
1
import
java.util.
*
;
2
import
java.io.
*
;
3
import
javax.media.
*
;
4
5
public
class
Mp3State
{
6
private
Vector
<
String
>
songlist
=
new
Vector
<
String
>
();
7
private
int
currentIndex
=
0
;
8
private
Player player
=
null
;
9
private
boolean
isStarted
=
false
;
10
private
boolean
isPaused
=
false
;
11
private
Time pauseTime
=
null
;
12
private
boolean
triggerStart
=
false
;
13
14
public
Mp3State()
{
15
try
{
16
BufferedReader in
=
new
BufferedReader(
new
FileReader(
"
data\\songlist.txt
"
));
17
String eachline;
18
while
((eachline
=
in.readLine())
!=
null
)
{
19
songlist.addElement(eachline);
20
}
21
in.close();
22
}
catch
(IOException e)
{
23
System.out.println(e.getMessage());
24
System.exit(
1
);
25
}
26
}
27
28
public
Vector
<
String
>
getSonglist()
{
29
return
songlist;
30
}
31
32
public
void
setTriggerStart(
boolean
state)
{
33
triggerStart
=
state;
34
}
35
36
public
boolean
getTriggerStart()
{
37
return
triggerStart;
38
}
39
40
public
void
setCurrentIndex(
int
index)
{
41
currentIndex
=
index;
42
}
43
44
public
int
getCurrentIndex()
{
45
return
currentIndex;
46
}
47
48
public
void
setPlayer(Player player)
{
49
this
.player
=
player;
50
}
51
52
public
Player getPlayer()
{
53
return
player;
54
}
55
56
public
void
setIsStarted(
boolean
state)
{
57
isStarted
=
state;
58
}
59
60
public
boolean
getIsStarted()
{
61
return
isStarted;
62
}
63
64
public
void
setIsPaused(
boolean
state)
{
65
isPaused
=
state;
66
}
67
68
public
boolean
getIsPaused()
{
69
return
isPaused;
70
}
71
72
public
void
setPauseTime(Time time)
{
73
pauseTime
=
time;
74
}
75
76
public
Time getPauseTime()
{
77
return
pauseTime;
78
}
79
}
Mp3State.java(用来保存播放器的状态,比如Player对象,以及音乐是否被暂停了)
1
import
javax.media.
*
;
2
3
public
class
Mp3Controller
{
4
private
Mp3State mp3;
5
6
public
Mp3Controller(Mp3State mp3)
{
7
this
.mp3
=
mp3;
8
}
9
10
public
void
mp3Start()
{
11
if
(
!
mp3.getIsStarted())
{
12
mp3.setTriggerStart(
true
);
13
}
else
{
14
System.out.println(
"
Error: A song is playing now, thus player cannot start another
"
);
15
}
16
}
17
18
public
void
mp3Stop()
{
19
if
(mp3.getIsStarted())
{
20
Player player
=
mp3.getPlayer();
21
player.stop();
22
player.deallocate();
23
player.close();
24
mp3.setIsStarted(
false
);
25
mp3.setTriggerStart(
false
);
26
mp3.setCurrentIndex(mp3.getCurrentIndex()
-
1
);
27
}
else
if
(mp3.getIsPaused())
{
28
mp3.setIsPaused(
false
);
29
mp3.setPauseTime(
null
);
30
}
else
{
31
System.out.println(
"
Error: No song has been playing yet, thus can not been stopped
"
);
32
}
33
}
34
35
public
void
mp3Next()
{
36
if
(mp3.getIsStarted()
||
mp3.getIsPaused())
{
37
this
.mp3Stop();
38
}
39
int
currentIndex
=
mp3.getCurrentIndex();
40
if
(currentIndex
<
(mp3.getSonglist().size()
-
1
))
{
41
mp3.setCurrentIndex( currentIndex
+
1
);
42
this
.mp3Start();
43
}
else
{
44
System.out.println(
"
Error: End of the songlist
"
);
45
}
46
}
47
48
public
void
mp3Previous()
{
49
if
(mp3.getIsStarted())
{
50
this
.mp3Stop();
51
}
52
if
(mp3.getIsPaused())
{
53
mp3.setPauseTime(
null
);
54
mp3.setIsPaused(
false
);
55
}
56
int
currentIndex
=
mp3.getCurrentIndex();
57
if
(currentIndex
>
0
)
{
58
mp3.setCurrentIndex( currentIndex
-
1
);
59
this
.mp3Start();
60
}
else
{
61
System.out.println(
"
Error: Start of the songlist
"
);
62
}
63
}
64
65
public
void
mp3Pause()
{
66
if
(mp3.getIsStarted())
{
67
Player player
=
mp3.getPlayer();
68
mp3.setPauseTime(player.getMediaTime());
69
player.stop();
70
player.deallocate();
71
player.close();
72
mp3.setIsStarted(
false
);
73
mp3.setIsPaused(
true
);
74
mp3.setTriggerStart(
false
);
75
mp3.setCurrentIndex(mp3.getCurrentIndex()
-
1
);
76
}
else
{
77
System.out.println(
"
Error: No song has been playing yet, thus can not paused
"
);
78
}
79
}
80
}
Mp3Controller.java(用来控制mp3文件的播放、暂停、停止、前进和后退)
1
import
java.util.
*
;
2
import
java.io.
*
;
3
import
javax.media.
*
;
4
5
public
class
Mp3Player
extends
Thread
{
6
private
Mp3State mp3;
7
private
int
songlistLength;
8
private
Vector
<
String
>
songlist;
9
private
Player player
=
null
;
10
11
public
Mp3Player(Mp3State mp3)
{
12
this
.mp3
=
mp3;
13
songlistLength
=
mp3.getSonglist().size();
14
songlist
=
mp3.getSonglist();
15
}
16
17
public
void
run()
{
18
int
currentIndex;
19
double
currentTime
=
0
;
20
double
currentDuration
=
-
1
;
21
22
while
((currentIndex
=
mp3.getCurrentIndex())
<=
songlistLength)
{
23
if
(mp3.getTriggerStart()
&&
(currentTime
>=
currentDuration))
{
24
try
{
25
File currentSong
=
new
File(songlist.elementAt(currentIndex));
26
player
=
Manager.createRealizedPlayer(currentSong.toURL());
27
mp3.setPlayer(player);
28
if
(mp3.getIsPaused())
{
29
player.setMediaTime(mp3.getPauseTime());
30
}
31
player.start();
32
System.out.println(currentSong.getName());
33
System.out.print(
"
>>>
"
);
34
mp3.setIsStarted(
true
);
35
currentDuration
=
player.getDuration().getSeconds();
36
}
catch
(Exception e)
{
37
System.out.println(e);
38
}
39
mp3.setCurrentIndex(currentIndex
+
1
);
40
}
41
if
(mp3.getIsStarted())
{
42
currentTime
=
player.getMediaTime().getSeconds();
43
}
else
{
44
currentTime
=
0
;
45
currentDuration
=
-
1
;
46
}
47
try
{
48
Thread.sleep((
int
)(Math.random()
*
500
));
49
}
catch
(InterruptedException e)
{}
50
}
51
}
52
}
53
Mp3Player.java(真正负责播放的类,继承了Thread,是一个单独的线程)
1
import
java.io.
*
;
2
3
public
class
Mp3Test
{
4
public
static
void
main(String[] args)
{
5
boolean
loop
=
true
;
6
Mp3State mp3
=
new
Mp3State();
7
Mp3Controller controller
=
new
Mp3Controller(mp3);
8
Mp3Player player
=
new
Mp3Player(mp3);
9
player.start();
10
String command
=
null
;
11
BufferedReader in
=
new
BufferedReader(
new
InputStreamReader(System.in));
12
13
while
(loop)
{
14
System.out.print(
"
>>>
"
);
15
try
{
16
command
=
in.readLine();
17
}
catch
(Exception e)
{}
18
if
(command.equals(
"
start
"
))
{
19
controller.mp3Start();
20
}
else
if
(command.equals(
"
pause
"
))
{
21
controller.mp3Pause();
22
}
else
if
(command.equals(
"
next
"
))
{
23
controller.mp3Next();
24
}
else
if
(command.equals(
"
prev
"
))
{
25
controller.mp3Previous();
26