7

我正在尝试使用 JavaFX SDK 2.0.1 在 JavaFX 2.0 应用程序中循环播放背景音频。我决定使用由以下代码创建的 MediaPlayer:

MediaPlayerBuilder
.create().media(BACKGROUND_MEDIA)
.cycleCount(MediaPlayer.INDEFINITE);

这基本上是有效的,但是当一个新的周期开始时,音频的结束和开始之间会有一个很小的(延迟?)间隙。所以这对我来说不是一个可行的选择,因为它没有播放干净的循环。

我决定构建一个新的 MediaPlayer 对象并在每次媒体结束时开始播放。到目前为止,这工作正常。此外,我使用一个按钮在单击时播放一个简短的 AudioClip。我发现频繁和快速单击此按钮会导致背景音频中断。我创建了一个示例来通过在单击一次按钮时无限播放音量为 0 的 AudioClip 来重现此行为。该示例不是独立的,因为缺少所需的音频文件。它需要在项目的源目录中放置 2 个音频文件:

  • click.wav(非常短的点击声音~300ms)
  • background.wav(约 5 秒的音频)

当播放其他一次性音频声音时,如何在没有这些中断的情况下在后台播放干净的音频循环?仅仅是性能问题吗?

例子:

package mediatest;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.media.AudioClip;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaPlayerBuilder;
import javafx.stage.Stage;

public class MediaTest extends Application {

    private static final AudioClip CLICK_AUDIOCLIP = new AudioClip(MediaTest.class.getResource("/click.wav").toString());
    private static final Media BACKGROUND_MEDIA = new Media(MediaTest.class.getResource("/background.wav").toString());

    private MediaPlayerBuilder builder;

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

    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root, 300, 250);

        this.builder = MediaPlayerBuilder
                       .create()
                       .media(BACKGROUND_MEDIA)
                       .onEndOfMedia(new Runnable() {

                           public void run() {
                               MediaPlayer player = MediaTest.this.builder.build();
                               player.play();
                           }
                       });

        MediaPlayer player = this.builder.build();
        player.play();

        Button btn = new Button();
        btn.setText("Repeat playing short audio clip");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                //Simulation of many button clicks
                MediaTest.CLICK_AUDIOCLIP.setCycleCount(AudioClip.INDEFINITE);
                MediaTest.CLICK_AUDIOCLIP.play(0);
            }
        });

        root.getChildren().add(btn);

        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
4

2 回答 2

1

你看过ExecutorService吗?然后,您将拥有许多预定义的线程,如下所示:

ExecutorService service = Executors.newFixedThreadPool(4);

其中 4 是它创建的线程数。它将提高性能,因为它使用已经创建的线程,而不是每次您想要运行某些东西时都创建一个新线程。

您将创建一个 Runnable 并使用服务执行它,如下所示:

Runnable r = new Runnable() {
    @Override
    public void run() {
       playSound();
    }
};
service.execute(r);

这不仅会提高性能,而且会自动将作业分配给其线程池中的当前不忙的线程。

另请参阅:使用 javafx 播放声音循环,我相信这可以解决您的小延迟问题。

编辑:该死的对不起,我不知道这篇文章有那么老了。这是谷歌的最高结果。

于 2014-02-15T19:14:57.613 回答
0

在使用另一个线程

public void handle(ActionEvent event) {
            Platform.runLater(new Runnable()
            {
               @Override
               public void run()
               {  
                  //Simulation of many button clicks
                  MediaTest.CLICK_AUDIOCLIP.setCycleCount(AudioClip.INDEFINITE);
                  MediaTest.CLICK_AUDIOCLIP.play(0);
               }
            });
        }
    });

可以解决中断问题

于 2012-09-19T12:33:12.617 回答