Playing sound in a Java Desktop application - java

How do we play sound (a music file of any format like .wma, .mp3 ) in a Java desktop application? (not an applet)
I have used the following code (taken from another question on Stack Overflow) but it throws an Exception.
public class playsound {
public static void main(String[] args) {
s s=new s();
s.start();
}
}
class s extends Thread{
public void run(){
try{
InputStream in = new FileInputStream("C:\\Users\\srgf\\Desktop\\s.wma");
AudioStream as = new AudioStream(in); //line 26
AudioPlayer.player.start(as);
}
catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
}
The program when run throws the following Exception:
java.io.IOException: could not create audio stream from input stream
at sun.audio.AudioStream.<init>(AudioStream.java:82)
at s.run(delplaysound.java:26)

Use this library:
http://www.javazoom.net/javalayer/javalayer.html
public void play() {
String song = "http://www.ntonyx.com/mp3files/Morning_Flower.mp3";
Player mp3player = null;
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new URL(song).openStream());
mp3player = new Player(in);
mp3player.play();
} catch (MalformedURLException ex) {
} catch (IOException e) {
} catch (JavaLayerException e) {
} catch (NullPointerException ex) {
}
}
Hope that helps everyone with a similar question :-)

Hmmm. This might look like advertisement for my stuff, but you could use my API here:
https://github.com/s4ke/HotSound
playback is quite easy with this one.
Alternative: use Java Clips (prebuffering)
... code ...
// specify the sound to play
File soundFile = new File("pathToYouFile");
//this does the conversion stuff for you if you have the correct SPIs installed
AudioInputStream inputStream =
getSupportedAudioInputStreamFromInputStream(new FileInputStream(soundFile));
// load the sound into memory (a Clip)
DataLine.Info info = new DataLine.Info(Clip.class, inputStream.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
// due to bug in Java Sound, explicitly exit the VM when
// the sound has stopped.
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
event.getLine().close();
System.exit(0);
}
}
});
// play the sound clip
clip.start();
... code ...
Then you need this method:
public static AudioInputStream getSupportedAudioInputStreamFromInputStream(InputStream pInputStream) throws UnsupportedAudioFileException,
IOException {
AudioInputStream sourceAudioInputStream = AudioSystem
.getAudioInputStream(pInputStream);
AudioInputStream ret = sourceAudioInputStream;
AudioFormat sourceAudioFormat = sourceAudioInputStream.getFormat();
DataLine.Info supportInfo = new DataLine.Info(SourceDataLine.class,
sourceAudioFormat,
AudioSystem.NOT_SPECIFIED);
boolean directSupport = AudioSystem.isLineSupported(supportInfo);
if(!directSupport) {
float sampleRate = sourceAudioFormat.getSampleRate();
int channels = sourceAudioFormat.getChannels();
AudioFormat newFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate,
16,
channels,
channels * 2,
sampleRate,
false);
AudioInputStream convertedAudioInputStream = AudioSystem
.getAudioInputStream(newFormat, sourceAudioInputStream);
sourceAudioFormat = newFormat;
ret = convertedAudioInputStream;
}
return ret;
}
Source for the Clip example (with little changes by me): http://www.java2s.com/Code/Java/Development-Class/AnexampleofloadingandplayingasoundusingaClip.htm
SPIs are added via adding their .jars to the classpath
for mp3 these are:
http://www.javazoom.net/mp3spi/mp3spi.html
http://www.javazoom.net/javalayer/javalayer.html
http://www.tritonus.org/plugins.html (tritonus_share.jar)

Using JavaFX (which is bundled with your JDK) is pretty simple.
You will need the following imports:
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import java.nio.file.Paths;
Steps:
Initialize JavaFX:
new JFXPanel();
Create a Media (sound):
Media media = new Media(Paths.get(filename).toUri().toString());
Create a MediaPlayer to play the sound:
MediaPlayer player = new MediaPlayer(media);
And play the Media:
player.play();
You can set the start/stop times as well with MediaPlayer.setStartTime() and MediaPlayer.setStopTime():
player.setStartTime(new Duration(Duration.ZERO)); // Start at the beginning of the sound file
player.setStopTime(1000); // Stop one second (1000 milliseconds) into the playback
Or, you can stop playing with MediaPlayer.stop().
A sample function to play audio:
public static void playAudio(String name, double startMillis, double stopMillis) {
Media media = new Media(Paths.get(name).toUri().toString());
MediaPlayer player = new MediaPlayer(media);
player.setStartTime(new Duration(startMillis));
player.setStopTime(new Duration(stopMillis));
player.play();
}
More info can be found at the JavaFX javadoc.

