2015-01-06 2 views
0

В приложении Java swing предполагается, что следующий фрагмент будет играть сирену. Он запускается нормально, но останавливается преждевременно, не всегда в одно и то же время (то есть иногда он останавливается почти сразу, а иногда и после более длительной задержки, но обычно он не заканчивает воспроизведение всего звукового файла). Что может быть причиной этого?Воспроизведение звука в режиме Java заканчивается досрочно

Я сделал все возможное, чтобы создать минимальный пример, который до сих пор имеет проблемы:

package monster; 

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.io.File; 
import javafx.embed.swing.JFXPanel; 
import javafx.scene.media.Media; 
import javafx.scene.media.MediaPlayer; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Example_2 extends JPanel { 

    protected static final long serialVersionUID = 1L; 

    public Example_2() { 
     setPreferredSize(new Dimension(100,100)); 
     setBackground(Color.white); 
     createPanel(); 
    } 

    public static void main(String[] args) { 
     Example_2 e = new Example_2(); 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(e, BorderLayout.CENTER); 
     f.pack(); 
     f.setVisible(true); 
     f.repaint(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     new Thread(
      new Runnable() { 
       public void run() { 
        try { 
         File f = new File("sound/siren_short.wav"); 
         String url = "file:///"+f.getAbsolutePath().replaceAll("\\\\","/").replaceAll(" ", "%20"); 
         MediaPlayer mp = new MediaPlayer(new Media(url)); 
         mp.play(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      }).start(); 
    } 

    public static JFXPanel createPanel() { 
     return new JFXPanel(); 
    } 

} 
+0

Возможно, jvm помещает медиа-поток в режим сна, прежде чем он будет сделан, потому что у него есть что-то более важное. Я надеюсь, что это решение голода в мире ... Вы пытались запустить это в отладчике, чтобы узнать, к какой теме переключается ваше приложение? – Foosh

+0

Чтобы лучше помочь, опубликуйте [MCVE] (http://stackoverflow.com/help/mcve) (минимальный полный проверяемый пример) или [SSCCE] (http://www.sscce.org/) (Short, Self Содержащийся, правильный пример). –

+0

Закрывает ли все приложение Swing? Или он продолжает работать, пока звуковой файл перестает играть? Кроме того, является ли ваш новый поток демоном или нет? –

ответ

1

В текущем примере кода «example2» отвечал, он смотрит на меня, как основной() выполняет и выходы , Да, вызов MediaPlayer запускает фоновый поток, но я предполагаю, что когда main() заканчивается, это также завершает поток MediaPlayer (возможно, потому, что он имеет только статус демона). Я еще не использовал MediaPlayer, так что я не знаю, может ли это привести или нет.

Простой тест для вас: добавьте следующую строку.

Thread.sleep(5000); // pauses 5 seconds 

или что-то похожее на конец main(), после вызова repaint(). Число миллисекунд: используйте число, которое больше длины вашего звука. Звук теперь воспроизводится до завершения? Вероятно, вам придется поместить новую строку кода в попытку ... catch.

Проверьте, есть ли api для Thread(), когда вы получаете шанс. Когда вы перейдете на страницу, я рекомендую выполнить поиск на «демоне». Существуют методы тестирования или настройки статуса демона, а также краткое объяснение того, что означает статус. Есть вероятность, что если вы установите свой runnable на , а не, будет демон, программа (как показано) будет воспроизводиться один раз, а затем висеть без возможности ее прекратить, кроме как убить ее через Eclipse (если она была запущена в Eclipse) или через диспетчер задач ОС.

Я не очень разбираюсь в отладочных потоках в Eclipse - боюсь, я не могу предложить никаких предложений.

Andrew Thompson сделал хорошее предложение, чтобы использовать Clip. Это имеет преимущество держать нас в «знакомой» территории. Я часто использовал Clip, но не библиотеки JavaFX. Если у вас былоКлип, строка кода, которую я предлагаю (Thread.sleep), определенно была бы необходима, чтобы звук воспроизводился до завершения.

Вот теория: код, который загружает и выполняет команду play(), не является демонами. Однако фононные процессы, которые передают звуковые данные в линию, являются демонами. Если это так, то поведение, которое я описываю (завершение после основного потока выполняется), будет последовательным.

+0

Проблема продолжалась после добавления Thread.sleep. Однако, используя Clip, он исправил это. Я нашел http://stackoverflow.com/tags/javasound/info очень полезным для выяснения того, как использовать Clip. Спасибо! – baixiwei

+0

Тогда кредит обязательно должен пойти к Эндрю! –

+0

Согласен, если он сделает это в ответ, я приму это (я не смогу это сделать, если он не ответит, не так ли?). – baixiwei

Смежные вопросы