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