Related

Changing the output audio level of a program in Java within the program

I am trying to change the output audio levels of the program, preferably in decibels. I need to change the audio levels of the entire program and record the change in the level. The language is Java. Is there any easy way to do this? The sounds I am using to play the sounds is below:
import java.io.InputStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Sound
{
String sounds;
public Sound(String file)
{
sounds = file;
playSound(sounds);
}//end contructor
public void playSound(String soundLoc)
{
try
{
InputStream inputStream = getClass().getResourceAsStream(soundLoc);
AudioStream audioStream = new AudioStream(inputStream);
AudioPlayer.player.start(audioStream);
}//end try
catch (Exception e)
{
}//end catch
}//end playSound method
}//end class Sound
You can use MASTER_GAIN_CONTROL using the Java sound API
you need to import this.... import javax.sound.sampled.*;
get your clip using a Clip object and then,
public void playSound(String soundLoc)
{
try
{
InputStream inputStream = getClass().getResourceAsStream(soundLoc);
AudioStream audioStream = new AudioStream(inputStream);
AudioPlayer.player.start(audioStream);
Clip myclip = AudioSystem.getClip();
myclip.open(audioStream);
FloatControl audioControl = (FloatControl) myclip.getControl(FloatControl.Type.MASTER_GAIN);
audioControl.setValue(-5.0f); //decrease volume 5 decibels
clip.start();
}//end try
catch (Exception e)
{
}//end catch
}//end playSound method

capturing internal audio java

