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
Related
thanks so much in advance for helping me with this seemingly tiny thing - yet I can't figure it out. MP4 Video/audio playback works just fine, yet I can't set the position in the video.
Here's my stripped down code:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import javax.swing.JPanel;
import com.sun.jna.NativeLibrary;
import java.util.logging.Level;
import java.util.logging.Logger;
import uk.co.caprica.vlcj.binding.RuntimeUtil;
import uk.co.caprica.vlcj.player.base.ControlsApi;
import uk.co.caprica.vlcj.player.base.MediaApi;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.component.CallbackMediaPlayerComponent;
import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.component.callback.FilledCallbackImagePainter;
import uk.co.caprica.vlcj.player.component.callback.FixedCallbackImagePainter;
import uk.co.caprica.vlcj.player.component.callback.ScaledCallbackImagePainter;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.renderer.RendererItem;
import uk.co.caprica.vlcjplayer.event.TickEvent;
import uk.co.caprica.vlcjplayer.view.action.mediaplayer.MediaPlayerActions;
public class TestClass extends JPanel {
private EmbeddedMediaPlayerComponent ourMediaPlayer;
TestClass(){
//NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC");
ourMediaPlayer = new EmbeddedMediaPlayerComponent();
/* Set the canvas */
Canvas c = new Canvas();
c.setBackground(Color.black);
c.setVisible(true);
/* Set the layout */
this.setLayout(new BorderLayout());
/* Add the canvas */
this.add(c, BorderLayout.CENTER);
this.setVisible(true);
this.add(ourMediaPlayer);
}
public void play() {
/* Play the video */
System.out.println("Starting...");
ourMediaPlayer.mediaPlayer().controls().setPosition((float) 0.5); // NOPE
ourMediaPlayer.mediaPlayer().media().play("/home/manfred/ExtraDisk/Work/BTL/Movement2022/walking.mp4"); // works
ourMediaPlayer.mediaPlayer().controls().stop(); // works
ourMediaPlayer.mediaPlayer().controls().setPosition((float) 0.5); //NOPE
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(TestClass.class.getName()).log(Level.SEVERE, null, ex);
}
ourMediaPlayer.mediaPlayer().controls().setPosition((float) 0.5); //NOPE
ourMediaPlayer.mediaPlayer().controls().setTime(2000); // NOPE
ourMediaPlayer.mediaPlayer().controls().start(); //works
//System.time.sleep(2);
System.out.println("Started!");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(TestClass.class.getName()).log(Level.SEVERE, null, ex);
}
ourMediaPlayer.mediaPlayer().controls().stop(); // works
}
}
Playback via .mediaPlayer().media().play() works, so does start and stop via .mediaPlayer().controls().start() and .mediaPlayer().controls().stop().
What doesn't work is .mediaPlayer().controls().setTime(xx) and .mediaPlayer().controls().setPosition(xx), basically nothing happens.
What am I not doing right here? Is this a threading issue? Anyone have any working minimal examples?
Thanks again, any help is greatly appreciated!
It is not possible to use the API to set the time/position before playback has started.
LibVLC operates asynchronously for many operations. Just calling play() does not mean that playback has started, so setting the time/position immediately after play() is called will not (always) work.
There are at least two approaches you can use:
Wait for a media player "ready" event, and set the time/position (this will fire an event each time the media player is ready, so each time you play it, although you can write a one-shot listener that unregisters itself if you only want to do it the first time you play).
public static void main(String[] args) throws Exception {
MediaPlayer mediaPlayer = new MediaPlayerFactory().mediaPlayers().newMediaPlayer();
mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
#Override
public void mediaPlayerReady(MediaPlayer mediaPlayer) {
mediaPlayer.controls().setTime(10000);
}
});
mediaPlayer.media().play("/home/movies/whatever.mp4");
Thread.currentThread().join();
}
With this first approach there is the small risk that you will see one or two video frames rendered before skipping occurs.
Use media options to set the start time (in seconds, including fractions of seconds like 10.5):
public static void main(String[] args) throws Exception {
MediaPlayer mediaPlayer = new MediaPlayerFactory().mediaPlayers().newMediaPlayer();
mediaPlayer.media().play("/home/movies/whatever.mp4", ":start-time=10");
Thread.currentThread().join();
}
Thanks to caprica's ingenious insights, this snippet actually works (don't know why, but it does - and that's all that matters for now):
ourMediaPlayer.mediaPlayer().media().play("/home/manfred/ExtraDisk/Work/BTL/Movement2022/walking.mp4"); // works
ourMediaPlayer.mediaPlayer().controls().stop(); // works
ourMediaPlayer.mediaPlayer().controls().start(); // works
ourMediaPlayer.mediaPlayer().controls().setTime(5000); // WORKS
Still a bit of a mystery, but I'll take it!
Music works just fine when i click on the box, but music won't stop when I click on it again. Then if i click on the unchecked box again, the music plays again so 2 times at once! Please help me with stopping the music!
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {
InputStream inputStream = getClass().getResourceAsStream("panda - desiigner (donald trump remix).au");
AudioStream audioStream = null;
try {
audioStream = new AudioStream(inputStream);
} catch (IOException ex) {
Logger.getLogger(kekFrame.class.getName()).log(Level.SEVERE, null, ex);
}
int check;
if(jCheckBox1.isSelected() == true){
check = 1;
} else {
check = 0;
}
switch (check) {
case 1 : AudioPlayer.player.start(audioStream);
System.out.println("Music has started playing");
break;
case 0 : AudioPlayer.player.stop(audioStream);
System.out.println("Music has stopped playing");
break;
}
}
/**
* #param args the command line arguments
*/
// Variables declaration - do not modify
private javax.swing.JCheckBox jCheckBox1;
Assuming you have properly created a Clip, and can access both it and a boolean (isSelected, say) that reflects the state of the JCheckBox, the following simple code should work:
if (isSelected)
{
clip.setFramePosition(0);
clip.start();
}
else
{
clip.stop();
}
This can be included in the JCheckBox's ActionListener.
More information about using Clips can be found on the Java Tutorial's "Audio Thread" with specifics about the Clips here. There are clearer examples elsewhere if you do a search on how to use a Java Clip. The official Java Tutorial for audio emphasizes background and high-level concepts at the expense of practical examples, imho, which makes for difficult reading for those of us who are just starting out.
sun.audio.AudioPlayer is no longer supported! Even if it works on your PC, there is no guarantee it will work on other systems. Unfortunately, this is a situation where obsolete code examples live on in blogs and unofficial tutorials, which can happen a lot as languages evolve and the parties that wrote the tutorials don't update or maintain their posts.
In response to the OP's request, here is an example adapted from one of my JavaFX gui's. I don't use Swing anymore and am not keen to go back.
In the code where the JavFX Button is being built:
btnPlay = new Button("Play");
btnPlay.setOnAction(e -> handlePlay(e));
This calls the following method:
private void handlePlay(ActionEvent e)
{
if (!isPlaying)
{
clip.setFramePosition(0);
clip.start();
((Button)e.getSource()).setText("STOP");
isPlaying = true;
}
else
{
clip.stop();
((Button)e.getSource()).setText("PLAY");
isPlaying = false;
}
}
In this code, isPlaying is an instance variable that in this case merely tells us whether the button is on or off. The clip may very well play to its end and stop on its own while the button is still in a "playing" state. It would require wiring up a LineListener to have the button toggle back when the clip finishes playing.
Maybe you can adapt the above into something useful? It seems to me the choice of JCheckBox is dubious, and a JToggleButton might be a better choice. Examples of writing Listeners for Swing Buttons can be found here.
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, 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
I was trying out the method of creating a background music for a java program, but it displayed an IO excedption error when i clicked the play button.
package javaentertainment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.*;
import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Music
{
public static void main(String args[])
{
JFrame frame=new JFrame();
frame.setSize(100,100);
JButton button=new JButton("P L A Y");
frame.add(button);
button.addActionListener(new AL());
frame.show();
}
public static class AL implements ActionListener
{
public void actionPerformed(ActionEvent e) {
music();
}
}
public static void music()
{
AudioPlayer MGP=AudioPlayer.player;
AudioStream BGM;
AudioData MD;
ContinousAudioDataStream loop=null;
try
{
BGM = new AudioStream(new FileInputStream("Vision.wmv"));
MD=BGM.getData();
loop=new ContinousAudioDataStream(MD);
}
catch (IOException ex)
{
System.out.println(ex);
}
MGP.start(loop); // word loop was underlined by netbeans
}
}
When I run the program and click on play it displays the following error,
java.io.IOException: could not create audio stream from input stream
You should use JMF (Java Media Framework). For your interest: The list of accepted formats can be found here.
In short, it supports AIFF, AVI, GSM, MVR, MID, MPG, MP2, MOV, AU and WAV files.
But there is a workarond as stated here:
On a side note, if you add a
mime-setting in JMFRegistry to map
Windows Media content (such as .asf
and .wmv) to the content-type
"video/mpeg", JMF can actually play
Windows Media or any other DirectShow
file (and only file - http wont work).
I would be surprised if Java can hand Windows Media format samples - try converting the .wmv to a .wav file and see if it works then.
Just got this, as well.
java.io.IOException: could not create AudioData object
Appears from the source [1] that this means that "your audio file is size > 1 MB" and it doesn't like that for whatever reason. Maybe a bug [?] that they don't accomodate for this.
One work-around might be to use JMF instead, as suggested, if you want looping to work for large files anyway.
[1] http://www.docjar.com/docs/api/sun/audio/AudioStream.html#getData