Как воспроизводить чистые звуковые петли и одноразовые звуки параллельно в JavaFX 2.0? - PullRequest
7 голосов
/ 08 ноября 2011

Я пытаюсь воспроизвести фоновое аудио в цикле в приложении JavaFX 2.0 с использованием JavaFX SDK 2.0.1.Я решил использовать MediaPlayer, созданный с помощью следующего фрагмента кода:

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

Это в основном работает, но когда начинается новый цикл, между концом и началом процесса возникает небольшой промежуток (задержка?)аудио.Так что это не рабочий вариант для меня, так как он не играет в чистую петлю.

Я решил создать новый объект MediaPlayer и запускать воспроизведение каждый раз, когда заканчивается Media.Это работает отлично до сих пор.Кроме того, при нажатии я использую кнопку воспроизведения короткого аудиоклипа.Я обнаружил, что частое и быстрое нажатие на эту кнопку приводит к прерыванию фонового звука.Я создал пример для воспроизведения этого поведения путем непрерывного воспроизведения аудиоклипа с громкостью 0 при нажатии кнопки один раз.Пример не является автономным, поскольку необходимые аудиофайлы отсутствуют.Требуется поместить 2 аудиофайла в исходную директорию проекта:

  • click.wav (очень короткий звук щелчка ~ 300 мс)
  • 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();
    }
}

Ответы [ 2 ]

1 голос
/ 15 февраля 2014

вы смотрели в ExecutorService ? Тогда у вас будет несколько предопределенных тем, например:

ExecutorService service = Executors.newFixedThreadPool(4);

, где 4 - количество создаваемых потоков. Это улучшит производительность, поскольку использует уже созданные потоки, а не создает новые каждый раз, когда вы хотите что-то запустить.

Вы бы создали Runnable и запустили бы его со службой так:

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

Это не только улучшит производительность, но и автоматически назначит задание не занятому в данный момент потоку в его пуле потоков.

Также посмотрите на это: Воспроизведение звуковых циклов с использованием javafx , которое, я считаю, решает вашу небольшую проблему с задержкой.

РЕДАКТИРОВАТЬ: чертовски извините, я не знал, что этот пост был такой старый. Это был лучший результат в Google.

0 голосов
/ 19 сентября 2012

Использование другого потока в

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);
               }
            });
        }
    });

Может решить проблему прерывания

...