我即将进入一个涉及解码+播放mp3流的项目。
我有一个Java解码器(JLayer),但据我所知,它没有搜索功能(我不使用内置播放器,我需要实现自己的播放器)。
此外,流已加密,因此我需要实时解密+解码 - 无法拥有整个解密文件。
那么你如何在mp3流上寻找呢?我想设置一个时间值,并在文件中获取适当的偏移量来解码。
请同时考虑对VBR的支持。
由于
答案 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的索引,以便你知道跳转和解码的位置,但这是一个稍微不同的主题:如何在加密流中寻找。