Play MP3 or OGG using javax.sound.sampled, mp3spi, vorbisspi

I tried to come up with the simplest possible way of writing a Java class that can play mp3 and ogg files, using standard Java Sound APIs, with purely Open Source libraries from the public Maven Central repositories.

The LGPL-licensed mp3spi and vorbisspi libraries from javazoom.net satisfy these requirements and worked for me right away. As service provider implementations (SPI), they transparently add support for the mp3 and ogg audio formats to javax.sound.sampled, simply by being in the classpath.

For my AudioFilePlayer class below I basically took the example code from javazoom and simplified it as much as possible. Please note that it requires Java 7 as it uses try-with-resources.

Maven dependencies

  <!-- 
    We have to explicitly instruct Maven to use tritonus-share 0.3.7-2 
    and NOT 0.3.7-1, otherwise vorbisspi won't work.
   -->
<dependency>
  <groupId>com.googlecode.soundlibs</groupId>
  <artifactId>tritonus-share</artifactId>
  <version>0.3.7-2</version>
</dependency>
<dependency>
  <groupId>com.googlecode.soundlibs</groupId>
  <artifactId>mp3spi</artifactId>
  <version>1.9.5-1</version>
</dependency>
<dependency>
  <groupId>com.googlecode.soundlibs</groupId>
  <artifactId>vorbisspi</artifactId>
  <version>1.0.3-1</version>
</dependency>

AudioFilePlayer.java

package net.doepner.audio;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

import static javax.sound.sampled.AudioSystem.getAudioInputStream;
import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;

public class AudioFilePlayer {

    public static void main(String[] args) {
        final AudioFilePlayer player = new AudioFilePlayer ();
        player.play("something.mp3");
        player.play("something.ogg");
    }

    public void play(String filePath) {
        final File file = new File(filePath);

        try (final AudioInputStream in = getAudioInputStream(file)) {
            
            final AudioFormat outFormat = getOutFormat(in.getFormat());
            final Info info = new Info(SourceDataLine.class, outFormat);

            try (final SourceDataLine line =
                     (SourceDataLine) AudioSystem.getLine(info)) {

                if (line != null) {
                    line.open(outFormat);
                    line.start();
                    stream(getAudioInputStream(outFormat, in), line);
                    line.drain();
                    line.stop();
                }
            }

        } catch (UnsupportedAudioFileException 
               | LineUnavailableException 
               | IOException e) {
            throw new IllegalStateException(e);
        }
    }

    private AudioFormat getOutFormat(AudioFormat inFormat) {
        final int ch = inFormat.getChannels();
        final float rate = inFormat.getSampleRate();
        return new AudioFormat(PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
    }

    private void stream(AudioInputStream in, SourceDataLine line) 
        throws IOException {
        final byte[] buffer = new byte[65536];
        for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) {
            line.write(buffer, 0, n);
        }
    }
}
Advertisement

27 thoughts on “Play MP3 or OGG using javax.sound.sampled, mp3spi, vorbisspi

  1. Thank you for this (relatively) simple example.
    I am an absolute beginner with Java and I learned that Java can play .Wav files as standard but I was more interested in playing an MP3 file.

    I managed to play an mp3 track using this code.

    But I had to find out about how to make Maven projects.

    And also I had to add some plug in as found here (to make compilation work): “https://stackoverflow.com/questions/20806470/resource-specification-not-allowed-here-for-source-level-below-1-7”

    org.apache.maven.plugins
    maven-compiler-plugin
    2.5.1

    1.7
    1.7

    And to make that work I had to write that code in between this code:
    https://maven.apache.org/guides/mini/guide-configuring-plugins.html

    I wish there was more comments explaining what actually happens in the program.

    But I guess it reads the file piece by piece and plays it as it goes along?

    It feels like (although this was a fun experiment) it is a bit sad that the program seems completely occupied while the song is playing.

    How hard would it be to make a program that can do other things while the music / sound plays?
    I mean it as an honest question!
    I am not just saying “how hard could it be!”
    Cause I really do not have any feeling for how hard it would be. :p

    1. Sorry about the late approval of your comment. I am responding now because I just noticed and approved it.

      I think when I needed to play audio in the background I wrapped the call to “play” in a new Thread.

      1. Yes!

        Thank you! =)

        Yes, I guess when I wrote my comment I did not yet know about threads! ^^

  2. The code does not paly MP3 or OGG files (issues “UnsupportedAudioFileException”). It only plays WAV files … which you do not include!! How lame this is!

    1. It works for me and other people. I am usually quite willing to help people. If you calm down and ask nicely then maybe I’ll help you troubleshoot your problem.

  3. hi,the code cannot play the mp3 file, it just can play the wav file. if play mp3 file,it shows Exception like this: Exception in thread “main” java.lang.IllegalStateException: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file

    1. Are you sure you have the dependencies in your pom.xml and are running the code with those libraries in the classpath? Without tritonus-share and mp3spi in your classpath, the JVM won’t be able to find an implementation for MP3 decoding.

  4. xception in thread “main” java.lang.IllegalStateException: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file
    at net.doepner.audio.AudioFilePlayer.play(AudioFilePlayer.java:48)
    at net.doepner.audio.AudioFilePlayer.main(AudioFilePlayer.java:21)
    Caused by: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file
    at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1189)
    at net.doepner.audio.AudioFilePlayer.play(AudioFilePlayer.java:28)
    … 1 more

    i am getting these errors please help me dude!

  5. Hi, I am doing an AWS blog post on the new Polly API and I would like to use your class here. Do you mind if I cross reference your blog? Thanks, Nick

  6. Is there any way to play more than one file at a time? Even if I put it in another thread it doesn’t work.. =T

    1. You shouldn’t need threads for concurrent audio. It might be a matter of your audio setup. If you are on Linux, make sure you have Pulseaudio installed. What Operating system are you using?

  7. If the audio resource is to be packed inside a jar, you would use URL instead of File. Also, you would use a relative address. Common practice: make a subfolder to the folder of the source code, named “audio”. Then invoke via:
    URL url = this.getClass().getResource(“./audio/yourMusicCue.wav”);
    ais = AudioSystem.getAudioInputStream(url);

  8. My ears prefer AAC to Ogg Vorbis and MP3. I would be grateful if you would add the ability to play M4A/AAC files to your Java music player.

  9. Thanks for the simplifications! Just one more question! In which folder should the audio file be saved, in order not to throw exception?

    1. You can save the file anywhere. Just make sure you pass the full path to the play(..) method. For example:
      player.play(“C:\Temp\something.mp3”);

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s