Audio not Working Correctly - java

The last time I asked how to use background audio correctly, I was told I had to use a thread. Now, I have done that, yet I still have the same problem: It does not run the rest of the program until the song completes, yet I need it to play in the background! help anyone? (Sorry for no comments in the code. If you all really feel there needs to be some to help you out I will update it with comments).
import javax.swing.JOptionPane;
import javax.swing.JDialog;
import java.io.*;
import javax.sound.sampled.*;
public class PokemonDemo3 implements LineListener
{
private boolean done = false;
public void update(LineEvent event)
{
if(event.getType() == LineEvent.Type.STOP || event.getType() == LineEvent.Type.CLOSE)
{
done = true;
}
}
public void waitonfinish() throws InterruptedException
{
while(!done)
{
Thread.sleep(1000);
}
}
public static void playSound(final String url)
{
try
{
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(url));
PokemonDemo3 control = new PokemonDemo3();
clip.addLineListener(control);
clip.open(inputStream);
clip.start();
control.waitonfinish();
}
catch (Exception e)
{
System.err.println(e.getMessage());
}
}
public static void main(String [] args)
{
String holder;
int response;
String[] options = {"Boy", "Girl"};
Pokemon intro = new Pokemon();
playSound("/Users/2018658/Desktop/pokemon.wav");
}

Related

Getting java.io.IOException:mark/reset not supported after uploading a file to play, pause, resume, loop audio

This is the code I have as of now:
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.util.Scanner;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.sound.sampled.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class changeyouvoice extends Frame implements WindowListener, ActionListener {
JButton upload;
JFileChooser jfc;
int i;
Long currentFrame;
Clip clip;
String status;
public static void main(String[] args) {
// 2nd step
changeyouvoice myWindow = new changeyouvoice();
myWindow.setSize(350, 100);
myWindow.setVisible(true);
}
public changeyouvoice() {
jfc = new JFileChooser();
setLayout(new FlowLayout());
addWindowListener(this);
upload = new JButton("Upload");
add(upload);
upload.addActionListener(this);
// create AudioInputStream object
}
public void actionPerformed(ActionEvent e) {
jfc.setDialogTitle("Select the video of your voice");
jfc.setAcceptAllFileFilterUsed(false);// you are not searching for anything.
// figure out why
FileNameExtensionFilter filter = new FileNameExtensionFilter("Select Audio", "m4a", "mp3", "flac", "wav", "wma",
"aac");
jfc.setFileFilter(filter);
int returnValue = jfc.showOpenDialog(this);
// create AudioInputStream object
if (returnValue == JFileChooser.APPROVE_OPTION) {
try {
if (e.getSource() == upload) {
int x = jfc.showOpenDialog(this);
if (x == JFileChooser.APPROVE_OPTION) {
File fileToBeSent = jfc.getSelectedFile();
File initialFile = new File(fileToBeSent.getAbsolutePath());
try {
// InputStream targetStream;
InputStream targetStream = new FileInputStream(initialFile);
AudioInputStream myvoice = AudioSystem.getAudioInputStream(targetStream); // figure
// out
// how
// its
// created. read the file
// and get audio stream
// create AudioInputStream object
// create clip reference
clip = AudioSystem.getClip();
try {
clip.start();
clip.open(myvoice);
clip.loop(Clip.LOOP_CONTINUOUSLY);
status = "play";
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("1. pause");
System.out.println("2. resume");
System.out.println("3. restart");
System.out.println("4. stop");
System.out.println("5. Jump to specific time");
int c = sc.nextInt();
switch (c) {
case 1:
pause();
break;
case 2:
resumeAudio();
break;
case 3:
restart();
break;
case 4:
stop();
break;
case 5:
System.out.println("Enter time (" + 0 +
", " + clip.getMicrosecondLength() + ")");
long c1 = sc.nextLong();
jump(c1);
break;
}
if (c == 4)
break;
}
sc.close();
} catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
// create clip reference
// open audioInputStream to the clip
} catch (Exception j) {
// Handle the error...
System.out.println(j.toString());
}
}
}
} catch (Exception png) {
// Handle the error...
System.out.println(png.toString());
} finally {
// ... cleanup that will execute whether or not an error occurred ...
}
}
}
// Method to pause the audio
public void pause() {
if (status.equals("paused")) {
System.out.println("audio is already paused");
return;
}
this.currentFrame = this.clip.getMicrosecondPosition();
clip.stop();
status = "paused";
}
// Method to resume the audio
public void resumeAudio() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
if (status.equals("play")) {
System.out.println("Audio is already " + "being played");
return;
}
clip.close();
resetAudioStream();
clip.setMicrosecondPosition(currentFrame);
clip.start();
status = "play";
}
// Method to restart the audio
public void restart() throws IOException, LineUnavailableException, UnsupportedAudioFileException {
clip.stop();
clip.close();
resetAudioStream();
currentFrame = 0L;
clip.setMicrosecondPosition(0);
clip.start();
status = "play";
}
// Method to stop the audio
public void stop() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
currentFrame = 0L;
clip.stop();
clip.close();
}
// Method to jump over a specific part
public void jump(long c) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
if (c > 0 && c < clip.getMicrosecondLength()) {
clip.stop();
clip.close();
resetAudioStream();
currentFrame = c;
clip.setMicrosecondPosition(c);
clip.start();
status = "play";
}
}
// Method to reset audio stream
public void resetAudioStream() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
AudioInputStream audioInputStream = AudioSystem
.getAudioInputStream(this.getClass().getResource(jfc.getSelectedFile().getAbsolutePath()));
clip.open(audioInputStream);
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
public void windowOpened(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
}
The code works fine when uploading a file, but for some reason I am not able to play, pause, or resume the audio. I used several tutorials to get the functions to help play the audio, but when I uploaded the file I had to upload it twice and an exception was displayed which was
/Users/thevladimirgeorge/Downloads/Vlad's story.mp3
java.io.IOException: mark/reset not supported
I wonder what was the issue going on with the code. The app I used to code is Visual Studio Code.
If you provide a URL instead of an InputStream as an argument to AudioSystem.getAudioStream, the requirement that the media resource supports marking and resetting is circumvented. This can be observed by comparing the APIs for the two methods.
AudioSystem.getAudioInputStream(InputStream)
AudioSystem.getAudioInputStream(URL)
Only the method that takes InputStream includes these checks:
The implementation of this method may require multiple parsers to
examine the stream to determine whether they support it. These parsers
must be able to mark the stream, read enough data to determine whether
they support the stream, and reset the stream's read pointer to its
original position. If the input stream does not support these
operations, this method may fail with an IOException.
So, rewriting the code to obtain a URL for your resource instead of an InputStream should solve your problem, unless you explicitly need to have the AudioInputStream support marking and resetting. I've not come across such a scenario myself. Would be interesting in learning about situations where this capability is used.
EDIT: I overlooked that you are trying to load an mp3. Java doesn't directly support this or many of the other files on your list of audio. You will need to include additional libraries and code to handle these. The following (executed in jshell) can show what formats are supported:
jshell> import javax.sound.sampled.*;
jshell> AudioFileFormat.Type[] types = AudioSystem.getAudioFileTypes();
types ==> AudioFileFormat$Type[3] { WAVE, AU, AIFF }
More documentation can be found in the JavaSound section of the TroubleShooting Guide.

