I made a java program and wanted a background music so I used this function
public static void playSound(final String url) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem
.getAudioInputStream(getClass().getResourceAsStream("/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
only problem is when I try to run the 27 minute wav file, it speeds it up really fast
I've been trying to play sound1 and sound2 using AudioClips. This is my code:
import javax.sound.sampled.*;
public class Sound {
private Clip clip;
public static final Sound sound1 = new Sound("src/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("src/Sounds/Classic Horror 3.mp3");
public Sound (String fileName) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(Sound.class.getResource(fileName));
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
public void play() {
try {
if (clip != null) {
new Thread() {
public void run() {
synchronized (clip) {
clip.stop();
clip.setFramePosition(0);
clip.start();
}
}
}.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop(){
if(clip == null) return;
clip.stop();
}
public void loop() {
try {
if (clip != null) {
new Thread() {
public void run() {
synchronized (clip) {
clip.stop();
clip.setFramePosition(0);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
}
}.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isActive(){
return clip.isActive();
}
}
When I try to do Sound.sound1.loop(); or Sound.sound1.play(); I get a null pointer exception. Same goes for sound2. Here are the exact errors messages:
java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidiFileReader.java:207)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:841)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:178)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1147)
at Sound.<init>(Sound.java:12)
at Sound.<clinit>(Sound.java:7)
at IntroductionComponent.<init>(IntroductionComponent.java:54)
at IntroductionGUI.main(IntroductionGUI.java:9)
java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidiFileReader.java:207)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:841)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:178)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1147)
at Sound.<init>(Sound.java:12)
at Sound.<clinit>(Sound.java:8)
at IntroductionComponent.<init>(IntroductionComponent.java:54)
at IntroductionGUI.main(IntroductionGUI.java:9)
I have repeatedly browsed stackoverflow to look for possible fixes, however it may be that fileName returns null constantly, or that my URL's are somehow incorrect. That said, for all I know it could be anything. Any suggestions on how to fix this?
The inclusion of src in your paths...
public static final Sound sound1 = new Sound("src/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("src/Sounds/Classic Horror 3.mp3");
is your key problem, src won't exist once the application is build and package, you should never refer to src ever.
You should probably be using something more like...
public static final Sound sound1 = new Sound("/Sounds/Classic_Horror_2.wav");
public static final Sound sound2 = new Sound("/Sounds/Classic Horror 3.mp3");
public Sound (String fileName) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(getClass().getResource(fileName));
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
Personally, I'd make Sound require a URL...
public Sound (URL url) {
try {
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(ais);
} catch (Exception e) {
e.printStackTrace();
}
}
This way there's no confusion over what String means and you can pass a reference from embedded resources, file references or even from the net
Also from memory, clip.start() creates it's own thread, so there's no need to create your own
I am having trouble stopping one thread and starting another one. I have created two threads. One of them is first run from the main method. It then takes user input and if the desired input is provided, thread one (sound) is supposed to stop and start thread two (sound2). From the code below, thread two does start playing after the correct input is provided during thread one. But thread one does not stop. I can hear audio files from both thread one and thread two playing. Please help.
public class crytask {
public static void main(String args[]) throws InterruptedException {
Runnable sound = new sound();
final Thread soundthread = new Thread(sound);
soundthread.start();
int count = 0;
System.out.println("Enter");
Scanner reader = new Scanner(System.in);
int a = reader.nextInt();
if (a==12)
soundthread.interrupt();
System.out.println("this thread is cancelled");
Runnable sound2 = new sound2();
final Thread soundthread2 = new Thread(sound2);
soundthread2.start();
int count2 = 0;
System.out.println("Enter");
Scanner reader2 = new Scanner(System.in);
int b = reader2.nextInt();
if (b==12)
soundthread2.interrupt();
}}
class sound implements Runnable {
#Override
public void run() {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
System.out.println("Cancelled 1!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
class sound2 implements Runnable {
#Override
public void run() {
try {
AudioInputStream audioInputStream2 = AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream2);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
System.out.println("Cancelled 2!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
Try stopping the clip when the thread is interrupted, adding clip.close() to the catch clause that catches the interruptedException, like this:
class sound implements Runnable {
#Override
public void run() {
Clip clip = null; // take the declaration of the clip variable out of the try - catch
try {
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(new File("/Users/babe/Desktop/Con1.wav").getAbsoluteFile());
clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
Thread.sleep(clip.getMicrosecondLength() / 1000);
} catch(InterruptedException ex) {
clip.stop(); // <--- ADD THIS LINE
System.out.println("Cancelled 1!");
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
}
I am using Java Sound API for creating a Web Application .User Interface(UI) has a button which on click starts recording the speech ,the recorded audio is saved in an audio file (.wav ext) .UI also has a play button which accesses the same audio file and plays the recording back.
Currently I am recording the audio for a specified duration which is hardcoded in my application or getting passed from UI as a parameter while the recording starts.But now the requirement is to stop the recording on click of a button on UI.
Now the issue is while capturing the audio I am opening a targetline using below code :
public void capture(int record_time)
{
try {
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if(!AudioSystem.isLineSupported(info))
{
System.out.println("Line not supported");}
final TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine(info);
targetDataLine.open();
targetDataLine.start();
Thread thread = new Thread()
{
#Override public void run()
{
AudioInputStream audioStream = new AudioInputStream(targetDataLine);
File audioFile = new File(fileName);
System.out.println("Recording is going to get saved in path :::: "+ audioFile.getAbsolutePath());
try{
AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
}
catch (IOException e){
e.printStackTrace();
}
System.out.println("Stopped Recording");
}
};
thread.start();
Thread.sleep(record_time*1000);
targetDataLine.stop();
targetDataLine.close();
System.out.println("Ended recording test");
} catch (LineUnavailableException e) {
System.err.println("Line unavailable: " + e);
System.exit(-2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Above code will stop recording once the record time is elapsed.
But I want another method like below which when invoked from jsp (stop button click) should be able to get the same targetline object which is responsible for current recording and stop the current recording.
Below code does not work for me and recording goes on
public void stop(){
try{
System.out.println("stop :: in stop");
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if(!AudioSystem.isLineSupported(info))
{
System.out.println("Line not supported");}
final TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine(info);
System.out.println("stop Recording....");
System.out.println("targetDataLine.getLineInfo() in stop:::::::"+targetDataLine.getLineInfo());
System.out.println("targetDataLine.isActive() in stop:::::::"+targetDataLine.isActive());
System.out.println("targetDataLine.isOpen() in stop:::::::"+targetDataLine.isOpen());
targetDataLine.stop();
targetDataLine.close();
}
catch (Exception e) {
System.err.println("Line unavailable: " + e);
}
}
Please suggest some resolution.
One more thing that might ..not sure but might has some role to play is the way I am calling these methods from my servlet ..below is the code....
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("buttonName");
String record_time = request.getParameter("time");
System.out.println("action:::"+action +"time in minutes:::"+ record_time);
int record_time_int =(Integer.parseInt(record_time));
String fileName = "studentXYZ.wav";
System.out.println("action:::"+action +"----wavfile:::"+fileName+"time in minutes:::"+ record_time);
Recorder01 record = new Recorder01();
if (action != null && (action.equalsIgnoreCase("Capture")) ){
record.capture(fileName, action,record_time_int);
request.setAttribute("fileName", fileName);
request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);
}
else if (action != null && action.equalsIgnoreCase("play")) {
Recorder01 playsound = new Recorder01();
playsound.play(fileName);
System.out.println("finished playing recording");
request.setAttribute("fileName", fileName);
request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);
}
else if(action!=null && action.equalsIgnoreCase("Stop")){
System.out.println("stop recording called");
record.stop();
request.getRequestDispatcher("/recordAudio.jsp").forward(request, response);
}
}
private TargetDataLine targetDataLine;
public void capture() {
if (targetDataLine == null) {
try {
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line not supported");
}
targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
targetDataLine.open();
targetDataLine.start();
Thread thread = new Thread() {
#Override
public void run() {
AudioInputStream audioStream = new AudioInputStream(targetDataLine);
File audioFile = new File(fileName);
System.out.println("Recording is going to get saved in path :::: " + audioFile.getAbsolutePath());
try {
AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, audioFile);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Stopped Recording");
}
};
thread.start();
} catch (LineUnavailableException e) {
System.err.println("Line unavailable: " + e);
System.exit(-2);
}
}
}
public void stop() {
if (targetDataLine != null) {
System.out.println("stop :: in stop");
targetDataLine.stop();
targetDataLine.close();
targetDataLine = null;
}
}
I have this slightly altered a sound manager from another question How can I play sound in Java?. Here it is:
public static synchronized void playSound(final String url)
{
new Thread(new Runnable()
{
public void run()
{
try
{
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("sound/" + url));
clip.open(inputStream);
clip.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
Whenever I call this method I get a javax.sound.sampled.LineUnavailableException in the clip.open(inputStream);. What can I do to repair it? Why does it not work?