2011-11-07 1 views
7

JavaFX SDK 2.0.1을 사용하여 JavaFX 2.0 응용 프로그램의 루프에서 배경 오디오를 재생하려고합니다. 나는 다음과 같은 코드 조각에 의해 생성 된 MediaPlayer를 사용하기로 결정 :JavaFX 2.0에서 깨끗한 오디오 루프와 원샷 사운드를 병렬로 재생하는 방법은 무엇입니까?

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

이 기본적으로 작동을하지만, 새로운주기가 작은 (대기 시간이?)이 끝과 오디오의 시작 사이의 간격이 시작될 때. 따라서 깨끗한 루프를 재생하지 못하기 때문에 나에게 맞는 옵션이 아닙니다.

미디어가 끝날 때마다 새로운 MediaPlayer 개체를 만들고 재생을 시작하기로 결정했습니다. 지금까지 잘 작동합니다. 또한 클릭하면 짧은 AudioClip을 재생하는 버튼을 사용합니다. 빈번하고 빠른이 버튼을 클릭하면 배경 오디오의 인터럽트가 발생 함을 발견했습니다. 이 버튼을 한 번 클릭하면 볼륨 0으로 AudioClip을 무의식적으로 재생하여이 동작을 재현하는 예제를 만들었습니다. 이 예제는 필수 오디오 파일이 없기 때문에 자체 포함되어 있지 않습니다. (~ 정말 짧은 클릭 음이 300ms)

  • click.wav
  • background.wav (오디오 ~ 오초)

을 : 그것은 프로젝트의 소스 디렉토리에이 개 오디오 파일을 배치 할 필요 다른 원샷 오디오 사운드를 재생할 때 이러한 인터럽트없이 백그라운드에서 깨끗한 오디오 루프를 재생하려면 어떻게합니까? 성능 문제일까요?

예 :

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(); 
    } 
} 
+1

백그라운드 오디오 용으로 'javax.sound.sampled.SourceDataLine'을 사용하는 경우, 문제는 없습니다. 'javafx.scene.media.Media'로 오디오 재생이 다른 것처럼 보입니다. – pmoule

답변

0

+1

고맙지 만 코드는 이미 JavaFX 응용 프로그램 스레드에서 실행됩니다. 그래서'Platform.runlater (...) '를 호출 할 때 다른 동작은 없다. 나는 새로운 스레드 (new Runnable (...)). start();로 새로 생성 된 스레드에서 이벤트를 실행하려고 시도했다. 문제가 계속 발생합니다. – pmoule

1

당신이 ExecutorService로 보았다 중단의 문제를 해결할 수 있습니다

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

에서 다른 스레드를 사용하십니까? 다음과 같이 사전 정의 된 스레드 수가 있습니다.

ExecutorService service = Executors.newFixedThreadPool(4); 

여기서 4는 스레드 수입니다. 무언가를 실행하고 싶을 때마다 새로운 스레드를 만들기보다는 이미 만들어진 스레드를 사용하기 때문에 성능이 향상됩니다.

은 당신의 Runnable을 만들고 그래서 같은 서비스를 실행하는 것입니다 :

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

뿐만 아니라이 성능을 향상시킬 것입니다하지만 자동으로 스레드 풀에서하지-현재 바쁜 스레드에 작업을 할당합니다.

또한보십시오 : Playing sound loops using javafx 나는 당신의 작은 잠복 문제를 해결할 것으로 믿습니다.

편집 : 죄송합니다. 죄송 합니다만, 나는이 게시물이 오래되었음을 알지 못했습니다. Google에서 최고의 결과였습니다.