Adjust the JLayer playback volume

How to set the volume in this simple example?
I saw different approaches before but I don't know how to adapt them for my simple snippet.
Related Questions:
Changing Volume with JLayer
Changing volume in Java when using JLayer
Code listing:
package view.sound;
import java.io.FileInputStream;
import javazoom.jl.player.Player;
public class Audio extends Thread {
String fileLocation = "src/EgyptianTavernFullofGuitarists_1.mp3";
boolean loop = true;
Player player;
#Override
public void run() {
try {
do {
FileInputStream buff = new FileInputStream(fileLocation);
player = new Player(buff);
player.play();
} while (loop);
} catch (Exception ioe) {
}
}
public void close(){
loop = false;
player.close();
this.interrupt();
}
}

How do I stop audio in Java?

I want to play music when my getoutput method is invoked and stop the music when the invoking is finished. I'm able to do the former but not the latter. How do I stop the music after I've finished invoking the getoutput method?
import java.io.InputStream;
import javax.sound.sampled.AudioSystem;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Student {
public void music() {
try {
// open the sound file as a Java input stream
String gongFile = "C:\\Users\\wei liang\\Documents\\Programming fundamentals\\T7-Arrays\\Assignment\\TT.wav";
InputStream in = new FileInputStream(gongFile);
// create an audiostream from the inputstream
AudioStream audioStream = new AudioStream(in);
// play the audio clip with the audioplayer class
AudioPlayer.player.start(audioStream);
} catch (Exception ex) {
System.out.println("Error! Can't find file.");
ex.printStackTrace();
}
}
}
This is my main method which calls the music method and another method not shown in the Student class.
public class StudentUser {
//Main method
public static void main(String args[]) {
//creating a new Student object
Student stud = new Student();
//Calling the music method
stud.music();
//Calling the getoutput method
stud.getoutput();
}
}
I would suggest using Thread, the Thread will be kept live until the music file is played and it will be ended automatically.
Since you did not provided getoutput method, you just call music method and it will play the music and ends.
Your Student class would be like:
import javax.sound.sampled.*;
import java.io.File;
class Student {
public synchronized void music(final String fileName, final SoundOptions mode) {
Thread music = new Thread(new Runnable() {
#Override
public void run() {
try {
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
new File(fileName));
final Clip audioLineClip = (Clip) AudioSystem.getLine(
new Line.Info(Clip.class));
audioLineClip.open(inputStream);
audioLineClip.setFramePosition(0);
audioLineClip.addLineListener(new LineListener() {
#Override
public void update(LineEvent event) {
LineEvent.Type type = event.getType();
if (type == LineEvent.Type.OPEN) {
} else if (type == LineEvent.Type.CLOSE) {
System.exit(0);
} else if (type == LineEvent.Type.START) {
} else if (type == LineEvent.Type.STOP) {
audioLineClip.close();
}
}
});
switch (mode) {
case Stop:
audioLineClip.stop();
break;
case Play:
audioLineClip.start();
break;
case Loop:
audioLineClip.loop(Clip.LOOP_CONTINUOUSLY);
break;
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
});
if (mode != SoundOptions.Stop) {
music.start();
synchronized (music) {
while (true) {
try {
music.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} else {
music.interrupt();
}
}
}
enum SoundOptions {
Play, Loop, Stop
}
and StudentUser class:
public class StudentUser {
private static String gongFile = "C:\\Users\\wei liang\\Documents\\Programming fundamentals\\T7-Arrays\\Assignment\\TT.wav";
//Main method
public static void main(String args[]) {
//Creating a new Student object
Student stud = new Student();
//Calling the music method and it is stops when music ends
stud.music(gongFile, SoundOptions.Play);
}
}

Clear data from Clip/AudioStream to free up memory

I have some code that serves as a super basic music player:
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class MusicPlayer{
private Clip c;
private boolean playing;
public MusicPlayer(){
playing = false;
}
public void play(String fileName) {
if(playing == false){
try {
c.drain();
c.flush();
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(fileName));
c = AudioSystem.getClip();
c.open(audioInputStream);
c.start();
playing = true;
} catch(Exception ex) {
System.out.println("Error with playing sound:" + ex);
ex.printStackTrace();
}
}
}
public void stop(){
if(playing == true){
c.stop();
playing = false;
}
}
}
The problem is that if I try to open too many wav files, the program crashes with an OutOfMemoryError. Giving the program more memory to work with (less than ideal to begin with) still means that the program runs slower each time a new file is opened. You can see I tried to solve this with:
c.drain();
c.flush();
but plainly this is not enough. Any help is appreciated!

What is wrong with my code so it can't play wav file?

I'm trying to use the code which available on: How can I play sound in Java?
but I can't post question there since this is a new account and only have 1 reputation.
original code:
public static synchronized void playSound(final String url) {
new Thread(new Runnable() { // the wrapper thread is unnecessary, unless it blocks on the Clip finishing, see comments
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream("/path/to/sounds/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
and this is my code:
package sound_test;
import javax.sound.sampled.*;
public class Main {
public static synchronized void playSound(final String url) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream("/path/to/sounds/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
public static void main(String[] args) {
// TODO code application logic here
playSound("C:\\warning_test.wav");
}
}
When I run the code i receive "null" as the output and no sound came out.
I've checked the file name and the path, it's correct.
screenshots:
http://puu.sh/pkYo
http://puu.sh/pkZl
Thank you in advance.
you could do
AudioInputStream inputStream=AudioSystem.getAudioInputStream(new File(url));
also add a delay after click.start(); i.e Thread.Sleep(4000);
or if you want to make sure it plays the entire audio sample you could use a simple snippet such as
import javax.sound.sampled.*;
import java.io.File;
public class Main implements LineListener {
private boolean done = false;
public void update(LineEvent event) {
if(event.getType() == LineEvent.Type.STOP || event.getType() == LineEvent.Type.CLOSE) {
done = true;
}
}
public void waitonfinish() throws InterruptedException {
while(!done) {
Thread.sleep(1000);
}
}
public static void playSound(final String url) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(url));
Main control = new Main();
clip.addLineListener(control);
clip.open(inputStream);
clip.start();
control.waitonfinish();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
public static void main(String[] args) {
// TODO code application logic here
playSound("C:\\warning_test.wav");
}
}
`
You copied the code entirely without noticing the in the original, it points to
path/to/sounds
since you give it the full path, u should replace it with just url:
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream(url));
EDIT:
I tried here and got null as well.
I changed it to create the audioInput from a file:
import java.io.File;
import javax.sound.sampled.*;
public class Main {
public static synchronized void playSound(final File file) {
new Thread(new Runnable() {
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(file);
clip.open(inputStream);
clip.start();
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
}).start();
}
public static void main(String[] args) {
// TODO code application logic here
File file = new File("C:\\warning_test.wav");
playSound(file);
}

Categories