I have written this code for playing audio file, I want to get indication when my audio file ends after playing. I have tried AS.getMicrosecondLength() == AS.getMicrosecondPosition() but these methods are undefined for the AudioStream. Please tell how I can do that.
import java.io.FileInputStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class A {
public static void main(String arg[]) throws Exception {
AudioStream AS = new AudioStream(new FileInputStream("sounds.wav"));
AudioPlayer.player.start(AS);
}
}
AS.getMicrosecondLength() == AS.getMicrosecondPosition() could be used to set off the flag when the clip has ended
Related
I play sound effects (WAV files) in a game with javax.sound.sampled.Clip. However, the effect that has 2 seconds is not played entirely, only a part of it. If I add clip.loop(2) then the sound is played multiple times correctly, i.e. the whole 2 seconds. What is wrong and how to fix it?
package com.zetcode;
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.LineEvent;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JOptionPane;
public enum SoundEffect {
EXPLODE("resources/explosion.wav"),
HITGROUND("resources/impact.wav"),
CANNON("resources/cannon.wav");
private Clip clip;
SoundEffect(String soundFileName) {
try {
URL url = this.getClass().getClassLoader().getResource(soundFileName);
try (AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url)) {
clip = AudioSystem.getClip();
clip.open(audioInputStream);
}
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
JOptionPane.showMessageDialog(null, "Cannot play sound", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
public void play() {
if (clip.isRunning()) {
clip.stop();
}
clip.setFramePosition(0);
clip.start();
}
static void init() {
values();
}
}
Are you aware and accounting for the fact that when a clip is played (via start() method), the thread playing the code is a daemon? Unlike regular threads, a daemon thread will not prevent a Java program from closing. If your program ends before the sound has finished executing, the daemon status thread also ends even if it is not finished.
Are you trying to run the sample code SoundClipTest or SoundEffectDemo? It looks to me like SoundClipTest is going to exit as soon as the program executes the start() method, whereas the SoundEffectDemo will persist and allow the sound to finish playing.
** Edit 1 **
Am just now noticing that you have made your SoundEffect an enum. I've never seen that approach used before.
One approach I've used is to create a class called GameSound, and have its constructor preload each Clip individually and hold them in memory, ready for playback. Then, I create a method or methods for their playback.
gameSound.playExplosion();
The GameSound class would have instance variables for each sound effect.
private Clip explosion;
private Clip cannon;
And GameSound constructor would have:
URL url = this.getClass().getResource("resources/explosion.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
explosion = AudioSystem.getClip();
explosion.open(ais);
and GameSound would have method:
public void playExplosion()
{
if (explosion.isRunning()) {
explosion.stop();
}
explosion.setFramePosition(0);
explosion.start();
}
If you prefer to have the play method take an argument and use that on a switch structure to select which sound to play, that is fine, too, especially as it eliminates some code duplication.
This approach might work better (easy to add to GameSound as code gets more complex), and shouldn't be too difficult to code. I'd be curious to learn whether or not changing to this plan makes the problem go away or not.
** Edit 2 **
Sorry for mistakes in the above code. I fixed them when I made the following example. One thought, though, when I went to listen to the sound effects you linked, several of the explosions were kind of truncated to begin with. Have you played the sounds in another app (like Windows Groove Music, or from the website where you got them) and verified that they are different when you play them in your code?
Here is a quickie "GameSound". I downloaded the Explosion+2.wav file from your reference as it was longer than the others and has a clear ending, and am referencing that.
package stackoverflow.janbodnar;
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.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class GameSound {
private final Clip explosion;
public GameSound() throws LineUnavailableException,
IOException, UnsupportedAudioFileException
{
URL url = this.getClass().getResource(
"resources/Explosion+2.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
explosion = AudioSystem.getClip();
explosion.open(ais);
}
public void playExplosion()
{
if (explosion.isRunning()) {
explosion.stop();
}
explosion.setFramePosition(0);
explosion.start();
}
}
And here is a simple Swing button that calls GameSound.
package stackoverflow.janbodnar;
import java.io.IOException;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class GameSoundTest extends JFrame
{
private static final long serialVersionUID = 1L;
private final GameSound gameSound;
public GameSoundTest() throws LineUnavailableException,
IOException, UnsupportedAudioFileException
{
gameSound = new GameSound();
JButton button = new JButton("Play Explosion");
button.addActionListener(e -> gameSound.playExplosion());
getContentPane().add(button);
}
private static void createAndShowGUI()
{
JFrame frame;
try
{
frame = new GameSoundTest();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setBounds(0, 0, 200, 200);
frame.setVisible(true);
}
catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
}
This all assumes, of course, that there is a subfolder called "resources" with the explosion SFX in it.
Hello I want to make an alarm clock and now I`m at the part at makeing the sound play....I wrote this
package audio;
import sun.audio.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Audio {
public static void main(String[] args) {
InputStream in;
try{
in = new FileInputStream(new File("sw.wav"));
AudioStream audio = new AudioStream(in);
AudioPlayer.player.start(audio);
}
catch(Exception e){}
}
}
And it doesn`t play the sound It doesnt give me an error it doesnt do nothing
I also put the direct pathway in a folder C:\...etc
try this: move the audio file to the source folder, then modify the path of the File in the form: new File("./sw.wav") and then do something helpful with the exception...
public static void main(String[] args) {
InputStream in;
try{
in = new FileInputStream(new File("./sw.wav"));
AudioStream audio = new AudioStream(in);
AudioPlayer.player.start(audio);
}
catch(Exception e){
//print some helpfull info from the stack trace
}
}
The problem in defining the path of FileInputStream you should provide the full path of your audio file and seperate it with double slashes \\:
in = new FileInputStream("C:\\Users\\serban\\Documents\\wav sound\\sw.wav");
Or instead you can move the audio file to the source folder of your java program and then put:
in = new FileInputStream("sw.wav");
I am working on an audio player and need to add pause() and play() features in it to connect with JButtons. The problem is I am not able to import Media package as it says package does not exist. I cannot find anywhere it online to download the package. Same goes for AudioPlayer class which gives bad class file error.
you need the JMF libraries , you can get them from there , for windows there is a typic installer :
JMF Download
Based on your question,
You can down load java.media
then use
import javax.media.*;
then you can declare like
Player audioplayer = Manager.createRealizedPlayer(file.toURI().toURL());
And
audioplayer.start(); and audioplayer.stop();
Here file means where the source file saved.
NB: you can use JMF jar file
Try like this
try {
audioplayer = Manager.createRealizedPlayer(file.toURI().toURL());
} catch (IOException ex) {
Logger.getLogger(MY_MP3_PLAYER.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoPlayerException ex) {
Logger.getLogger(MY_MP3_PLAYER.class.getName()).log(Level.SEVERE, null, ex);
} catch (CannotRealizeException ex) {
Logger.getLogger(MY_MP3_PLAYER.class.getName()).log(Level.SEVERE, null, ex);
}
OR Try the sample code given below
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.media.CannotRealizeException;
import javax.media.Manager;
import javax.media.NoPlayerException;
import javax.media.Player;
public class Mp3Player {
public static void main(String[] args) throws IOException, NoPlayerException, CannotRealizeException {
// Source of song file
File f=new File("your path in which mp3 file is saved");
// Create a Player object that realizes the audio
final Player p=Manager.createRealizedPlayer(f.toURI().toURL());
// Start the music
p.start();
// Create a Scanner object for taking input from cmd
Scanner s=new Scanner(System.in);
// Read a line and store it in st
String st=s.nextLine();
// If user types 's', stop the audio
if(st.equals("s"))
{
p.stop();
}
}
}
It is a late answer, but you can use the Maven dependency:
<!-- https://mvnrepository.com/artifact/javax.media/jmf -->
<dependency>
<groupId>javax.media</groupId>
<artifactId>jmf</artifactId>
<version>2.1.1e</version>
</dependency>
Following four packages will solve your problem. They contains most of helpful methods to deal with audio player.
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
import javazoom.jl.player.advanced.AdvancedPlayer;
You can use .stop(), start(), .play() etc. from above packages.
Hope that will help.
I have written this code for playing audio file,and I want to get indication when my audio file ends after playing. I have tried AS.getMicrosecondLength() == AS.getMicrosecondPosition() but these methods are undefined for the AudioStream.
My Code:
import java.io.FileInputStream;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class A {
public static void main(String arg[]) throws Exception {
AudioStream AS = new AudioStream(new FileInputStream("sounds.wav"));
AudioPlayer.player.start(AS);
}
}
Please tell how I can solve my problem
First question/post on here, hopefully I've done it right!
Using java, I need a method to somehow add audio files to a queue and play the next file once the last one has finished because at the minute they just play over the top of each other. I am using Audiosystem to play the sound files.
I thought of using an array to store the sound clips waiting to be played but got stumped and didn't know where to go from there.
Hopefully someone can help, thanks.
import javax.sound.midi.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class MidiPlayer{
public static void main(String[] args) {
try {
Sequencer sequencer = MidiSystem.getSequencer();
if (sequencer == null)
throw new MidiUnavailableException();
sequencer.open();
FileInputStream is = new FileInputStream("music.mid");
Sequence Seq = MidiSystem.getSequence(is);
sequencer.setSequence(Seq);
sequencer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
here is a sample code that shows you how to play MIDI files in your java program, hope it helps