How to implement seek on mp3

大兔子大兔子 提交于 2019-12-08 01:52:52

问题


I am about to get into a project that involves decoding + playing an mp3 stream.

I have a Java decoder (JLayer), but as far as I can see it has no seek functionality (I don't use the built in player, I need to implement my own player).

Also, the stream is encrypted, so I need to decrypt + decode in real time - can't have an entire decrypted file.

So how do you approach seeking on mp3 stream? I would like to set a time value, and get the appropriate offset in the file to decode from.

Please also consider support for VBR.

Thanks


回答1:


I've been looking in exactly the same thing. The JLayer code is somewhat messy. Just browsing through it convinced me that the mp3 decoding core was written (or taken from somewhere) and then ported to Java, then an extra -fairly unoptimal- layer was added. In any case. To seek have a look at the code in the player (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;
    }

This routine illustrates how the bitstream is advanced without decoding.(m_audioInputStream.skip(...)). I don't know though whether it is skipped from the start (there is after all a initAudioStream call before), or from the current playposition.

VBR is no problem since the frames are skipped individually.

With respect to decryption, it shuoldn't matter since this routine skips individual frames as read from the inputstream. If the inputstream supports decoding it should wokr. How fast is of course another question. In that case it might be better to build an index of the mp3 so that you know to what position to jump and decode, but that is a slightly different topic: how to seek in an encrypted stream.



来源:https://stackoverflow.com/questions/9980852/how-to-implement-seek-on-mp3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!