问题描述
我注意到很多话题都是关于使用 JLayer
暂停/恢复MP3,所以为了帮助每个人,我已经完成了整个班级专为此而设计!请参阅下面的答案。
I've noticed that a lot of topics were about pausing/resuming an MP3 using JLayer
, so in order to help everybody, I've made a whole entire class designed just for that! Please see the answer below.
注意:这仅供我个人使用,因此可能不像某些人希望的那样强大。但由于它的简单性,进行简单的修改并不难。
Note: This was for my personal use, so it may not be as robust as some people were hoping. But it is not that hard to make simple modifications, due to its simplicity.
推荐答案
一个非常简单的播放器实现真的暂停播放。它的工作原理是使用一个单独的线程播放流并告诉玩家线程是否/何时暂停和恢复。
A very simple implementation of a player that is really pausing playback. It works by using a separate thread to play the stream and telling the player thread if/when to pause and resume.
public class PausablePlayer {
private final static int NOTSTARTED = 0;
private final static int PLAYING = 1;
private final static int PAUSED = 2;
private final static int FINISHED = 3;
// the player actually doing all the work
private final Player player;
// locking object used to communicate with player thread
private final Object playerLock = new Object();
// status variable what player thread is doing/supposed to do
private int playerStatus = NOTSTARTED;
public PausablePlayer(final InputStream inputStream) throws JavaLayerException {
this.player = new Player(inputStream);
}
public PausablePlayer(final InputStream inputStream, final AudioDevice audioDevice) throws JavaLayerException {
this.player = new Player(inputStream, audioDevice);
}
/**
* Starts playback (resumes if paused)
*/
public void play() throws JavaLayerException {
synchronized (playerLock) {
switch (playerStatus) {
case NOTSTARTED:
final Runnable r = new Runnable() {
public void run() {
playInternal();
}
};
final Thread t = new Thread(r);
t.setDaemon(true);
t.setPriority(Thread.MAX_PRIORITY);
playerStatus = PLAYING;
t.start();
break;
case PAUSED:
resume();
break;
default:
break;
}
}
}
/**
* Pauses playback. Returns true if new state is PAUSED.
*/
public boolean pause() {
synchronized (playerLock) {
if (playerStatus == PLAYING) {
playerStatus = PAUSED;
}
return playerStatus == PAUSED;
}
}
/**
* Resumes playback. Returns true if the new state is PLAYING.
*/
public boolean resume() {
synchronized (playerLock) {
if (playerStatus == PAUSED) {
playerStatus = PLAYING;
playerLock.notifyAll();
}
return playerStatus == PLAYING;
}
}
/**
* Stops playback. If not playing, does nothing
*/
public void stop() {
synchronized (playerLock) {
playerStatus = FINISHED;
playerLock.notifyAll();
}
}
private void playInternal() {
while (playerStatus != FINISHED) {
try {
if (!player.play(1)) {
break;
}
} catch (final JavaLayerException e) {
break;
}
// check if paused or terminated
synchronized (playerLock) {
while (playerStatus == PAUSED) {
try {
playerLock.wait();
} catch (final InterruptedException e) {
// terminate player
break;
}
}
}
}
close();
}
/**
* Closes the player, regardless of current state.
*/
public void close() {
synchronized (playerLock) {
playerStatus = FINISHED;
}
try {
player.close();
} catch (final Exception e) {
// ignore, we are terminating anyway
}
}
// demo how to use
public static void main(String[] argv) {
try {
FileInputStream input = new FileInputStream("myfile.mp3");
PausablePlayer player = new PausablePlayer(input);
// start playing
player.play();
// after 5 secs, pause
Thread.sleep(5000);
player.pause();
// after 5 secs, resume
Thread.sleep(5000);
player.resume();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
这篇关于JLayer - 暂停和恢复歌曲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!