java的同时播放多个剪辑 [英] Java play multiple Clips simultaneously

查看:179
本文介绍了java的同时播放多个剪辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我的应用程序应该我点击面板上的每一次播放WAV文件。但现在的问题是,它会等待第一个完成它扮演的第二个之前。我希望能够让他们同时播放。

So my application should play the WAV file every time I click on the panel. But the problem right now is, it waits for the first one to finish before it plays the second one. I want to be able to have them play simultaneously.

我把视频下载的原因(500)是因为如果我不这样做,那么它不会播放声音在所有:(

The reason I put Thread.sleep(500) is because if I don't, then it won't play the sound at all :(

    import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class SoundEffectPlayer extends JFrame {

    /*
     * Jframe stuff
     */
    public SoundEffectPlayer() {
        this.setSize(400, 400);
        this.setTitle("Mouse Clicker");
        this.addMouseListener(new Clicker());


        this.setVisible(true);
    }

    private class Clicker extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            try {
                playSound(1);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }

    /*
     * Directory of your sound files
     * format is WAV
     */
    private static final String DIRECTORY = "file:///C:/Users/Jessica/Desktop/audio/effects/sound 1.wav";

    /*
     * The volume for sound effects
     */
    public static float soundEffectsVolume = 0.00f;

    /*
     * Loads the sound effect files from cache
     * into the soundEffects array.
     */
    public void playSound(int ID) throws InterruptedException {

        try {
            System.out.println("playing");
            Clip clip;
            URL url = new URL(DIRECTORY);
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
            clip = AudioSystem.getClip();
            clip.open(audioInputStream);
            clip.setFramePosition(0);
            FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
            gainControl.setValue(soundEffectsVolume);

            clip.start();   
            System.out.println("played");
            Thread.sleep(3000);
            System.out.println("closing");

        } catch (MalformedURLException e) {
            System.out.println("Sound effect not found: "+ID);
            e.printStackTrace();
            return;
        } catch (UnsupportedAudioFileException e) {
            System.out.println("Unsupported format for sound: "+ID);
            return;
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }   
    }
    public static void main(String[] args) throws InterruptedException {
        new SoundEffectPlayer();
    }
}

更新:好了,所以我让他们来打simeutaneously,但我想使线程关闭时,剪辑完成打,而不是让线程等待500ms的

Update: Okay so I got them to play simeutaneously, but I want to make the the thread close when the Clip is done playing, instead of making the thread wait 500ms

我怎么能这样做?

推荐答案

我一直运行多个声音是这样的。我猜javaSound已经运行在另一个线程剪辑我不产生新线程。主营游戏循环可能会继续做自己的东西。应用程序可以注册监听回调或使用干将,看看剪辑做。

I have always run multiple sounds like this. I don't spawn a new thread as I guess javaSound already runs clips in an another threads. Main "game loop" may continue doing its own stuff. App may register listeners for callbacks or use getters to see what clips are doing.

有时候,如果我们要使多媒体或游戏应用的更容易只使用干将。运行gameloop 30-60fps给出了大多数情况下足够的粒度和我们发生了什么,当一个总量控制。这个小testapp播放2 wav文件,首先是运行一次,第二个是3秒,第二循环开始后。

Sometimes if we are to make multimedia or game application its easier to just use getters. Running gameloop 30-60fps gives enough granularity for most cases and we have a total control of what happens and when. This little testapp playbacks two wav files, first is run once, second is started after 3sec, second loops.

// java -cp ./classes SoundTest1 clip1=sound1.wav clip2=sound2.wav
import java.util.*;
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;

public class SoundTest1 {

    public Clip play(String filename, boolean autostart, float gain) throws Exception {
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
        Clip clip = AudioSystem.getClip();
        clip.open(audioInputStream);
        clip.setFramePosition(0);

        // values have min/max values, for now don't check for outOfBounds values
        FloatControl gainControl = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN);
        gainControl.setValue(gain);

        if(autostart) clip.start();
        return clip;
    }

//**************************************
    public static void main(String[] args) throws Exception {
        Map<String,String> params = parseParams(args);
        SoundTest1 test1 = new SoundTest1();

        Clip clip1 = test1.play(params.get("clip1"), true, -5.0f);
        Clip clip2 = test1.play(params.get("clip2"), false, 5.0f);

        final long duration=20000;
        final int interval=500;
        for(long ts=0; ts<duration; ts+=interval) {
            System.out.println(String.format("clip1=%d/%d, clip2=%d/%d"
                ,clip1.getFramePosition(), clip1.getFrameLength()
                ,clip2.getFramePosition(), clip2.getFrameLength()
            ));
            if (ts>3000 && !clip2.isRunning()) {
                clip2.setFramePosition(0);
                clip2.start();
            }
            if (!clip1.isRunning()) {
                clip1.close();
            }
            Thread.sleep(interval);
        }
    }

    private static Map<String,String> parseParams(String[] args) {
        Map<String,String> params = new HashMap<String,String>();
        for(String arg : args) {
            int delim = arg.indexOf('=');
            if (delim<0) params.put("", arg.trim());
            else if (delim==0) params.put("", arg.substring(1).trim());
            else params.put(arg.substring(0, delim).trim(), arg.substring(delim+1).trim() );
        }
        return params;
    }

}

这篇关于java的同时播放多个剪辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