首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JLayer总是引发ArrayIndexOutOfBounds异常

JLayer总是引发ArrayIndexOutOfBounds异常
EN

Stack Overflow用户
提问于 2013-11-10 19:06:47
回答 2查看 588关注 0票数 2

我使用JLayer对MP3进行解码,并将其存储为PCM数据。但是,无论我使用什么MP3文件,我都会得到一个索引为443的ArrayIndexOutOfBoudnsException。我听说这种情况只发生在特定的MP3s上,但是它发生在我在这里播放的每个MP3的每个帧上,这是我的代码:

代码语言:javascript
复制
private short[] getPCM(Header frameHeader, Bitstream bs) {
    short[] pcm = null;
    try {
        Decoder d = new Decoder();
        SampleBuffer buffer = (SampleBuffer) d.decodeFrame(frameHeader, bs);
        pcm = buffer.getBuffer();
    } catch (ArrayIndexOutOfBoundsException | DecoderException e) {
        System.err.println("JLayer, stap it");
    }
    return pcm;
}

并使用以下代码调用该方法:

代码语言:javascript
复制
while ((frameHeader = bs.readFrame()) != null) {
    short[] pcm = getPCM(frameHeader, bs);

    for(short i : pcm){
        try {
            os.write(i);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }       
}

堆栈跟踪:

代码语言:javascript
复制
java.lang.ArrayIndexOutOfBoundsException: 433
at javazoom.jl.decoder.Bitstream.get_bits(Unknown Source)
at javazoom.jl.decoder.LayerIIIDecoder.decode(Unknown Source)
at javazoom.jl.decoder.LayerIIIDecoder.decodeFrame(Unknown Source)
at javazoom.jl.decoder.Decoder.decodeFrame(Unknown Source)
at com.dentonposs.Canvas.getPCM(Canvas.java:70)
at com.dentonposs.Canvas.paintComponent(Canvas.java:48)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-11 11:21:54

您需要在每次调用Bitstream.closeFrame() - so之间调用readFrame()

代码语言:javascript
复制
while ((frameHeader = bs.readFrame()) != null) {
    short[] pcm = getPCM(frameHeader, bs);

    bs.closeFrame();

    .. more ..
票数 1
EN

Stack Overflow用户

发布于 2013-11-10 20:05:17

从它的外观来看,您正在尝试让解码器一遍又一遍地解码相同的帧。这将不起作用,BitStream具有内部状态(指向要读取的下一个位的指针),在解码该帧后将变得无效。异常表示它试图读取缓冲区容量。

必须对每个帧只调用一次decodeFrame()。

编辑:您的堆栈跟踪没有显示实际读取数据的位置。因为异常在component方法中,所以我假设您在另一个线程或其他地方读取了框架。

另外,查看您的getPCM()方法:该代码将永远无法工作。您不能为每个帧创建一个新的解码器实例--这将根本无法工作,因为解码器具有大量的内部状态,这是必要的,并且取决于前一个帧。您必须创建解码器一次,并重复使用它的所有帧.

看看javazoom.jl.player.Player的来源--它在play(int)方法中显示了一个适当的play循环(它只有几行长,但您必须遵守那里显示的调用顺序,否则会破坏解码器和解码器持有的对象的正确状态)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19893854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档