Как реализовать поиск по mp3 - PullRequest
2 голосов
/ 02 апреля 2012

Я собираюсь попасть в проект, который включает в себя декодирование + воспроизведение потока mp3.

У меня есть Java-декодер (JLayer), но, насколько я вижу, он не имеет функции поиска (я нене использую встроенный проигрыватель, мне нужно реализовать собственный проигрыватель).

Кроме того, поток зашифрован, поэтому мне нужно расшифровать + декодировать в режиме реального времени - не может иметь весь расшифрованный файл.

Итак, как вы подходите к поиску в потоке mp3?Я хотел бы установить значение времени и получить соответствующее смещение в файле для декодирования.

Пожалуйста, рассмотрите также поддержку VBR.

Спасибо

1 Ответ

1 голос
/ 16 ноября 2012

Я искал в точности то же самое. Код 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) или из текущей позиции воспроизведения.

VBR не проблема, поскольку кадры пропускаются по отдельности.

Что касается дешифрования, то это не имеет значения, поскольку эта процедура пропускает отдельные кадры, считанные из входного потока. Если входной поток поддерживает декодирование, он должен работать. Насколько быстро, конечно, другой вопрос. В этом случае может быть лучше создать индекс mp3, чтобы вы знали, в какую позицию перейти и декодировать, но это немного другая тема: как искать в зашифрованном потоке.

...