source

자바에서 사운드를 재생하려면 어떻게 해야 하나요?

goodcode 2022. 8. 15. 21:11
반응형

자바에서 사운드를 재생하려면 어떻게 해야 하나요?

프로그램에서 사운드 파일을 재생할 수 있도록 하고 싶습니다.어디를 봐야 하나요?

저는 다음과 같이 정상적으로 동작하는 코드를 작성했습니다.근데 이게 잘 되는 건.wav포맷합니다.

public static synchronized void playSound(final String url) {
  new Thread(new Runnable() {
  // The wrapper thread is unnecessary, unless it blocks on the
  // Clip finishing; see comments.
    public void run() {
      try {
        Clip clip = AudioSystem.getClip();
        AudioInputStream inputStream = AudioSystem.getAudioInputStream(
          Main.class.getResourceAsStream("/path/to/sounds/" + url));
        clip.open(inputStream);
        clip.start(); 
      } catch (Exception e) {
        System.err.println(e.getMessage());
      }
    }
  }).start();
}

나쁜 예:

import  sun.audio.*;    //import the sun.audio package
import  java.io.*;

//** add this into your application code as appropriate
// Open an input stream  to the audio file.
InputStream in = new FileInputStream(Filename);

// Create an AudioStream object from the input stream.
AudioStream as = new AudioStream(in);         

// Use the static class member "player" from class AudioPlayer to play
// clip.
AudioPlayer.player.start(as);            

// Similarly, to stop the audio.
AudioPlayer.player.stop(as); 

단순한 소리만 들려주려고 코드 줄이 그렇게 많은 건 원치 않았어요JavaFX 패키지(jdk 8에 이미 포함되어 있음)가 있으면 이 기능이 작동합니다.

private static void playSound(String sound){
    // cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader();
    URL file = cl.getResource(sound);
    final Media media = new Media(file.toString());
    final MediaPlayer mediaPlayer = new MediaPlayer(media);
    mediaPlayer.play();
}

주의: JavaFX를 초기화해야 합니다.이를 위한 빠른 방법은 JFXPanel()의 컨스트럭터를 앱에서 한 번 호출하는 것입니다.

static{
    JFXPanel fxPanel = new JFXPanel();
}

Java에서 사운드를 재생하려면 다음 코드를 참조할 수 있습니다.

import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;

// To play sound using Clip, the process need to be alive.
// Hence, we use a Swing application.
public class SoundClipTest extends JFrame {

   public SoundClipTest() {
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setTitle("Test Sound Clip");
      this.setSize(300, 200);
      this.setVisible(true);

      try {
         // Open an audio input stream.
         URL url = this.getClass().getClassLoader().getResource("gameover.wav");
         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
         // Get a sound clip resource.
         Clip clip = AudioSystem.getClip();
         // Open audio clip and load samples from the audio input stream.
         clip.open(audioIn);
         clip.start();
      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }
   }

   public static void main(String[] args) {
      new SoundClipTest();
   }
}

어떤 이유로든 wchargin에 의한 상위 응답에서는 이.getClass().getResourceAsStream()을 호출했을 때 늘 포인터 오류가 발생하였습니다.

나에게 효과가 있었던 것은 다음과 같다.

void playSound(String soundFile) {
    File f = new File("./" + soundFile);
    AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL());  
    Clip clip = AudioSystem.getClip();
    clip.open(audioIn);
    clip.start();
}

그리고 저는 그 소리를 다음과 같이 연주합니다.

 playSound("sounds/effects/sheep1.wav");

사운드/효과/음성1wav는 Eclipse에 있는 내 프로젝트의 기본 디렉토리에 있습니다(따라서 src 폴더 내에는 없습니다).

Android와 Desktop에서 작업하기 위해 얼마 전에 게임 프레임워크를 만들었는데, 사운드를 다루는 데스크톱 부분은 필요한 것에 대한 영감을 줄 수 있을 것 같습니다.

https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java

여기 참조용 코드가 있습니다.

