如何在mp3上实现搜索 [英] How to implement seek on mp3

查看:145
本文介绍了如何在mp3上实现搜索的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

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

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.

还请考虑支持VBR。

谢谢

推荐答案

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

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;
    }

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

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是没有问题的这些帧是单独跳过的。

VBR is no problem since the frames are skipped individually.

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

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.

这篇关于如何在mp3上实现搜索的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