i will record the sound from my programs. I use Ubuntu 14.04 and PulseAudio.
Now i try to record from pulseaudio but currently i'm only recording from my microphone.
How can i record the sound from pulseaudio instead of my microphone?
public static void captureAudio() {
try {
final AudioFormat format = getFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
final TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
Runnable runnable = new Runnable() {
int bufferSize = (int)format.getSampleRate() * format.getFrameSize();
byte buffer[] = new byte[bufferSize];
public void run() {
out = new ByteArrayOutputStream();
running = true;
try {
while (running) {
int count = line.read(buffer, 0, buffer.length);
if (count > 0) {
out.write(buffer, 0, count);
}
}
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
};
Thread captureThread = new Thread(runnable);
captureThread.start();
} catch (LineUnavailableException ex) {
ex.printStackTrace();
}
}
I tried some things to change this in my code:
Mixer mixer = AudioSystem.getMixer(null);
And then:
final TargetDataLine line = (TargetDataLine) mixer.getLine(info);
Hope anyone have a solution.
Greetings
Daniel
This problem cannot be solved from within Java alone. Java sees only the devices which are already there, as the following Java program demonstrates:
import javax.sound.sampled.*;
public class ListDevices {
public static void main(final String... args) throws Exception {
for (final Mixer.Info info : AudioSystem.getMixerInfo())
System.out.format("%s: %s %s %s %s%n", info, info.getName(), info.getVendor(), info.getVersion(), info.getDescription());
}
}
What you need to do is create a loopback device for your audio system. The following post shows how to do that: https://askubuntu.com/questions/257992/how-can-i-use-pulseaudio-virtual-audio-streams-to-play-music-over-skype The purpose was different, but it should be adaptable for your situation, as your situation seems simpler to me than the situation described in that post.
It should be possible to run those pactl commands from Java using Process.

getting lag when loading and playing sounds

i wrote a little sound class where i can make a sound and toggle it and stuff but im not too great and i had to at least temporarily scrap it. i tried a little method to load sound and play it and then when it ends to unload it. it causes a lot of lag though. the class i had before would do the same thing as far as i can see but it didnt discard the sound properly and the soundswouldnt load anymore. heres my method thats causing ober lag but is working for what it should do. i need help refining it please.
public static void runOnce(final String location) {
try {
File audioFile = new File(Game.gameFolder + "/sounds/" + location);
final AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
final Clip audioClip = (Clip) AudioSystem.getLine(info);
audioClip.open(audioStream);
audioClip.start();
new Thread(new Runnable() {
public void run() {
while (audioClip.isActive()) {}
try {
audioClip.close();
audioStream.close();
} catch (Exception e) {}
}
}).start();
} catch (Exception e) {}
}

Playing Sound in Java [duplicate]

This question already has answers here:
Access restriction error on my Java Code
(2 answers)
Closed 8 years ago.
Hello I'm trying to play a sound in java the code looks like this:
public void playSound(String sound) {
try {
InputStream in = new FileInputStream(new File(sound));
AudioStream audio = new AudioStream(in);
AudioPlayer.player.start(audio);
} catch (Exception e) {}
}
I imported sun.audio*; however get an error:
Access restriction: The type 'AudioPlayer' is not API (restriction on
required library 'C:\Program Files\Java\jre7\lib\rt.jar')
The following program plays a 16-bit wav sound from eclipse if we use javax.sound.
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 {
// Constructor
public SoundClipTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Test Sound Clip");
this.setSize(300, 200);
this.setVisible(true);
// You could also get the sound file with a URL
File soundFile = new File("C:/Users/niklas/workspace/assets/Sound/sound.wav");
try ( // Open an audio input stream.
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
// 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();
}
}

Get sound from a URL with Java

I'm learning english and I'd like to develop a software to help me with the pronunciation.
There is a site called HowJSay, if you enter here: http://www.howjsay.com/index.php?word=car
immediatly you'll hear the pronunciation of the word car . I'd like to develop a software in JAVA that could play this sound without necessity of enter in the site =]
I tried this, but doesn't work =/
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.howjsay.com/index.php?word=car");
url.openConnection();
AudioStream as = new AudioStream(url.openStream());
AudioPlayer.player.start(as);
AudioPlayer.player.stop(as);
}
Any Ideas? Please.
Here you go
import javax.sound.sampled.*;
import java.io.IOException;
import java.net.URL;
public class HowJSay
{
public static void main(String[] args) {
AudioInputStream din = null;
try {
AudioInputStream in = AudioSystem.getAudioInputStream(new URL("http://www.howjsay.com/mp3/"+ args[0] +".mp3"));
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(), 16, baseFormat.getChannels(),
baseFormat.getChannels() * 2, baseFormat.getSampleRate(),
false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
if(line != null) {
line.open(decodedFormat);
byte[] data = new byte[4096];
// Start
line.start();
int nBytesRead;
while ((nBytesRead = din.read(data, 0, data.length)) != -1) {
line.write(data, 0, nBytesRead);
}
// Stop
line.drain();
line.stop();
line.close();
din.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if(din != null) {
try { din.close(); } catch(IOException e) { }
}
}
}
}
Java Sound can play short clips easily, but supports a limited number of formats out of the box. The formats it supports by default are given by AudioSystem.getAudioFileTypes() & that list will not include MP3.
The solution to the lack of support for MP3 is to add a decoder to the run-time class-path of the app. Since Java Sound works on a Service Provider Interface, it only needs to be on the class-path to be useful. An MP3 decoder can be found in mp3plugin.jar.
As to the code for playing the MP3, the short source on the info. page should suffice so long as the clips are short. Viz.
import java.net.URL;
import javax.swing.*;
import javax.sound.sampled.*;
public class LoopSound {
public static void main(String[] args) throws Exception {
URL url = new URL(
"http://pscode.org/media/leftright.wav");
Clip clip = AudioSystem.getClip();
// getAudioInputStream() also accepts a File or InputStream
AudioInputStream ais = AudioSystem.
getAudioInputStream( url );
clip.open(ais);
clip.loop(Clip.LOOP_CONTINUOUSLY);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// A GUI element to prevent the Clip's daemon Thread
// from terminating at the end of the main()
JOptionPane.showMessageDialog(null, "Close to exit!");
}
});
}
}
If you don't care much about the site then you try to use Google Translate API
try{
String word="car";
word=java.net.URLEncoder.encode(word, "UTF-8");
URL url = new URL("http://translate.google.com/translate_tts?ie=UTF-8&tl=ja&q="+word);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.addRequestProperty("User-Agent", "Mozilla/4.76");
InputStream audioSrc = urlConn.getInputStream();
DataInputStream read = new DataInputStream(audioSrc);
AudioStream as = new AudioStream(read);
AudioPlayer.player.start(as);
AudioPlayer.player.stop(as);
}
With help from here:
Java: download Text to Speech from Google Translate
If for every word the site guarantees to have mp3 file with link howjsay.com/mp3/word.mp3 then you just need to change URL to
URL url = new URL("howjsay.com/mp3/" + word + ".mp3");
If you're having issues with the code provided by Marek, make sure you're meeting this criteria:
Use a supported audio format, such as 16 bit .wav
Make sure that the URL you're using is actually playing audio automatically.
It isn't sufficient to simply reference the download page for an audio file. It has to be streaming the audio. YouTube URLs won't work, as they're videos. Audacity is a good approach to converting your audio file to a compatible 16 bit .wav file, and if you have your own domain / website, you can provide a direct link to the file from there.

Categories