如何在Java中播放Ogg文件?

时间:2014-07-15 17:56:16

标签: java ogg

我使用Vorbis SPI播放Ogg文件,但我得到了这个例外

    javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file
    at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1189)
    at application.OggPlayer.play(OggPlayer.java:31)
    at application.OggPlayer.main(OggPlayer.java:23)

以下是文档链接http://www.javazoom.net/vorbisspi/documents.html

在这里,如果我的代码

public class OggPlayer {
    static OggPlayer player;
    public static void main(String[] args) {
        player = new OggPlayer ();
        player.play(System.getProperty("user.dir")+ "/myFile.ogg");
    }

    public void play(String filePath) {
        try
        {
            File file = new File(filePath);
            // Get AudioInputStream from given file.
            AudioInputStream in= AudioSystem.getAudioInputStream(file);
            AudioInputStream din = null;
            if (in != null)
            {
                AudioFormat baseFormat = in.getFormat();
                AudioFormat  decodedFormat = new AudioFormat(
                        AudioFormat.Encoding.PCM_SIGNED,
                        baseFormat.getSampleRate(),
                        16,
                        baseFormat.getChannels(),
                        baseFormat.getChannels() * 2,
                        baseFormat.getSampleRate(),
                        false);
                // Get AudioInputStream that will be decoded by underlying VorbisSPI
                din = AudioSystem.getAudioInputStream(decodedFormat, in);
                // Play now !
                rawplay(decodedFormat, din);
                in.close();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void rawplay(AudioFormat targetFormat,
            AudioInputStream din) throws IOException, LineUnavailableException
    {
        byte[] data = new byte[4096];
        SourceDataLine line = getLine(targetFormat);
        if (line != null)
        {
            // Start
            line.start();
            int nBytesRead = 0, nBytesWritten = 0;
            while (nBytesRead != -1)
            {
                nBytesRead = din.read(data, 0, data.length);
                if (nBytesRead != -1) nBytesWritten = line.write(data, 0, nBytesRead);
            }
            // Stop
            line.drain();
            line.stop();
            line.close();
            din.close();
        }
    }

    private SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException
    {
        SourceDataLine res = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
        res = (SourceDataLine) AudioSystem.getLine(info);
        res.open(audioFormat);
        return res;
    }
}

我的代码有什么问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

未经许可,来自here

/**
 *  Decodes the current packet and sends it to the audio output line.
 */
private void decodeCurrentPacket()
{
    int samples;

    // Check that the packet is a audio data packet etc.
    if(jorbisBlock.synthesis(joggPacket) == 0)
    {
        // Give the block to the DspState object.
        jorbisDspState.synthesis_blockin(jorbisBlock);
    }

    // We need to know how many samples to process.
    int range;

    /*
     * Get the PCM information and count the samples. And while these
     * samples are more than zero...
     */
    while((samples = jorbisDspState.synthesis_pcmout(pcmInfo, pcmIndex))
        > 0)
    {
        // We need to know for how many samples we are going to process.
        if(samples < convertedBufferSize)
        {
            range = samples;
        }
        else
        {
            range = convertedBufferSize;
        }

        // For each channel...
        for(int i = 0; i < jorbisInfo.channels; i++)
        {
            int sampleIndex = i * 2;

            // For every sample in our range...
            for(int j = 0; j < range; j++)
            {
                /*
                 * Get the PCM value for the channel at the correct
                 * position.
                 */
                int value = (int) (pcmInfo[0][i][pcmIndex[i] + j] * 32767);

                /*
                 * We make sure our value doesn't exceed or falls below
                 * +-32767.
                 */
                if(value > 32767)
                {
                    value = 32767;
                }
                if(value < -32768)
                {
                    value = -32768;
                }

                /*
                 * It the value is less than zero, we bitwise-or it with
                 * 32768 (which is 1000000000000000 = 10^15).
                 */
                if(value < 0) value = value | 32768;

                /*
                 * Take our value and split it into two, one with the last
                 * byte and one with the first byte.
                 */
                convertedBuffer[sampleIndex] = (byte) (value);
                convertedBuffer[sampleIndex + 1] = (byte) (value >>> 8);

                /*
                 * Move the sample index forward by two (since that's how
                 * many values we get at once) times the number of channels.
                 */
                sampleIndex += 2 * (jorbisInfo.channels);
            }
        }

        // Write the buffer to the audio output line.
        outputLine.write(convertedBuffer, 0, 2 * jorbisInfo.channels
            * range);

        // Update the DspState object.
        jorbisDspState.synthesis_read(range);
    }
}