Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在mp3上实现seek_Java_Mp3_Javasound - Fatal编程技术网

Java 如何在mp3上实现seek

Java 如何在mp3上实现seek,java,mp3,javasound,Java,Mp3,Javasound,我即将进入一个涉及解码+播放mp3流的项目 我有一个Java解码器(JLayer),但据我所知,它没有seek功能(我不使用内置播放器,我需要实现自己的播放器) 而且,流是加密的,所以我需要实时解密-不能有一个完整的解密文件 那个么,你们是如何在mp3流上进行搜索的呢?我想设置一个时间值,并在要解码的文件中获得适当的偏移量 也请考虑对VBR的支持。 谢谢我一直在看同样的东西。JLayer代码有点凌乱。只是浏览一下,我就确信mp3解码核心是编写的(或从某处获取的),然后移植到Java,然后添加了一

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

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

而且,流是加密的,所以我需要实时解密-不能有一个完整的解密文件

那个么,你们是如何在mp3流上进行搜索的呢?我想设置一个时间值,并在要解码的文件中获得适当的偏移量

也请考虑对VBR的支持。


谢谢

我一直在看同样的东西。JLayer代码有点凌乱。只是浏览一下,我就确信mp3解码核心是编写的(或从某处获取的),然后移植到Java,然后添加了一个额外的相当不理想的层。无论如何。要查找,请查看播放器中的代码(http://code.google.com/p/jesuifoo/source/browse/trunk/src/javazoom/jlgui/basicplayer/BasicPlayer.java?r=23)

/**
*跳过文件inputstream中的字节。它将跳过N个匹配到的帧
*字节,因此它永远不会精确跳过给定的字节长度。
* 
*@param字节
*@return value>0表示文件,value=0表示URL和InputStream
*@crows-basicLayerException
*/
受保护的长skipBytes(长字节)引发BasicLayerException{
长时间总计=0;
if(m_数据源实例文件){
log.info(“要跳过的字节:+字节”);
int-previousStatus=m_状态;
m_状态=寻找;
长跳过=0;
试一试{
已同步(m_audioInputStream){
notifyEvent(BasicLayerEvent.SEEKING,
getEncodedStreamPosition(),-1,null);
initAudioInputStream();
如果(m_audioInputStream!=null){
//循环,直到真正跳过字节。
while(totalSkipped<(字节-skipped\u不准确度\u大小)){
跳过=m_audioInputStream.skip(字节)
-全部跳过);
如果(跳过==0)
打破
totalSkipped=totalSkipped+skipped;
log.info(“跳过:“+totalSkipped+”/“+bytes”);
如果(总跳过==-1)
抛出新的BasicLayerException(
BasicLayerException.SKIPNOTSUPPORTED);
}
}
}
notifyEvent(BasicLayerEvent.seek,
getEncodedStreamPosition(),-1,null);
m_状态=打开;
如果(先前状态==正在播放)
startPlayback();
else if(先前状态==暂停){
startPlayback();
pausePlayback();
}
}捕获(IOE异常){
抛出新的BasicLayerException(e);
}
}
返回全部跳过;
}
此例程演示了如何在不解码的情况下提升位流。(m_audioInputStream.skip(…))。我不知道它是从一开始就被跳过(毕竟之前有一个initAudioStream调用),还是从当前播放位置被跳过

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


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

对于已经解码、加载的mp3,搜索很容易。对于一个尚未形成
音频输入流
,这并不容易,尤其是对于一个VBR MP3,这必须是纯Java吗?支持自定义的
seek()
方法,该方法也是如此。CASampledSP在OS X(CA=CoreAudio)上运行,在Windows 7和更高版本(MF=MediaFoundation)上运行4年后,我实际上想通过链接到我的JLayer端口来扩展这个答案。它大约快4倍,并提供了关于如何在字节精确位置查找/解码流的演示代码:请参阅JLayer 1.0.1部分。它有一个指向库和示例的公共存储库的链接。
    /**
     * 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;
    }