Javafx 2 如何使用JavaFX播放mp3片段?

Javafx 2 如何使用JavaFX播放mp3片段?,javafx-2,Javafx 2,我想开发一个以特定方式播放mp3文件的Java程序。我用startTime和endTime标记了这个文件中的许多片段。程序应播放第一个片段,然后休眠5秒钟。然后播放第二个片段并再次入睡。等等我使用JavaFX类MediaPlayer。程序原型如下所示: import javafx.application.Application; import javafx.stage.Stage; import java.io.FileNotFoundException; import java.io.IOEx

我想开发一个以特定方式播放mp3文件的Java程序。我用startTime和endTime标记了这个文件中的许多片段。程序应播放第一个片段,然后休眠5秒钟。然后播放第二个片段并再次入睡。等等我使用JavaFX类MediaPlayer。程序原型如下所示:

import javafx.application.Application;
import javafx.stage.Stage;
import java.io.FileNotFoundException;
import java.io.IOException;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import java.util.concurrent.TimeUnit;

public class JavaFXMediaPlayer02 extends Application {
    @Override
    public void start(Stage stage) throws FileNotFoundException,IOException,InterruptedException {
        Media media = new Media("file:///D:/1016_00.mp3");
        MediaPlayer mediaPlayer = new MediaPlayer(media);
//Set and play the first fragment of mp3-file
        mediaPlayer.setStartTime(Duration.millis(1219.0));
        mediaPlayer.setStopTime(Duration.millis(2728.0));
        mediaPlayer.play();
        System.out.println("1st fragment played!");
        TimeUnit.SECONDS.sleep(5);
//Set and play the second fragment
        mediaPlayer.setStartTime(Duration.millis(3947.0));
        mediaPlayer.setStopTime(Duration.millis(6629.0));
        mediaPlayer.play();
        System.out.println("2nd fragment played!");
        TimeUnit.SECONDS.sleep(5);
//Set and play the second fragment
        mediaPlayer.setStartTime(Duration.millis(7453.0));
        mediaPlayer.setStopTime(Duration.millis(10704.0));
        mediaPlayer.play();
        System.out.println("3rd fragment played!");
    }
    public static void main(String[] args) {
        launch(args);
    }
}

但我只听到第三个片段。怎么了为什么我听不到第一个和第二个片段?如何更正我的程序?JavaFX不适合我的任务吗?

这里的问题在于
时间单位.SECONDS.sleep(5)调用。此方法将当前线程设置为睡眠状态。在您的例子中,这个线程是JavaFX应用程序线程。这会导致整个应用程序“冻结”(如果添加一些GUI元素,情况会更明显),因此
mediaPlayer.play()命令被执行,但由于sleep功能,命令会立即“冻结”。在
`TimeUnit.SECONDS.sleep(5)之后
调用时,您可以为
MediaPlayer
设置新的开始和结束时间,并再次执行
play()
,以便曲目在新的开始时间开始。这就是为什么只播放你最后的片段

现在来看解决方案: 决不能在JavaFX应用程序线程上调用
Thread.sleep()
或类似的方法。但是在你的情况下,你必须在播放片段之间等待一定的时间。第一种方法是调用
Thread.sleep()
TimeUnit.SECONDS.sleep(5)并在JFX应用程序线程上调用
Mediaplayer
方法。但这并不能正常工作,因为您还没有设置调用线程的“顺序”。有多种方法可以做到这一点(通过,等等…)

我试图通过快速而肮脏的编程来解决您的问题,但是我遇到了一个关于
mediaPlayer.setStopTime(Duration.millis())的问题。它似乎在我的电脑上不起作用,所以文件总是播放到最后。我添加了一个停止按钮来模拟自动停止。
下面的类设置新的起点和终点,并播放片段。如果mediaplayer停止,它将调用
LittleMediaScheduler
类上的下一个片段

public class LittleMediaHelper implements Runnable {

public double startTime;
public double endTime;
public MediaPlayer player;
public int id;
public LittleMediaScheduler scheduler;

public LittleMediaHelper(double startTime, double endTime,
        MediaPlayer player, int id) {
    this.startTime = startTime;
    this.endTime = endTime;
    this.player = player;
    this.id = id;
}

public LittleMediaScheduler getScheduler() {
    return scheduler;
}

public void setScheduler(LittleMediaScheduler scheduler) {
    this.scheduler = scheduler;
}

@Override
public void run() {

    Platform.runLater(new Runnable() {

        @Override
        public void run() {

            player.setStartTime(Duration.millis(startTime));
            player.setStopTime(Duration.millis(endTime));

            System.out.println(player.getStartTime());
            System.out.println(player.getStopTime());
            player.play();
            player.setOnStopped(new Runnable() {

                @Override
                public void run() {

                    int idtmp = id + 1;
                    System.out.println("NEXT " + idtmp);

                    scheduler.call(idtmp);

                }
            });

        }
    });

}

}
这个类负责在一个新线程上睡眠一定量,并且在成功睡眠后调用下一个
LittleMediaHelper
class播放功能

public class LittleMediaScheduler {
private ArrayList<LittleMediaHelper> hArrL;
private int SLEEPTIME = 2000;

public LittleMediaScheduler(LittleMediaHelper... helpers) {
    this.hArrL = new ArrayList<>();
    for (LittleMediaHelper h : helpers) {
        h.setScheduler(this);
        System.out.println(h.startTime);
        this.hArrL.add(h);
    }

    System.out.println(hArrL.size());

}

public void init() {
    Thread t = new Thread(this.hArrL.get(0));
    t.start();
}

public void call(final int id) {
    Thread t = new Thread(new Task<String>() {

        @Override
        protected String call() throws Exception {
            Thread.sleep(SLEEPTIME);
            return null;
        }

        @Override
        protected void succeeded() {
            super.succeeded();
            System.out.println("Next playing...");
            if (id > LittleMediaScheduler.this.hArrL.size() - 1) {
                return;
            }
            LittleMediaHelper next = LittleMediaScheduler.this.hArrL
                    .get(id);
            Thread nextT = new Thread(next);
            nextT.start();
        }
    });
    t.start();
}

}
public class JavaFXMediaPlayer02 extends Application {
@Override
public void start(Stage stage) throws FileNotFoundException, IOException,
        InterruptedException {
    Media media = new Media("file:///C:/test.mp3");
    final MediaPlayer mediaPlayer = new MediaPlayer(media);

    LittleMediaHelper phase1 = new LittleMediaHelper(0, 1000, mediaPlayer,
            0);
    LittleMediaHelper phase2 = new LittleMediaHelper(50000, 55000,
            mediaPlayer, 1);
    LittleMediaHelper phase3 = new LittleMediaHelper(200000, 200500,
            mediaPlayer, 2);
    LittleMediaScheduler scheduler = new LittleMediaScheduler(phase1,
            phase2, phase3);

    scheduler.init();

    Group g = new Group();
    Button b = new Button("STOP");
    b.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent arg0) {
            mediaPlayer.pause();
            mediaPlayer.stop();
        }
    });

    g.getChildren().add(b);
    Scene sc = new Scene(g);
    stage.setScene(sc);
    stage.show();

}

public static void main(String[] args) {
    launch(args);
}
}