Как проигрывать аудио в Java-приложении - PullRequest
1 голос
/ 17 января 2011

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

Первый метод - это буквально метод:

        public void playSoundFile(File file) {//http://java.ittoolbox.com/groups/technical-functional/java-l/sound-in-an-application-90681

        try {
//get an AudioInputStream
            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
//get the AudioFormat for the AudioInputStream
            AudioFormat audioformat = ais.getFormat();
            System.out.println("Format: " + audioformat.toString());
            System.out.println("Encoding: " + audioformat.getEncoding());
            System.out.println("SampleRate:" + audioformat.getSampleRate());
            System.out.println("SampleSizeInBits: " + audioformat.getSampleSizeInBits());
            System.out.println("Channels: " + audioformat.getChannels());
            System.out.println("FrameSize: " + audioformat.getFrameSize());
            System.out.println("FrameRate: " + audioformat.getFrameRate());
            System.out.println("BigEndian: " + audioformat.isBigEndian());
//ULAW format to PCM format conversion
            if ((audioformat.getEncoding() == AudioFormat.Encoding.ULAW)
                    || (audioformat.getEncoding() == AudioFormat.Encoding.ALAW)) {
                AudioFormat newformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                        audioformat.getSampleRate(),
                        audioformat.getSampleSizeInBits() * 2,
                        audioformat.getChannels(),
                        audioformat.getFrameSize() * 2,
                        audioformat.getFrameRate(), true);
                ais = AudioSystem.getAudioInputStream(newformat, ais);
                audioformat = newformat;
            }

//checking for a supported output line
            DataLine.Info datalineinfo = new DataLine.Info(SourceDataLine.class, audioformat);
            if (!AudioSystem.isLineSupported(datalineinfo)) {
                //System.out.println("Line matching " + datalineinfo + " is not supported.");
            } else {
                //System.out.println("Line matching " + datalineinfo + " is supported.");
//opening the sound output line
                SourceDataLine sourcedataline = (SourceDataLine) AudioSystem.getLine(datalineinfo);
                sourcedataline.open(audioformat);
                sourcedataline.start();
//Copy data from the input stream to the output data line
                int framesizeinbytes = audioformat.getFrameSize();
                int bufferlengthinframes = sourcedataline.getBufferSize() / 8;
                int bufferlengthinbytes = bufferlengthinframes * framesizeinbytes;
                byte[] sounddata = new byte[bufferlengthinbytes];
                int numberofbytesread = 0;
                while ((numberofbytesread = ais.read(sounddata)) != -1) {
                    int numberofbytesremaining = numberofbytesread;
                    sourcedataline.write(sounddata, 0, numberofbytesread);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Проблема в том, что мойвся программа останавливается до тех пор, пока звуковой файл не будет завершен или, по крайней мере, почти завершен.

Второй метод заключается в следующем:

    File file = new File("Launch1.wav");
    AudioClip clip;
    try {
        clip = JApplet.newAudioClip(file.toURL());
        clip.play();
    } catch (Exception e) {
        e.getMessage();
    }

Проблема, с которой я столкнулся, заключается в том, что каждый раз, когда звуковой файл заканчиваетсярано или не играет вообще, в зависимости от того, где я размещаю код.

Есть ли какой-нибудь способ воспроизвести звук без вышеуказанных проблем?Я делаю что-то неправильно?Любая помощь с благодарностью.

Ответы [ 4 ]

6 голосов
/ 17 января 2011

Для первого метода вы должны создать другую нить для аудио.

Например, например:

new Thread(
            new Runnable() {
                public void run() {
                    try {
                        // PLAY AUDIO CODE
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();

Конечно, вы должны убедиться, что предыдущий звук не все ещеигры.

3 голосов
/ 17 января 2011

Вы должны создать поток, который обрабатывает воспроизведение аудио.Но убедитесь, что он способен микшировать звуки, чтобы два выстрела, следующих друг за другом, могли воспроизводить свои звуки в нужное время, не дожидаясь завершения предыдущего звука.Там должны быть фреймворки, которые будут делать микширование для вас.

Хорошая отправная точка: http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140239.html

3 голосов
/ 17 января 2011

Проблема в том, что вся моя программа останавливается до тех пор, пока звуковой файл не будет завершен или, по крайней мере, почти завершен.

Это кричит о потоке. Вы пытались воспроизвести звук в фоновом потоке? Кстати, это программа Swing? Если это так, используйте SwingWorker для воспроизведения звука. Для этого есть много причин, но одной из основных является то, что легко отслеживать состояние потока с помощью встроенной в SwingWorker поддержки PropertyChangeListener.

3 голосов
/ 17 января 2011

Я полагаю, вам следует запустить свой метод playSound в фоновом потоке, как указано в документе здесь

"Вы, вероятно, захотите вызвать этот цикл воспроизведения в отдельномпоток из остальной части прикладной программы, чтобы ваша программа не зависала при воспроизведении длинного звука "

Может быть, что-то вроде

// shared executor
ExecutorService soundExecutor = ...; //Executors.newSingleThreadExecutor();
...
final File soundFile = ...;
soundExecutor.submit(new Runnable(){
   public void run(){
        SoundUtils.playSoundFile(soundFile);
   }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...