package com.athanazio.jaga.desktop.sound;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Sound {

    AudioInputStream in;

    AudioFormat decodedFormat;

    AudioInputStream din;

    AudioFormat baseFormat;

    SourceDataLine line;

    private boolean loop;

    private BufferedInputStream stream;

    // private ByteArrayInputStream stream;

    /**
     * recreate the stream
     * 
     */
    public void reset() {
        try {
            stream.reset();
            in = AudioSystem.getAudioInputStream(stream);
            din = AudioSystem.getAudioInputStream(decodedFormat, in);
            line = getLine(decodedFormat);

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

    public void close() {
        try {
            line.close();
            din.close();
            in.close();
        } catch (IOException e) {
        }
    }

    Sound(String filename, boolean loop) {
        this(filename);
        this.loop = loop;
    }

    Sound(String filename) {
        this.loop = false;
        try {
            InputStream raw = Object.class.getResourceAsStream(filename);
            stream = new BufferedInputStream(raw);

            // ByteArrayOutputStream out = new ByteArrayOutputStream();
            // byte[] buffer = new byte[1024];
            // int read = raw.read(buffer);
            // while( read > 0 ) {
            // out.write(buffer, 0, read);
            // read = raw.read(buffer);
            // }
            // stream = new ByteArrayInputStream(out.toByteArray());

            in = AudioSystem.getAudioInputStream(stream);
            din = null;

            if (in != null) {
                baseFormat = in.getFormat();

                decodedFormat = new AudioFormat(
                        AudioFormat.Encoding.PCM_SIGNED, baseFormat
                                .getSampleRate(), 16, baseFormat.getChannels(),
                        baseFormat.getChannels() * 2, baseFormat
                                .getSampleRate(), false);

                din = AudioSystem.getAudioInputStream(decodedFormat, in);
                line = getLine(decodedFormat);
            }
        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        }
    }

    private SourceDataLine getLine(AudioFormat audioFormat)
            throws LineUnavailableException {
        SourceDataLine res = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class,
                audioFormat);
        res = (SourceDataLine) AudioSystem.getLine(info);
        res.open(audioFormat);
        return res;
    }

    public void play() {

        try {
            boolean firstTime = true;
            while (firstTime || loop) {

                firstTime = false;
                byte[] data = new byte[4096];

                if (line != null) {

                    line.start();
                    int nBytesRead = 0;

                    while (nBytesRead != -1) {
                        nBytesRead = din.read(data, 0, data.length);
                        if (nBytesRead != -1)
                            line.write(data, 0, nBytesRead);
                    }

                    line.drain();
                    line.stop();
                    line.close();

                    reset();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

애플릿과 어플리케이션 모두에서 동작하는 사운드 파일을 Import 하는 대신 오디오 파일을 .java 파일로 변환하여 코드로 사용하는 방법이 있습니다.

저는 이 과정을 훨씬 쉽게 할 수 있는 도구를 개발했습니다.Java Sound API를 상당히 단순화합니다.

http://stephengware.com/projects/soundtoclass/

애플릿 사용을 제안하지 않았다니 놀랍네요.사용 Applet. 비프음 오디오 파일을 로서 제공해야 합니다.wav파일, 하지만 작동해요.Ubuntu에서 해봤는데

package javaapplication2;

import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

public class JavaApplication2 {

    public static void main(String[] args) throws MalformedURLException {
        File file = new File("/path/to/your/sounds/beep3.wav");
        URL url = null;
        if (file.canRead()) {url = file.toURI().toURL();}
        System.out.println(url);
        AudioClip clip = Applet.newAudioClip(url);
        clip.play();
        System.out.println("should've played by now");
    }
}
//beep3.wav was available from: http://www.pacdv.com/sounds/interface_sound_effects/beep-3.wav

저는 좋아요.단순 변종

public void makeSound(){
    File lol = new File("somesound.wav");
    

    try{
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(lol));
        clip.start();
    } catch (Exception e){
        e.printStackTrace();
    }
}

이 스레드는 다소 오래되었지만 도움이 될 수 있는 옵션을 결정했습니다.

Java를 사용하는 대신AudioStream라이브러리는 Windows Media Player나 VLC와 같은 외부 프로그램을 사용하여 Java를 통해 콘솔 명령으로 실행할 수 있습니다.

String command = "\"C:/Program Files (x86)/Windows Media Player/wmplayer.exe\" \"C:/song.mp3\"";
try {
    Process p = Runtime.getRuntime().exec(command);
catch (IOException e) {
    e.printStackTrace();
}

이를 통해 프로그램을 제어할 수 있는 별도의 프로세스도 생성됩니다.

p.destroy();

물론 이 작업은 내부 라이브러리를 사용하는 것보다 시간이 더 걸리지만 특정 콘솔명령어를 사용하면 GUI 없이 더 빨리 시작할 수 있는 프로그램이 있을 수 있습니다.

만약 시간이 중요하지 않다면, 이것은 유용하다.

mp3 파일 형식을 재생하는 데 많은 문제가 있어서 온라인 컨버터를 사용하여 .wav로 변환했습니다.

그 후 아래 코드를 사용합니다(mp3를 지원하는 대신 더 쉬웠습니다).

try
{
    Clip clip = AudioSystem.getClip();
    clip.open(AudioSystem.getAudioInputStream(GuiUtils.class.getResource("/sounds/success.wav")));
    clip.start();
}
catch (Exception e)
{
    LogUtils.logError(e);
}
import java.net.URL;
import java.net.MalformedURLException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.IOException;
import java.io.File;
public class SoundClipTest{
    //plays the sound
    public static void playSound(final String path){
        try{
            final File audioFile=new File(path);
            AudioInputStream audioIn=AudioSystem.getAudioInputStream(audioFile);
            Clip clip=AudioSystem.getClip();
            clip.open(audioIn);
            clip.start();
            long duration=getDurationInSec(audioIn);
            //System.out.println(duration);
            //We need to delay it otherwise function will return
            //duration is in seconds we are converting it to milliseconds
            Thread.sleep(duration*1000);
        }catch(LineUnavailableException | UnsupportedAudioFileException | MalformedURLException | InterruptedException exception){
            exception.printStackTrace();
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
    }
    //Gives duration in seconds for audio files
    public static long getDurationInSec(final AudioInputStream audioIn){
        final AudioFormat format=audioIn.getFormat();
        double frameRate=format.getFrameRate();
        return (long)(audioIn.getFrameLength()/frameRate);
    }
    ////////main//////
    public static void main(String $[]){
        //SoundClipTest test=new SoundClipTest();
        SoundClipTest.playSound("/home/dev/Downloads/mixkit-sad-game-over-trombone-471.wav");
    }
}

언급URL : https://stackoverflow.com/questions/26305/how-can-i-play-sound-in-java

반응형