I am trying to play a simple audio file which is in the same directory near the class file. I tried many examples from the internet, but all the others gave me errors which I couldn't even understand.
Then I found this, and I am using it now.
There are neither compile errors nor runtime errors. But the problem is I cannot hear any noise.
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
class A{
public static void main (String[]args){
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("abc.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch(Exception ex) {
System.out.println("Error with playing sound.");
}
}
}
Please note that my system volume is 80%, and the audio file plays in VLC media player.
Starting the audio clip does not block the main method. So
clip.start();
starts playing and then returns. Now your main method ends and therefore the Java process ends. No sound.
If you do
clip.start();
Thread.sleep(20000);
you should hear the clip playing for 20 seconds.
So for a working program just must make sure that the main thread does not end as long as you want to play the clip.
Hold the thread for a while until the audio clip plays.
long audioPlayTime = 1000; //clip duration in miliseconds.
try {
Thread.sleep(audioPlayTime);
} catch (InterruptedException ex){
//TODO
}
Related
I tried to play some sounds using the javax.sound.sampled package, when I encountered a strange residual beeping sound right after the clip ends. I am playing back four different audio files and the other three are working fine. I can not find a reason, why it is making this sound. Just to clarify, I checked the audio file in a editor and the beeping noise is not showing up and therefore has to be caused by Java. The following code is used to play the sounds (I am having trouble with case 1):
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class SoundHandler implements SoundConstants{
URL url;
public SoundHandler() {
url = this.getClass().getResource("/sounds3.wav");
}
public void playSound(int sound) {
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(url));
clip.setFramePosition(0);
clip.start();
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
}
Trying to loop an audio clip. Look right but i hear nothing.
Does local audio clip have to have the extension ".au"? or can i play aiff, mp3 or wav for example?
I'm really sorry if this is not properly explaned. I'm really new to this.
Tried to play sounds on my hard drive (.wav) (put in the same folder as my java program) AND of the internet.
An input dialog pops up and asks for an audio clip. Works fine. Here the user is supposed to write either a local file name or a web address.
I write (for local files) "file:myAudioclip.wav" or (for internet) "https://www....) but nothing plays.
import java.applet.*; //Importerar necessary packages
import java.net.*;
import javax.swing.*;
public class AudioClip2 {
public static void main(String[] args) throws
MalformedURLException, InterruptedException {
// Handling errors
String filnamn = JOptionPane.showInputDialog("Audio clip?");
// This is where I write what clip I wanna play
URL u = new URL(filnamn);
// Create a URL for my clip
AudioClip a = Applet.newAudioClip(u);
a.loop();
//Looping AudioClip a
Thread.sleep(10000); //Create a paus (ignore)
}
}
I have been following this tutorial for Java 1.7 and I am sure I have the code right. However, Java throws an IllegalArgumentException at runtime.
I've tried to catch it in an existing catch block, using Java's slightly-newer multi-catch. However, it simply throws exceptions.
Here is the beginning of my code.
Mixer.Info[] mixInfos = AudioSystem.getMixerInfo();
/*
for (Mixer.Info info : mixInfos)
{
System.out.println(info.getName() + " - " + info.getDescription());
}
*/
mixer = AudioSystem.getMixer(mixInfos[0]);
DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
try
{
clip = (Clip) mixer.getLine(dataInfo);
}
I expect that the code will continue running and play the Clip but I get this exception:
Exception in thread "main" java.lang.IllegalArgumentException: Line unsupported: interface Clip
at java.desktop/com.sun.media.sound.PortMixer.getLine(PortMixer.java:131)
at main.Driver.main(Driver.java:35)
Note: If this isn't forward compatible, please explain.
I think you should check your imports. AFAIK, the libraries for sound are all in javax.sound.sampled. The PortMixer is in com.sun.media.sound.
The author of the tutorial is going to a lot more trouble than is necessary. Instead of hardcoding a specific Mixer, you can just let the system pick defaults. This is probably the best strategy, as PC's out in the world are going to have diverse hardware configurations.
Following is an example that might be helpful. Notice that we don't even bother to declare a Mixer.
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class BasicClipExample {
public static void main(String[] args) {
BasicClipExample bc = new BasicClipExample();
try {
bc.run();
} catch (UnsupportedAudioFileException | IOException
| LineUnavailableException | InterruptedException e) {
e.printStackTrace();
}
}
private void run() throws UnsupportedAudioFileException,
IOException, LineUnavailableException, InterruptedException
{
String filename = "a3.wav";
URL url = this.getClass().getResource("audio/" + filename);
System.out.println(url);
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
Thread.sleep(6000);
clip.close();
}
}
This example assumes that your audio file is in a subdirectory called "/audio".
It also has a sleep command to keep the program running while the Clip is playing. Clips run under their own thread, but the thread is a "daemon" type and will not prevent a Java program from closing. My a3.wav is a recording of a bell that happens to last about 5 seconds.
Last thing, the above code does not use a Clip in the ideal fashion. The concept of a Clip is that it is for re-use. Reloading the clip variable before playing it each time it is played is inefficient. The clip variable should be loaded only once, and then played on demand. If you have clip.open() and clip.start() as contiguous lines of code, you should probably either be using a SourceDataLine instead of a Clip, or you should recode and put the two commands into separate methods.
I've been rampaging about for a couple of hours now looking for sample code that can play simple wav files in Java. However, none of the ones I've received are working for me. Maybe it's just me that doesn't understand how to operate the sample code but could anyone provide me with sample code and "instructions" on how to get it working correctly. Any help would be much appreciated.
This code will create a clip and play it continuously once started:
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new URL(filename)));
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);
There are more modern ways to do this, but the applet class AudioClip might satisfy your needs:
import java.applet.Applet;
import java.applet.AudioClip;
final AudioClip clip = Applet.newAudioClip(resourceUrl);
To play it once:
clip.play();
To loop:
clip.loop();
clip.stop();
See Javadocs for Applet and AudioClip
getAudioClip
public AudioClip getAudioClip(URL url)
Returns the AudioClip object specified by the URL argument.
This method always returns immediately, whether or not the audio clip exists. When this applet attempts to play the audio clip, the data will be loaded.
Parameters:
url - an absolute URL giving the location of the audio clip.
Returns:
the audio clip at the specified URL.
You don't need to actually be doing anything with applets for this to work. It will work fine in a regular Java application.
import java.io.File;
import javax.sound.sampled.*;
public void play(File file)
{
try
{
final Clip clip = (Clip)AudioSystem.getLine(new Line.Info(Clip.class));
clip.addLineListener(new LineListener()
{
#Override
public void update(LineEvent event)
{
if (event.getType() == LineEvent.Type.STOP)
clip.close();
}
});
clip.open(AudioSystem.getAudioInputStream(file));
clip.start();
}
catch (Exception exc)
{
exc.printStackTrace(System.out);
}
}
I have a number of .wav files I play from Java. In this stripped down example, "drip" is audible but "swish" is not even though they run via the same code. There does not seem to be anything unusual about "swish": it plays from the Gnome desktop. I have a similar app, not quite as stripped down that plays "swish" but not "drip" so again it does not seem to be a problem tied to the nature of the data.
Any ideas what is happening here? This bug was noticed after code that was known to be working was "redeployed" on a rebuilt system: reinstalled Ubuntu 10.10 and Eclipse Indigo. This bug happens with both Sun JDK 6 and OpenJDK 6. Edit The "rebuilt" system is actually different hardware as well: Intel E6500 (2 cores, 2.93 GHz) I have only installed Ubuntu, Eclipse, OpenJDK, Sun JDK. The previous system was an AMD 630 (4 cores, 2.8 GHz) with Ubuntu, Eclipse, OpenJDK (I think).
Edit After some experimenting, it seems the first clip loaded will be the one that works. The TestSounder constructor loads them so that is where the order can be reversed. Perhaps the use of the static method AudioSystem.getLine has something to do with it since that is obviously the non-object oriented operation here.
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Clip;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.LineUnavailableException;
public class TestSounder
{
String resourcePathFromBin = "/resources/";
Clip dripClip;
Clip swishClip;
public TestSounder()
{
dripClip = setupClip("drip.wav");
swishClip = setupClip("swish.wav");
}
public void close()
{
dripClip.close();
swishClip.close();
}
private Clip setupClip(String fileName)
{
Clip clip = null;
try
{
AudioInputStream ais =
AudioSystem.getAudioInputStream(this.getClass().getResourceAsStream(resourcePathFromBin +
fileName));
AudioFormat af = ais.getFormat();
DataLine.Info lineInfo = new DataLine.Info(Clip.class, af);
clip = (Clip)AudioSystem.getLine(lineInfo);
clip.open(ais);
}
catch (UnsupportedAudioFileException e)
{
assert false: "bug";
}
catch (IOException e)
{
assert false: "bug";
}
catch (LineUnavailableException e)
{
assert false: "bug";
}
return clip;
}
public void go(UtilityK.Sounds s)
{
Clip clip = null;
if (s == UtilityK.Sounds.drip)
clip = dripClip;
if (s == UtilityK.Sounds.swish)
clip = swishClip;
clip.stop();
clip.setFramePosition(0);
clip.start();
//while (clip.isRunning())
// TestSounder.delay();
}
public static void main(String[] args)
{
TestSounder obj = new TestSounder();
obj.go(UtilityK.Sounds.swish);
TestSounder.delay();
obj.go(UtilityK.Sounds.drip);
TestSounder.delay();
obj.go(UtilityK.Sounds.swish);
TestSounder.delay();
obj.go(UtilityK.Sounds.drip);
TestSounder.delay();
obj.close();
}
private static void delay()
{
Thread.sleep(5000);
}
}
public interface UtilityK
{
enum Sounds { drip, swish };
}
Here is an alternative approach. It seems well suited to short sounds that might need to be played often or in quick succession as user feedback.
link to a way to play two kinds of beeps that come from .wav files