如何在mp3上实现搜索

时间:2012-04-02 17:23:13

标签: java mp3 javasound

我即将进入一个涉及解码+播放mp3流的项目。

我有一个Java解码器(JLayer),但据我所知,它没有搜索功能(我不使用内置播放器,我需要实现自己的播放器)。

此外,流已加密,因此我需要实时解密+解码 - 无法拥有整个解密文件。

那么你如何在mp3流上寻找呢?我想设置一个时间值,并在文件中获取适当的偏移量来解码。

请同时考虑对VBR的支持。

由于

1 个答案:

答案 0 :(得分:1)

我一直在寻找完全相同的东西。 JLayer代码有些混乱。只是浏览它让我确信mp3解码核心是写入(或从某处获取)然后移植到Java,然后添加了一个非常不公平的层。在任何情况下。要查看播放器中的代码(http://code.google.com/p/jesuifoo/source/browse/trunk/src/javazoom/jlgui/basicplayer/BasicPlayer.java?r=23)

    /**
     * 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
     */
    protected long skipBytes(long bytes) throws BasicPlayerException {
            long totalSkipped = 0;
            if (m_dataSource instanceof File) {
                    log.info("Bytes to skip : " + bytes);
                    int previousStatus = m_status;
                    m_status = SEEKING;
                    long skipped = 0;
                    try {
                            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();
                            }
                    } catch (IOException e) {
                            throw new BasicPlayerException(e);
                    }
            }
            return totalSkipped;
    }

此例程说明了如何在不解码的情况下提升比特流。(m_audioInputStream.skip(...))。我不知道是否从头开始跳过(之前有一个initAudioStream调用),或者从当前的playposition中跳过。

VBR没有问题,因为单独跳过帧。

关于解密,它并不重要,因为该例程会跳过从输入流读取的各个帧。如果输入流支持解码,它应该是wokr。当然是另一个问题的速度有多快。在这种情况下,最好建立一个mp3的索引,以便你知道跳转和解码的位置,但这是一个稍微不同的主题:如何在加密流中寻找。