I want just to perform a simple task. (I'm a java newbie). I want to play an audio clip when a button is clicked.
here's the part of my code(which I did exactly by copying a tutorial from Youtube.)
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {
InputStream in;
try{
in=new FileInputStream(new File("C:\\Users\\Matt\\Documents\\dong.wav"));
AudioStream timeupsound=new AudioStream(in);
AudioPlayer.player.start(timeupsound);
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
But the problem is, this doesn't work.
It throws and IOException saying: "could not create audio stream from input stream".
My question is, what am I doing wrong? (as I clearly saw this code work in that youtube video, and I've used the same code. Please help. and once again, I'm a newbie);
The sun package classes should be causing some informative warnings at compile time. Heed them. Don't use classes in that package hierarchy. They are undocumented, are not guaranteed from one Java version to the next, and will probably not be available in a non-Oracle JRE at all.
Instead use the Java Sound based Clip to play audio. See the info. page for working examples.
Note
It might be the WAV is encoded in a format that Java Sound does not support. Media formats are typically 'container formats' that might be encoded using any number of different Codecs. It is likely that WAV is using a more compressive Codec such as MP3 or OGG internally.
I don't know of a Service Provider Interface for the OGG format, but if they are encoded as MP3, you might be able to get it working using the MP3 SPI. See the info. page linked above for details.
Tip
Also change code of the form:
catch (Exception e) { ..
To
catch (Exception e) {
e.printStackTrace(); // very informative! ...
Related
This question already has an answer here:
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file when loading wav file
(1 answer)
Closed 8 years ago.
I want to play a audio clip from my computer while a game is playing. But i can only use very very short sounds. Is there any similar way to playing songs like i play sound effects?
Im using swing graphics for the game if that matters.
The error i get when i try to use a song
"javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file"
public static void main(String args[]) {
Sound s = new Sound();
s.playSound("C:/Users/isac/Desktop/banjos.wav");
}
}
public void playSound(String file) {
try {
AudioInputStream audio = AudioSystem.getAudioInputStream(new File(
file));
Clip clip = AudioSystem.getClip();
clip.open(audio);
clip.start();
}
catch (UnsupportedAudioFileException uae) {
System.out.println(uae);
} catch (IOException ioe) {
System.out.println(ioe);
} catch (LineUnavailableException lua) {
System.out.println(lua);
}
}
}
The error message you are getting indicates the problem is probably with the format of the file, not its length.
You can check the format of an audio file by looking at it's properties--usually requires a right click on Windows. The properties that matter may be on an "Advanced" tab. Java can read many formats, but where I've most often seen it hang up is with the following:
a person tries to load a .mp3 or .ogg or other form of compression but hasn't implemented any libraries that can decompress those files (not your situation, since your banjo.wav is a wav).
the .wav is not the standard "CD Quality" format (44100 fps, 16-bit encoding, stereo) but rather something like 24-bit or 32-bit encoding or 48000 or 96000 fps.
Current DAWs often make it easy to record in formats that are superior to "CD Quality" but Java doesn't support them yet.
For the most part, you can convert audio files that are not readable with Java to one that is with Audacity (free), if you aren't working from another home studio program. Be careful where you obtain Audacity as some sites that provide it (other than the official site) will include adware or malware or viruses.
As a side note, for a longer file, it would be better to load into a SourceDataLine for playback instead of a Clip. With a SourceDataLine, you don't have to wait for the entire file to load before it will start playing back, and it won't take up anywhere near as much RAM. The Java Tutorials has a section for Java Sound and a page there specifically on playback.
I am working on sound code for a game. And I was using the following code:
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
/**
* This enum encapsulates all the sound effects of a game, so as to separate the sound playing
* codes from the game codes.
* 1. Define all your sound effect names and the associated wave file.
* 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
* 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
* sound files, so that the play is not paused while loading the file for the first time.
* 4. You can use the static variable SoundEffect.volume to mute the sound.
*/
public enum SoundEffect {
EXPLODE("explode.wav"), // explosion
GONG("gong.wav"), // gong
SHOOT("shoot.wav"); // bullet
// Nested class for specifying volume
public static enum Volume {
MUTE, LOW, MEDIUM, HIGH
}
public static Volume volume = Volume.LOW;
// Each sound effect has its own clip, loaded with its own sound file.
private Clip clip;
// Constructor to construct each element of the enum with its own sound file.
SoundEffect(String soundFileName) {
try {
// Use URL (instead of File) to read from disk and JAR.
URL url = this.getClass().getClassLoader().getResource(soundFileName);
// Set up an audio input stream piped from the sound file.
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
// Get a clip resource.
clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioInputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
// Play or Re-play the sound effect from the beginning, by rewinding.
public void play() {
if (volume != Volume.MUTE) {
if (clip.isRunning())
clip.stop(); // Stop the player if it is still running
clip.setFramePosition(0); // rewind to the beginning
clip.start(); // Start playing
}
}
// Optional static method to pre-load all the sound files.
static void init() {
values(); // calls the constructor for all the elements
}
}
Now when I replace one of the listed *.wav files from the code with my own or even name one of my own to the file name listed from the above code. I receive the follow error:
Exception in thread "main" java.lang.ExceptionInInitializerError
at soundTest.main(soundTest.java:19)
Caused by: java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(Unknown Source)
at javax.sound.midi.MidiSystem.getSequence(Unknown Source)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at SoundEffect.<init>(sfx.java:75)
at SoundEffect.<clinit>(sfx.java:55)
From following the stack URL url is null going in, which is telling me the *.wav file itself is not being read.
I have tried the following lines and yes the *.wav file was present (I am aware that I cannot have three items named the same, I've used one played with it, then commented it out and try again with another one, I just removed the "//" to make is easier to read):
TEST("file://C:/shoot.wav");
TEST("/soundTest/shoot.wav");
TEST("shoot.wav");
As well as, placing a copy of the file in the directory with the package (default), in the src folder, and of course in the root (c:).
How I am envoking the enum is in my main statement where it is all the standard java, main code but with:
SoundEffect.SHOOT.play();
Where exactly does the *.wav file need to be at int he directory? Or if there is another issue I am missing please point it out. I am also using the Eclipse IDE "Kepler," on Windows 8.1. I would like to note the posted code is all I have thus far.
There is some discussion in the comments that Eclipse might be the problem. I seriously doubt Eclipse is the problem. I have loaded hundreds of audio files using Eclipse. Usually I put the files in a sub-directory "audio" that is one level below the calling code, and use the relative address form: "audio/mySound.wav".
Here is how I load my URL:
URL url = this.getClass().getResource("audio/" & fileName);
I am puzzled as to why there are MIDI references in your stack trace. MIDI has nothing to do with loading .wav files, and really should not be involved at all. Are you sure this is the correct stack trace? Why are we seeing references to MIDI?
Sometimes an unrecognizable .wav file format will throw unexpected errors. The most common .wav is 16-bit encoding, 44100 bps, stereo, little-endian. Are your .wav files of this format?
There are some aspects of your code that I haven't seen implemented in this manner, particularly the use of ENUMS. I'll take your word all that has been tested and verified. I tend to just name individual sound objects (using a wrapper for wav files with Clip or SourceDataLine for playback) and use them that way. Could be what you have with that is a good organizational tool, but I'm not clear if it is working as intended.
For example, with Static use of SoundEffect, as in SoundEffect.SHOOT.play(), are you sure it is pointing to the shoot.wav? Have you written a test to verify this? Combining ENUMS and static invocations--it's getting a little tricky for me to follow.
I'm using JAAD with SPI to play m4a files through JavaSound, which I have working fine.
However, I'd like to support a number of formats in this way - but whenever I try and play another format, JAAD seems to try to deal with it and then fail (obviously because it only deals with AAC.)
I'm assuming this is a bug in JAAD, since all the other SPI libraries play fine with each other. Is there a nice way to work around it until it's fixed, or is there another AAC library that works with Javasound which I can use?
There is a workaround using jaad created by Michael Berry: this is the url
https://code.google.com/p/quelea-projection/source/browse/Quelea/src/org/quelea/sound/AudioTrack.java?spec=svn0352523f49cf20d41d1a7dc098af1db38000cc6d&r=0352523f49cf20d41d1a7dc098af1db38000cc6d
Since it took me a while to find berry150's code, here is the solution:
First, you have to order the jars in the classpath so that JLayer, MP3SPI and Tritonous Share are loaded before JAAD. Then for getting the AudioInputStream, use the following code:
if (getAudioFormat().equals(".mp3")) {
audioStream = AudioSystem.getAudioInputStream(file); // Obtains an audio input stream of the song
}
else if (getAudioFormat().equals(".m4a")){
audioStream = new AACAudioFileReader().getAudioInputStream(file);
}
So what happens is that if the audio is mp3, the getAudioStreamMethod() from Javasound will be called first since its JAR was loaded first. If the audio is .m4a, a new instance of the ACCAudioFileReader() is created and the getAudioInputStream() of the JAAD library is called.
I am trying to run a sound file in Java using this code:
public class Audio3
{
public static void main(String[] args) throws Exception
{
URL soundFile =new URL(
"http://everyayah.com/data/Ghamadi_40kbps/audhubillah.mp3");
AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
AudioPlayer.player.start(ais);
}
}
I am getting this exception
javax.sound.sampled.UnsupportedAudioFileException:
could not get audio input stream from input URL
Any idea what could be the reason?
According to the JavaSound info. page.
MP3 decoding support
The Java Sound API does not support many formats of sampled sound internally. In a 1.6.0_24 Oracle JRE getAudioFileTypes() will generally return {WAVE, AU, AIFF}. An MP3 decoder at least, is close by. The mp3plugin.jar of the Java Media Framework supports decoding MP3s.
I can vouch for that information since I've successfully loaded MP3s using Java Sound and the MP3 SPI (& also wrote the info. page ;) ). The JMF installer download is becoming hard to find, but you can get the mp3plugin.jar direct from where I put it for use in JWS apps.
I tried both of the following options:
1.
BufferedImage Buffered_Image;
MemoryCacheImageOutputStream MemoryCache_OutputStream =
new MemoryCacheImageOutputStream(new FileOutputStream("C:/Test.mov",false));
while (notFinished) // Main recording loop.
{
Buffered_Image=robot.createScreenCapture(); // Capture Screen image.
try { ImageIO.write(Buffered_Image,"png",MemoryCache_OutputStream); }
catch (Exception e) { e.printStackTrace(); }
}
2.
BufferedImage Buffered_Image;
ImageWriter writer;
try
{
ImageOutputStream ios=ImageIO.createImageOutputStream(new File("C:/Test.mov"));
Iterator writers=ImageIO.getImageWritersByFormatName("png");
while (writers.hasNext())
{
writer=(ImageWriter)writers.next();
writer.setOutput(ios);
Out(writer.toString()+" canInsertImage : "+writer.canInsertImage(0));
// Got this: com.sun.imageio.plugins.png.PNGImageWriter#19fcc69
// canInsertImage : false
}
}
catch (Exception e) { }
cntPics=0;
while (notFinished) // Main recording loop.
{
Buffered_Image=robot.createScreenCapture(); // Capture Screen image.
writer.write(null,new IIOImage(Buffered_Image,null,null),null);
if (writer.canInsertImage(-1)) {
// Append image at highest index
writer.writeInsert(-1,new IIOImage(Buffered_Image,null,null),null);
} else Out("Writer can’t append image Id : "+cntPics);
cntPics++;
}
Neither of them worked, what's the correct way to save multiple PNG images to a file?
Edit:
You are right, I found a java program called Krut that can record screen sessions, but it uses JPEGImageEncoder, the image quality isn't as good as I want, so I wonder if I can use ImageIO to encode the sequence.
If ImageIO can't do it, my next question would be is there a stand alone open source PNGImageEncoder that I can use to encode it? I know there are open source PNGImageEncoders, but they tend to be tangled in projects and hard to get all the supporting files out of it, any ideas? Thanks!
It looks like you're trying to create a video (MOV) file by writing multiple PNG files in a row. This isn't going to work. You'll probably have to find a third-party library for encoding your images into a video file (which is itself may be a good SO question).
EDIT: I should also note that you may actually be able to get video by writing multiple JPG images in a row to get a form of MJPEG (Motion JPEG) but for other formats such as MOV you're going to need an actual encoder.
What are you trying to do? Re-inventing MNG? Even if you can write multiple PNG images in the same file, it makes a compound file understood by no program (except those you might write).
If, as suggested by Marc, you want to make a movie, you might want to look at QuickTime for Java (QTJava). It is the solution used by Processing to make movies out of animations/frames. It has several quality/formats, from the worst (but small files) to the highest quality (high file sizes as result).