需要在使用Java的ogg游戏中应用搜索

时间:2014-10-23 11:58:33

标签: java ogg seek multiplatform audio-player

我一直在为一个需要同时实现mp3和ogg播放器的多平台桌面应用程序工作,包括寻求,现在我的mp3部分是好的,但是在ogg游戏中搜索不起作用...

我使用的是BasicPlayer javazoom.jlgui,以下是我的搜索功能

/**
 * Skip bytes in the File inputstream. It will skip N frames matching to
 * bytes, so it will never skip given bytes length exactly.
 *
 * @param bytes
 * @return value>0 for File and value=0 for URL and InputStream
 * @throws BasicPlayerException
 * @throws IOException
 */
protected long skipBytes(long bytes) throws BasicPlayerException, NullPointerException, IOException {

    long totalSkipped = 0;

    if (m_dataSource instanceof File) {
        log.info("Bytes to skip : " + bytes);
        int previousStatus = m_status;
        m_status = SEEKING;
        long skipped = 0;

        synchronized (m_audioInputStream) {
            notifyEvent(BasicPlayerEvent.SEEKING, getEncodedStreamPosition(), -1, null);
            initAudioInputStream();

            if (m_audioInputStream != null) {
                // Loop until bytes are really skipped.
                while (totalSkipped < (bytes - SKIP_INACCURACY_SIZE)) {
                    skipped = m_audioInputStream.skip(bytes - totalSkipped);
                    if (skipped == 0) {
                        break;
                    }

                    totalSkipped = totalSkipped + skipped;
                    log.info("Skipped : " + totalSkipped + "/" + bytes);

                    if (totalSkipped == -1) {
                        throw new BasicPlayerException(BasicPlayerException.SKIPNOTSUPPORTED);
                    }
                }
            }
        }

        notifyEvent(BasicPlayerEvent.SEEKED, getEncodedStreamPosition(), -1, null);
        m_status = OPENED;

        if (previousStatus == PLAYING) {
            startPlayback();
        } else if (previousStatus == PAUSED) {
            startPlayback();
            pausePlayback();
        }
    }

    return totalSkipped;
}

有没有办法添加另一个搜索功能来实现搜索ogg?提前谢谢......

不太了解这是如何工作的,但它适用于mp3,包括寻求, 音频播放,暂停,停止 在ogg播放,暂停,停止都很好,但是当从头开始寻找音频播放时,寻求是问题。

我没有改变代码的任何部分 BasicPlayer Api的来源是 http://www.javazoom.net/jlgui/sources/basicplayer3.0.zip

当我深入查看细节时,使用此代码实现的jlgui3.0播放器也未实现寻求Ogg播放,他们已经提到过它。因此,当播放音频为Ogg时,当前代码需要为Ogg播放添加单独的搜索功能并使用它而不是当前seek() ...

我不知道该怎么做,请帮助我提供良好的资料来源和实施相同的简单方法......

1 个答案:

答案 0 :(得分:1)

我认为这个图书馆可能不足以满足您的需求。查看jlGui的源代码(下面粘贴),只支持.mp3文件和.wav文件。

此外,它背后的逻辑有些幼稚,因为它只向前跳过固定数量的字节。对于PCM格式的.wav文件,跳过的字节数总是与跳过的时间量成正比,但对于可变比特率.mp3文件,跳过的时间将随文件中不同点的瞬时比特率而变化。 Ogg Vorbis是一种支持多路复用的容器格式,这使得搜索变得比在文件中跳跃并重新同步解码器更复杂。

作为替代方案,我建议使用JavaSound或JavaFX API,它们可以播放音频文件并寻找您提供的时间,而不是字节偏移。

来自jlGui:

protected void processSeek(double rate)
{
    try
    {
        if ((audioInfo != null) && (audioInfo.containsKey("audio.type")))
        {
            String type = (String) audioInfo.get("audio.type");
            // Seek support for MP3.
            if ((type.equalsIgnoreCase("mp3")) && (audioInfo.containsKey("audio.length.bytes")))
            {
                long skipBytes = (long) Math.round(((Integer) audioInfo.get("audio.length.bytes")).intValue() * rate);
                log.debug("Seek value (MP3) : " + skipBytes);
                theSoundPlayer.seek(skipBytes);
            }
            // Seek support for WAV.
            else if ((type.equalsIgnoreCase("wave")) && (audioInfo.containsKey("audio.length.bytes")))
            {
                long skipBytes = (long) Math.round(((Integer) audioInfo.get("audio.length.bytes")).intValue() * rate);
                log.debug("Seek value (WAVE) : " + skipBytes);
                theSoundPlayer.seek(skipBytes);
            }
            else posValueJump = false;
        }
        else posValueJump = false;
    }
    catch (BasicPlayerException ioe)
    {
        log.error("Cannot skip", ioe);
        posValueJump = false;
    }
}