ฉันต้องการเล่นไฟล์เสียงในโปรแกรมของฉัน ฉันควรมองที่ไหน
ฉันต้องการเล่นไฟล์เสียงในโปรแกรมของฉัน ฉันควรมองที่ไหน
คำตอบ:
ฉันเขียนโค้ดต่อไปนี้ซึ่งใช้งานได้ดี แต่ฉันคิดว่ามันใช้ได้กับ.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();
}
Thread
ไม่จำเป็น 2) เพื่อเป็นตัวอย่างที่ดีในการใช้Clip
งานโปรดดูข้อมูล JavaSound หน้า 3) หากวิธีการนั้นต้องการURL
(หรือFile
) ให้มันเป็น Dang URL
(หรือFile
) แทนที่จะยอมรับวิธีString
นั้นแทน (เพียงแค่ 'ผึ้งในฝากระโปรงของฉันส่วนบุคคล.) 4) ให้ข้อมูลเพิ่มเติมกับการพิมพ์น้อยกว่าe.printStackTrace();
System.err.println(e.getMessage());
ตัวอย่างที่ไม่ดี:
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();
}
สำหรับการเล่นเสียงในภาษาจาวาคุณสามารถดูรหัสต่อไปนี้
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 ทำให้ฉันมีข้อผิดพลาดตัวชี้โมฆะเมื่อฉันเรียก this.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");
sounds / effects / sheep1.wav ตั้งอยู่ในไดเรกทอรีฐานของโครงการของฉันใน Eclipse (ดังนั้นไม่ควรอยู่ในโฟลเดอร์ src)
getResourceAsStream()
จะกลับมาnull
หากไม่พบทรัพยากรหรือโยนข้อยกเว้นถ้าname
เป็นnull
- ไม่ใช่ความผิดของคำตอบสูงสุดหากเส้นทางที่กำหนดไม่ถูกต้อง
ฉันสร้างกรอบเกมขึ้นเมื่อไม่นานมานี้เพื่อทำงานบน Android และเดสก์ท็อปส่วนเดสก์ท็อปที่จัดการกับเสียงอาจใช้เป็นแรงบันดาลใจในสิ่งที่คุณต้องการ
นี่คือรหัสสำหรับการอ้างอิง
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();
}
}
}
stream.reset();
Resetting to invalid mark
คุณเสนอให้แก้ไขสิ่งนี้อย่างไร
raw.mark(raw.available()+1)
หลังจาก initialising raw
และจากนั้นในขณะที่ห่วงแล้วใช้แทนraw.reset()
stream.reset()
ปัญหาของฉันตอนนี้คือเมื่อมันมาถึงการตั้งค่าใหม่มีช่องว่างระหว่างการเล่น Clip
ฉันต้องการที่จะประสบความสำเร็จในวงอย่างต่อเนื่องเช่นที่คุณได้รับ ฉันไม่ได้ใช้Clip
เพราะการควบคุมการควบคุมเช่น MASTER_GAIN มีความล่าช้าอย่างเห็นได้ชัด ~ 500ms นี่อาจเป็นคำถามของตัวเองที่ฉันจะถามต่อไป
do { ... } while
หรือ
มีทางเลือกอื่นในการนำเข้าไฟล์เสียงที่ใช้งานได้ทั้งในแอพเพล็ตและแอพพลิเคชั่น: แปลงไฟล์เสียงเป็นไฟล์. java และใช้ในรหัสของคุณ
ฉันได้พัฒนาเครื่องมือที่ทำให้กระบวนการนี้ง่ายขึ้นมาก มันทำให้ Java Sound API ง่ายขึ้นเล็กน้อย
ฉันประหลาดใจที่ไม่มีใครแนะนำให้ใช้แอปเพล็ต ใช้ 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
Applet
เลิกใช้แล้วตั้งแต่วันที่ Java 9
เธรดนี้ค่อนข้างเก่า แต่ฉันได้พิจารณาตัวเลือกที่สามารถพิสูจน์ได้ว่ามีประโยชน์
แทนที่จะใช้AudioStream
ไลบรารีJava คุณสามารถใช้โปรแกรมภายนอกเช่น 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 ที่ให้คำสั่งคอนโซลบางอย่าง
หากเวลาไม่เป็นสาระสำคัญนี่จะเป็นประโยชน์